日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Freemarker动态模板渲染flyingsaucer将html转PDF(多页固定头尾)

發(fā)布時(shí)間:2024/1/1 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Freemarker动态模板渲染flyingsaucer将html转PDF(多页固定头尾) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

  • 一、序言
  • 二、CSS樣式控制打印模板
  • 三、代碼示例
    • 1、pom.xml
    • 2、application.yml
    • 3、PdfGenerationController
    • 4、Freemarker模板內(nèi)容
  • 四、展示效果

一、序言

一般正常來(lái)說(shuō),生成PDF的操作都是通過(guò)將HTML轉(zhuǎn)成PDF,HTML動(dòng)態(tài)渲染可以借助模板引擎,如常用的Thymeleaf或者Freemarker。

HTML轉(zhuǎn)PDF可以通過(guò)flyingsaucer來(lái)實(shí)現(xiàn),可以參考之前博主寫的一篇文章《flyingsaucer進(jìn)行html文件轉(zhuǎn)圖片和pdf》,至于PDF樣式,我們可以通過(guò)CSS打印樣式來(lái)控制。

今天這篇文章主要分享模板引擎動(dòng)態(tài)渲染以及結(jié)合flyingsaucer通過(guò)CSS打印樣式控制PDF的內(nèi)容呈現(xiàn),固定每頁(yè)P(yáng)DF的頭和尾部。


二、CSS樣式控制打印模板

在PrintCSS上有一篇文章: Running Headers and Footers ,里面會(huì)介紹CSS運(yùn)行時(shí)元素以及如何控制打印PDF時(shí)的頭部和尾部。

這里介紹一個(gè)在線工具:PrintCSS.live,里面可以在線預(yù)覽pdf打印效果,如下:

三、代碼示例

1、pom.xml

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf-itext5</artifactId><version>9.1.22</version></dependency>

2、application.yml

spring:# freemarker configurationfreemarker:cache: truesuffix: .ftlcharset: UTF-8template-loader-path: classpath:templates/

備注:template-loader-path為.ftl模板加載路徑,這里我們指定了類路徑下的templates目錄。

3、PdfGenerationController

