SpringBoot?pdf打印及預(yù)覽(openhtmltopdf+freemarker)
SpringBoot pdf打印及預(yù)覽(openhtmltopdf+freemarker)
添加依賴
<properties> <openhtml.version>1.0.10</openhtml.version> </properties> <!--openhtmltopdf --> <dependencies> <dependency> <!-- ALWAYS required, usually included transitively. --> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-core</artifactId> <version>${openhtml.version}</version> </dependency> <dependency> <!-- Required for PDF output. --> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-pdfbox</artifactId> <version>${openhtml.version}</version> </dependency> <dependency> <!-- Optional, leave out if you do not need logging via slf4j. --> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-slf4j</artifactId> <version>${openhtml.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> </dependencies>
在/resources/template/view/html新建模板xxx.ftl文件
<html> <head> <meta charset="UTF-8"/> <style> /* 特有css樣式自行參考官網(wǎng) */ @page { size: a4; @top-left { content: element(header-left); } @top-center { content: element(header-center); } @top-right { content: element(header-right); } @bottom-center { font-size: 14px; content: counter(page); font-family: 'simsun', serif; } margin: 50px; } * { margin: 0; padding: 0; font-family: 'simsun', serif; } #page-header-left { font-size: 10px; font-weight: bold; position: running(header-left); } #page-header-center { font-size: 10px; font-weight: bold; position: running(header-center); } #page-header-right { font-size: 10px; font-weight: bold; position: running(header-right); } table { width: 100%; font-size: 14px; border-collapse: collapse; font-family: 'simsun', serif; border-spacing: 0; /* The magical table pagination property. */ /*-fs-table-paginate: paginate;*/ /* Recommended to avoid leaving thead on a page by itself. */ -fs-page-break-min-height: 0.5cm; border-left: 0.07cm solid black; border-right: 0.07cm solid black; border-bottom: 0.03cm solid black; } .checkbox { display: inline-block; position: relative; top: 1px; width: 10px; height: 10px; border: 1px solid black; } .correct { display: inline-block; position: relative; top: 2px; right: 15px; width: 7px; height: 3px; border-left: 1px solid black; border-bottom: 1px solid black; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); margin-right: -16px; } input[type = "checkbox"] { width: 10px; height: 10px; border: 1px solid black; } tr, thead, tfoot { page-break-inside: avoid; } td, th { page-break-inside: avoid; font-family: 'simsun', serif; padding: 1px; border-top: 0.03cm solid black; border-left: 0.03cm solid black; } td:first-child, th:first-child { border-left: 0; } #table-title { text-align: center; margin-top: 0; margin-bottom: 5px; font-weight: bold; } </style> </head> <body> <div class="header-box"> <div id="page-header-left"> <span id="page-header-text">編號(hào):<span style="font-weight: normal">${code!''}</span></span> </div> <div id="page-header-center"> <span id="page-header-text">時(shí)間 <sup>1)</sup>:<span style="font-weight: normal">${time?date!''}</span></span> </div> </div> <div class="basic-box"> <table style="border-top: 0;"> <tr> <td>標(biāo)題1</td> <td>${xx1!''}</td> <td>標(biāo)題2</td> <td>${xx2!''}</td> <td>標(biāo)題3</td> <td>${xx3!''}</td> </tr> <tr> <td style="font-weight: bold;text-align: left;">結(jié)果</td> <td colspan="3" style="text-align: left;"> <div> <div class="checkbox"></div> <#if result??&&result == '1'> <div class="correct"></div> </#if> <div style="display: inline-block">合格</div> <div class="checkbox"></div> <#if result??&&result == '0'> <div class="correct"></div> </#if> <div style="display: inline-block">不合格</div> </div> </td> <td colspan="4" style="font-weight: bold;text-align: left;">簽字人:</td> </tr> </table> </div> </body> </html>
controller接口
@RequestMapping(value = "/print/pdf/[code]", produces = MediaType.APPLICATION_PDF_VALUE) public ResponseEntity<byte[]> printPdf(@PathVariable("code") String detectCode) throws IOException, TemplateException { Assert.hasText(code, "code不能為空"); return detectReportPrintService.findPdf(code); }
service實(shí)現(xiàn)類
??pdf預(yù)覽有中文亂碼,需要重新引入simsun.ttf字體文件,放在/resources/fonts文件夾下(與代碼路徑一致即可),ftl文件中css樣式必須font-family: 'simsun', serif;
??在 Configuration
中可以使用下面的方法來(lái)方便建立三種模板加載。 (每種方法都會(huì)在其內(nèi)部新建一個(gè)模板加載器對(duì)象,然后創(chuàng)建 Configuration
實(shí)例來(lái)使用它。)
1. void setDirectoryForTemplateLoading(File dir);
2. void setClassForTemplateLoading(Class cl, String prefix);
3. void setServletContextForTemplateLoading(Object servletContext, String path);
項(xiàng)目打包為jar包只能使用setClassForTemplateLoading方法。
public ResponseEntity<byte[]> findPdf(String code) throws IOException, TemplateException { //獲取ftl所需變量值的自定義方法 Map data = this.findValue(code); //FreeMarker 生成 html字符串 Configuration conf = new Configuration(Configuration.VERSION_2_3_23); conf.setDefaultEncoding("UTF-8"); //加載模板文件(模板的路徑) //有多種加載模板的方法 //項(xiàng)目打包為jar包只能使用setClassForTemplateLoading方法 //第一個(gè)參數(shù):springboot啟動(dòng)類,第二個(gè)參數(shù):ftl模板對(duì)應(yīng)resources下的位置 conf.setClassForTemplateLoading(XaWebApplication.class, "/template/view/html"); // 加載模板 Template template = conf.getTemplate("/xxx.ftl"); //傳入變量生成html字符串 String htmlString = FreeMarkerTemplateUtils.processTemplateIntoString(template, data ); //openhtmltopdf生成pdf @Cleanup ByteArrayOutputStream os = new ByteArrayOutputStream(); PdfRendererBuilder builder = new PdfRendererBuilder(); builder.withHtmlContent(htmlString, ""); builder.useFont(new FSSupplier<InputStream>() { @SneakyThrows @Override public InputStream supply() { return resourceLoader.getResource("classpath:fonts/simsun.ttf").getInputStream(); } }, "simsun"); builder.toStream(os); builder.run(); byte[] bytes = os.toByteArray(); return new ResponseEntity<>(bytes, HttpStatus.OK); }
以上就是SpringBoot pdf打印及預(yù)覽(openhtmltopdf+freemarker)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot pdf打印預(yù)覽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用IDEA和Gradle構(gòu)建Vertx項(xiàng)目(圖文步驟)
這篇文章主要介紹了使用IDEA和Gradle構(gòu)建Vertx項(xiàng)目(圖文步驟),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Spring Data JPA中的動(dòng)態(tài)查詢實(shí)例
本篇文章主要介紹了詳解Spring Data JPA中的動(dòng)態(tài)查詢。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04使用idea搭建一個(gè)spring mvc項(xiàng)目的圖文教程
這篇文章主要介紹了使用idea直接創(chuàng)建一個(gè)spring mvc項(xiàng)目的圖文教程,本文通過(guò)圖文并茂的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03java 最新Xss攻擊與防護(hù)(全方位360°詳解)
這篇文章主要介紹了java 最新Xss攻擊與防護(hù)(全方位360°詳解),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Java通過(guò)Freemarker模板實(shí)現(xiàn)生成Word文件
FreeMarker是一款模板引擎: 即一種基于模板和要改變的數(shù)據(jù), 并用來(lái)生成輸出文本的通用工具。本文將根據(jù)Freemarker模板實(shí)現(xiàn)生成Word文件,需要的可以參考一下2022-09-09SpringMVC框架如何與Junit整合看這個(gè)就夠了
這篇文章主要介紹了SpringMVC框架如何與Junit整合看這個(gè)就夠了,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Java實(shí)戰(zhàn)之電影在線觀看系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java實(shí)現(xiàn)電影在線觀看系統(tǒng),文中用到的技術(shù)有:JSP、Spring、SpringMVC、MyBatis等,感興趣的可以了解一下2022-04-04