import com.itextpdf.text.pdf.BaseFont; import com.universe.wonderful.pojo.model.AccountProofModel; import freemarker.template.Configuration; import freemarker.template.Template; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ContentDisposition; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.time.LocalDate;/*** @author Nick Liu* @date 2023/3/1*/ @Slf4j @RestController @RequiredArgsConstructor public class PdfGenerationController {private final Configuration configuration;@RequestMapping("/pdf/preview")public ResponseEntity<byte[]> downloadPdfWithFixedHeaderAndFooter() {AccountProofModel accountProofModel = AccountProofModel.builder().generationDate(LocalDate.now().toString()).memberName("Nick Liu").memberAddress("Nanshan District, Shenzhen city, Guangdong Province").accountNo("88888888888888").bankName("ICBC").bankSwiftCode("ABCDEFG").bankAddress("Shenzhen city of Guangdong Province").countryName("China").build();ByteArrayOutputStream os = new ByteArrayOutputStream();try {// 不建議直接創(chuàng)建Template實(shí)例,開(kāi)銷比較大,可以直接通過(guò)Configuration實(shí)例獲取,有緩存機(jī)制Template template = configuration.getTemplate("personalAccountProof.ftl");String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, accountProofModel);ITextRenderer renderer = new ITextRenderer();// 如果內(nèi)容有中文則需要添加支持中文的字體renderer.getFontResolver().addFont("/fonts/calibri.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);renderer.setDocumentFromString(content);renderer.layout();renderer.createPDF(os);renderer.finishPDF();} catch (Exception e) {log.error("Fail to generate pdf: {}", e.getMessage(), e);return ResponseEntity.internalServerError().body(null);}HttpHeaders respHeaders = new HttpHeaders();respHeaders.setContentType(MediaType.APPLICATION_PDF);respHeaders.setContentDisposition(ContentDisposition.inline().filename("accountProof.pdf", StandardCharsets.UTF_8).build());return new ResponseEntity<>(os.toByteArray(), respHeaders, HttpStatus.OK);} }

備注:字體會(huì)從類路徑下加載,底層通過(guò)ClassLoader#getResourceAsStream()讀取。

字體目錄和freemarker模板目錄如下圖:

4、Freemarker模板內(nèi)容

<!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>Running Headers and Footers</title><style>@page {size: A4;margin: 40mm 10mm 50mm 10mm;@top-left {content: element(headerLeft);}@bottom-center {content: element(footerCenter);}}* {padding: 0;margin: 0;}body {font-family: Calibri, serif;}.headerLeft {position: running(headerLeft);}.titleWrapper > div {margin: 2px 0;}.footerCenter {text-align: center;position: running(footerCenter);}.footerTipsWrapper {color: #C1A97D;margin-top: 10px;border-top: 2px solid #EFE7DA;}.footerTipsWrapper > div {font-size: 12px;margin-top: 12px;}.contentWrapper {margin-top: -10px;}.paddingWrapper {padding: 10px;}.accountIntroduction {margin-top: 60px;background-color: #EFE7DA;border: 1px solid #EFE7DA;border-radius: 10px;}.accountDetailsWrapper {margin-top: 50px;border: 3px solid #EFE7DA;border-radius: 10px;}.subTitle {font-weight: bold;border-bottom: 2px solid #EFE7DA;padding-bottom: 10px;}.accountDetails > div {margin-top: 8px;}</style> </head> <body><div class="headerLeft paddingWrapper"><img src="http://localhost:8080/images/proof/head_logo.png" /></div><div class="footerCenter"><div class="footerLogoWrapper"><img src="http://localhost:8080/images/proof/footer_logo.png" alt="logo" /></div><div class="footerTipsWrapper"><div>www.aletaplanet.com | account@aletaplanet.com</div><div>MPHK Management Company Limited | Suite 615, 6/F, Ocean Centre, Harbour City, Tsim Sha Tsui, Tsim Sha Tsui, Kowloon |<br/>License No.: 21-10-03068</div></div></div><div class="contentWrapper"><div class="titleWrapper paddingWrapper"><div><b>Proof of Account Details</b></div><div>Generated on: ${generationDate}</div></div><div class="tips paddingWrapper">To whom it may concern,</div><div class="accountIntroduction paddingWrapper"><div><b>Personal account of ${memberName}</b></div><div style="margin-top: 10px;word-break: break-word">This letter confirms the below account details allow ${memberName} residing at ${memberAddress} to receive payments into his/ her AP-1 Account:</div></div><div class="accountDetailsWrapper paddingWrapper"><div class="subTitle">Business account details</div><div class="accountDetails"><div>Account Name: ${memberName}</div><div>Account Number: ${accountNo}</div><div>Bank Name: ${bankName}</div><div>Bank SWIFT/BIC: ${bankSwiftCode}</div><div>Bank Country: ${countryName}</div><div>Bank Address: ${bankAddress}</div></div></div></div> </body> </html>

在@page{}代碼塊中我們指定了打印頁(yè)面的大小為A4、上下左右的邊緣分別為40毫米50毫米10毫米10毫米,同時(shí)在頁(yè)面左上角指定了logo,以及在頁(yè)面底部居中指定了logo和描述。

實(shí)際上@top-left和@bottom-center的效果類似于固定定位

備注:關(guān)于@page、@top-left、@bottom-center的介紹可以參考:https://www.w3.org/TR/css-page-3/#margin-boxes


四、展示效果

啟動(dòng)項(xiàng)目,打開(kāi)瀏覽器,輸入http://localhost:8080/pdf/preview,可以預(yù)覽生成的PDF,如下:

備注:如果有多頁(yè),頭部和尾部的logo也會(huì)在同樣的地方顯示。

總結(jié)

以上是生活随笔為你收集整理的Freemarker动态模板渲染flyingsaucer将html转PDF(多页固定头尾)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美抠逼视频 | 亚洲AV无码久久精品国产一区 | 制服.丝袜.亚洲.另类.中文 | 欧美一区二区不卡视频 | 91一级视频 | 老司机在线永久免费观看 | 日本bbwbbw | 夫妻毛片| 亚洲精品中文字幕在线播放 | 欧美亚日韩 | 中文字幕在线观看一区二区 | 中文字幕亚洲乱码 | 国产成人无码一区二区三区在线 | 青青草原国产在线 | 欧美日b片 | 国产三级在线看 | 精品国产亚洲一区二区麻豆 | 久久偷看各类wc女厕嘘嘘偷窃 | 91色在线播放 | 伊人草草| 久久黄色大片 | 蜜臀aⅴ免费一区二区 | 国产麻豆剧传媒精品国产av | 一区二区在线观看免费视频 | 精品国产一区二区三区久久久蜜臀 | 日韩黄网 | 国产精品成人免费看片 | 成人影片在线免费观看 | 伊人在线 | 午夜国产福利 | 欧美日韩国产在线观看 | 久草视频福利在线 | 国产chinese男男gaygay视频 | 国产伦精品一区二区三区照片 | 久久久国产亚洲 | 生活片毛片 | 成人av18| 欧美极品视频在线观看 | 精品欧美一区二区精品久久 | 欧美日韩另类一区 | 尤物在线观看视频 | 亚洲妇熟xx妇色黄蜜桃 | 激情五月婷婷综合 | 色呦呦官网 | 性欧美18一19性猛交 | 欧美91精品| 四虎少妇做爰免费视频网站四 | 麻豆网站在线播放 | 一级黄色大片免费观看 | 国产高清免费在线播放 | 欧美丰满老熟妇aaaa片 | www.日 | 国产精品爽爽爽 | 九色自拍视频 | 国产丝袜一区二区 | 天天干天天舔 | 亚洲女人的天堂 | 日韩中文在线一区 | 一区二区三区中文字幕在线观看 | 黑人极品ⅴideos精品欧美棵 | 亚洲天堂男人天堂 | 久久天堂电影 | 天天国产视频 | 久久午夜福利电影 | 欧美色吊丝 | 在线国产三级 | 国产免费网址 | 性欧美videos另类艳妇3d | 国产一区二区三区在线看 | 人妻互换一区二区三区四区五区 | 国产69精品久久久久久久久久 | 久久精品丝袜 | 欧美熟妇7777一区二区 | 国产精品视频 | 91免费看黄| 日韩av影片在线观看 | av免费观看不卡 | 美日韩免费视频 | 国产精品成人一区二区网站软件 | 日韩3区 | 国产精品香蕉国产 | 成a人片亚洲日本久久 | 久久2019| 激情网综合 | 2019中文字幕在线免费观看 | 香蕉视频三级 | 久久精品综合视频 | 成人午夜黄色 | 精品人妻伦一二三区免费 | 亚洲一区二区 | 欧美性久久久久 | 大肉大捧一进一出好爽视频动漫 | av网站黄色 | 激情五月五月婷婷 | 爽妇网国产精品 | 青娱乐极品在线 | 综合色导航 | 日韩性xxx | 日韩中文视频 |