Thymeleaf企業(yè)級(jí)真實(shí)應(yīng)用:使用Flying Saucer結(jié)合iText5將HTML界面數(shù)據(jù)轉(zhuǎn)換為PDF輸出
SpringBoot+Thymeleaf:后端HTML轉(zhuǎn)PDF
本文將介紹如何使用SpringBoot和Thymeleaf將后端HTML轉(zhuǎn)換為PDF。我們將使用Flying Saucer和iText5將HTML界面數(shù)據(jù)轉(zhuǎn)換為PDF輸出。以下是一些相關(guān)的參考鏈接:
https://blog.51cto.com/u_13146445/6190475
https://blog.csdn.net/qq_27242695/article/details/11565444
需求
我們的目標(biāo)是生成PDF,這個(gè)PDF是由Thymeleaf根據(jù)已有的HTML模板渲染后生成的。
PDF中可以放置圖片,但圖片不是以文件形式引入,而是采用Base64方式。需要注意的是,HTML文件需要單獨(dú)開發(fā),CSS樣式需要內(nèi)嵌,不允許外置CSS文件。Echarts圖表部分暫時(shí)未整理,如有需要,可以參考上述URL。
Thymeleaf
Thymeleaf簡(jiǎn)介
Thymeleaf是一種現(xiàn)代化的服務(wù)器端Java模板引擎,適用于Web和獨(dú)立環(huán)境中的HTML、XML、JavaScript、CSS和文本。
在實(shí)際開發(fā)中,Thymeleaf可以用于生成動(dòng)態(tài)的HTML頁面,支持將數(shù)據(jù)與模板進(jìn)行綁定,生成最終的HTML內(nèi)容。它是一個(gè)開源的軟件,采用Apache許可證2.0進(jìn)行發(fā)布。
Thymeleaf的特點(diǎn)
與其他服務(wù)器端Java模板引擎相比,Thymeleaf具有以下特點(diǎn):
語法簡(jiǎn)單易懂,支持自然的HTML標(biāo)簽
支持HTML5的規(guī)范和特性
支持CSS樣式的綁定和操作
支持表達(dá)式語言(Expression Language,簡(jiǎn)稱EL)和Spring表達(dá)式語言(Spring Expression Language,簡(jiǎn)稱SpEL)
支持標(biāo)準(zhǔn)和Spring MVC的多種模板渲染方式
支持多種模板緩存策略
支持可擴(kuò)展的引擎架構(gòu)
在實(shí)際開發(fā)中,Thymeleaf可以用于生成動(dòng)態(tài)的HTML頁面,支持將數(shù)據(jù)與模板進(jìn)行綁定,生成最終的HTML內(nèi)容。它可以作為Web應(yīng)用程序的模板引擎,也可以作為其他應(yīng)用程序的模板引擎。由于其簡(jiǎn)單易用的語法和強(qiáng)大的功能,Thymeleaf已經(jīng)成為Java領(lǐng)域中最受歡迎的模板引擎之一。
將HTML界面數(shù)據(jù)轉(zhuǎn)換為PDF輸出的邏輯說明
我們的主要思路是使用模板引擎的模板文件和數(shù)據(jù)模型。
模板文件定義了最終輸出的PDF頁面的結(jié)構(gòu)和樣式,而數(shù)據(jù)模型則提供了模板中要填充的動(dòng)態(tài)數(shù)據(jù)。
具體來說,Thymeleaf使用Java對(duì)象作為數(shù)據(jù)模型,可以通過Spring的控制器將數(shù)據(jù)注入到數(shù)據(jù)模型中。
然后,Thymeleaf將數(shù)據(jù)模型與模板文件結(jié)合起來,生成HTML內(nèi)容。
最后,使用PDF生成庫將HTML內(nèi)容轉(zhuǎn)換為PDF輸出。
在實(shí)現(xiàn)PDF輸出功能時(shí),可以使用Spring Boot提供的spring-boot-starter-thymeleaf依賴,該依賴包含了Thymeleaf、PDF生成庫以及其他必需的依賴項(xiàng)。
可以在控制器中使用Thymeleaf的TemplateEngine對(duì)象將數(shù)據(jù)模型和模板文件合并,生成HTML內(nèi)容。
然后,可以使用PDF生成庫將HTML內(nèi)容轉(zhuǎn)換為PDF格式。
需要注意的是,PDF輸出可能需要一些特定的CSS樣式和HTML標(biāo)記,以便正確呈現(xiàn)和格式化PDF頁面。
因此,在生成PDF輸出之前,可能需要對(duì)模板文件進(jìn)行調(diào)整和優(yōu)化,以確保輸出的PDF頁面具有所需的外觀和布局。
具體步驟
定義HTML模板,需要輸出的數(shù)據(jù)以HTML格式創(chuàng)建一個(gè)模板,生成.HTML文件
引入Thymeleaf中TemplateEngine->生成文本輸出的Java模板引擎框架、Context->Web應(yīng)用程序的上下文對(duì)象。生成html 模板渲染工具。處理上邊我們定義的模板。得到一個(gè)String類的結(jié)果
讀取這個(gè)結(jié)果byte[],將byte數(shù)組 轉(zhuǎn)換為 Base64字符串
最后將Base64字符串轉(zhuǎn)換為PDF格式的數(shù)據(jù),輸出路徑
具體實(shí)現(xiàn)
1. 依賴
<!--thymeleaf--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- html 轉(zhuǎn) pdf 需要用的jar --> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf --> <!-- <dependency>--> <!-- <groupId>org.xhtmlrenderer</groupId>--> <!-- <artifactId>flying-saucer-pdf</artifactId>--> <!-- <version>9.1.22</version>--> <!-- </dependency>--> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.1.22</version> </dependency>
2. 依賴介紹
Flying Saucer是一個(gè)基于Java的開源庫,用于將XHTML和CSS渲染為PDF、SVG、圖像或打印輸出。它是一個(gè)強(qiáng)大的工具,使您能夠以編程方式生成高質(zhì)量的PDF文檔,同時(shí)利用CSS樣式和布局來控制文檔的外觀。
該依賴是 flying-saucer-pdf-itext5
,它是一個(gè)基于iText 5的開源Java庫,用于將XHTML/CSS渲染為PDF文檔。它提供了將HTML內(nèi)容轉(zhuǎn)換為PDF的功能,包括支持CSS樣式和布局,生成復(fù)雜的PDF文檔。
具體介紹該依賴的相關(guān)信息如下:
Group ID(組織標(biāo)識(shí)):org.xhtmlrenderer
Artifact ID(項(xiàng)目標(biāo)識(shí)):flying-saucer-pdf-itext5
Version(版本號(hào)):9.1.22
這個(gè)依賴項(xiàng)允許您在Java應(yīng)用程序中使用Flying Saucer庫來生成和操作PDF文檔。Flying Saucer使用XHTML和CSS作為輸入,并使用iText庫將其渲染為PDF。
您可以在項(xiàng)目的Maven配置文件(pom.xml)中添加該依賴項(xiàng),以便在您的項(xiàng)目中使用它。通過在<dependencies>
標(biāo)簽中添加上述代碼,Maven將從中央存儲(chǔ)庫中下載并管理該依賴項(xiàng)的jar文件。
請(qǐng)注意,這只是Flying Saucer庫的一個(gè)特定版本。如果需要更高版本或其他版本,請(qǐng)參考Flying Saucer項(xiàng)目的文檔和存儲(chǔ)庫以獲取最新信息。
更多關(guān)于Flying Saucer和iText的詳細(xì)信息,請(qǐng)參考它們的官方文檔和相關(guān)資源。
github地址 https://github.com/flyingsaucerproject/flyingsaucer
Flying Saucer提供了多個(gè)相關(guān)的Maven構(gòu)件,每個(gè)構(gòu)件提供不同的功能和特性。以下是這些構(gòu)件的簡(jiǎn)要介紹:
org.xhtmlrenderer:flying-saucer-core
:Flying Saucer的核心庫,提供了XHTML和CSS解析以及基于Java2D的渲染功能。它可以將XHTML和CSS文檔轉(zhuǎn)換為Java2D圖像,以便在Java應(yīng)用程序中顯示或輸出。org.xhtmlrenderer:flying-saucer-pdf
:使用iText 2.x生成PDF輸出的Flying Saucer構(gòu)件。它基于flying-saucer-core
,允許將XHTML和CSS文檔轉(zhuǎn)換為PDF格式。org.xhtmlrenderer:flying-saucer-pdf-itext5
:使用iText 5.x生成PDF輸出的Flying Saucer構(gòu)件。類似于flying-saucer-pdf
,但使用iText 5.x版本庫。org.xhtmlrenderer:flying-saucer-pdf-openpdf
:使用OpenPDF生成PDF輸出的Flying Saucer構(gòu)件。類似于flying-saucer-pdf
,但使用OpenPDF庫作為PDF生成引擎。org.xhtmlrenderer:flying-saucer-swt
:提供了基于SWT (Standard Widget Toolkit) 的輸出功能的Flying Saucer構(gòu)件。它允許將XHTML和CSS文檔渲染為SWT界面。org.xhtmlrenderer:flying-saucer-log4j
:這是Flying Saucer的一個(gè)日志插件,用于與log4j日志框架集成,以記錄Flying Saucer的日志消息。
需要注意的是,文檔中提到iText 2.x存在未修復(fù)的安全漏洞,因此新項(xiàng)目應(yīng)該避免使用它。推薦使用iText 5.x或OpenPDF作為PDF生成引擎。根據(jù)您的需求和項(xiàng)目要求,您可以選擇適合的Flying Saucer構(gòu)件來滿足您的需求。
org.xhtmlrenderer:flying-saucer-pdf-itext5 和 org.xhtmlrenderer:flying-saucer-pdf-openpdf 有什么區(qū)別
org.xhtmlrenderer:flying-saucer-pdf-itext5
和 org.xhtmlrenderer:flying-saucer-pdf-openpdf
是 Flying Saucer 庫中用于生成 PDF 輸出的兩個(gè)不同的構(gòu)件。它們之間的區(qū)別在于使用的 PDF 生成引擎不同。
org.xhtmlrenderer:flying-saucer-pdf-itext5
:使用 iText 5.x 作為 PDF 生成引擎。
iText 5.x 是一個(gè)廣泛使用的 Java 庫,提供了強(qiáng)大的 PDF 處理功能。
它具有豐富的 API 和功能,可以用于創(chuàng)建、修改和操作 PDF 文檔。
iText 5.x 版本庫在過去被廣泛使用,但目前已經(jīng)過時(shí),官方推薦使用更新的 iText 7.x 版本。
org.xhtmlrenderer:flying-saucer-pdf-openpdf
:使用 OpenPDF 作為 PDF 生成引擎。
OpenPDF 是一個(gè)基于 iText 的開源項(xiàng)目,旨在提供一個(gè)簡(jiǎn)單易用的 PDF 處理庫。
它是 iText 5.x 的一個(gè)分支,專注于提供基本的 PDF 生成和操作功能。
OpenPDF 與 Flying Saucer 結(jié)合使用,可以將 XHTML 和 CSS 文檔轉(zhuǎn)換為 PDF。
選擇使用哪個(gè)構(gòu)件取決于您的具體需求和項(xiàng)目要求。如果您已經(jīng)熟悉 iText 5.x 并且需要更豐富的 PDF 處理功能,那么 org.xhtmlrenderer:flying-saucer-pdf-itext5
可能是更好的選擇。如果您希望使用一個(gè)輕量級(jí)的 PDF 生成引擎,并且只需要基本的 PDF 生成功能,那么 org.xhtmlrenderer:flying-saucer-pdf-openpdf
可能更適合您。
哪個(gè)用的更廣泛一些
目前來說,org.xhtmlrenderer:flying-saucer-pdf-itext5
使用的更廣泛一些。這是因?yàn)?iText 5.x 在過去被廣泛采用,并且有大量的用戶基礎(chǔ)和社區(qū)支持。許多項(xiàng)目和應(yīng)用程序都在使用 Flying Saucer 結(jié)合 iText 5.x 生成 PDF 輸出。
然而,需要注意的是,iText 5.x 已經(jīng)過時(shí),官方推薦使用更新的 iText 7.x 版本。因此,隨著時(shí)間的推移,更多的項(xiàng)目可能會(huì)轉(zhuǎn)向使用 iText 7.x 或其他 PDF 生成引擎。
另一方面,org.xhtmlrenderer:flying-saucer-pdf-openpdf
使用的相對(duì)較少,因?yàn)?OpenPDF 是一個(gè)較新的項(xiàng)目,并且在廣泛采用方面還沒有達(dá)到與 iText 5.x 相當(dāng)?shù)乃健5?,如果您?duì)使用較新的 PDF 生成引擎和較輕量級(jí)的解決方案感興趣,那么使用 org.xhtmlrenderer:flying-saucer-pdf-openpdf
也是一個(gè)可行的選擇。
最終選擇取決于您的具體需求、項(xiàng)目要求以及對(duì)不同庫的了解和熟悉程度。建議根據(jù)項(xiàng)目的需求和技術(shù)要求進(jìn)行評(píng)估,并選擇適合您項(xiàng)目的庫。
有沒有 iText 7.x 對(duì)應(yīng)的flying-saucer
目前并沒有針對(duì) iText 7.x 的特定版本的 Flying Saucer。Flying Saucer 項(xiàng)目目前主要支持 iText 2.x 和 iText 5.x 版本。
如果您需要與 iText 7.x 結(jié)合使用 Flying Saucer,可以考慮以下兩種方式:
使用 Flying Saucer 的核心庫(
org.xhtmlrenderer:flying-saucer-core
)和 iText 7.x 進(jìn)行自定義集成。Flying Saucer 的核心庫提供了將 XHTML 渲染為 PDF 的功能,您可以使用 iText 7.x 的 API 來處理 PDF 相關(guān)操作。尋找其他與 iText 7.x 兼容的 PDF 生成庫或工具。iText 官方提供了 iText 7 的許多功能和組件,您可以直接使用 iText 7.x 提供的功能來生成 PDF,而無需額外依賴 Flying Saucer。
選擇哪種方式取決于您對(duì) Flying Saucer 和 iText 7.x 的依賴程度以及項(xiàng)目的具體要求。如果 Flying Saucer 提供的功能對(duì)您的項(xiàng)目至關(guān)重要,并且您想繼續(xù)使用 Flying Saucer 的渲染引擎,那么與 iText 7.x 進(jìn)行自定義集成可能是一個(gè)選擇。如果您更傾向于直接使用 iText 7.x 提供的功能和 API,那么可以考慮直接使用 iText 7.x 生成 PDF,而不使用 Flying Saucer。
2. 定義好html模板
需要轉(zhuǎn)成thymeleaf格式,如頭部標(biāo)簽
@page為pdf的尺寸
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <title>Hello World!</title> <style> .setAa { background-color: red; } @page{ size:297mm 210mm; } </style></head><body><h1 class="setAa" th:text="'Hello, ' + ${name} + '!'"></h1><p th:text="'You are ' + ${age} + ' years old.'"></p><img alt="" th:src="${imgSrc}" style="margin:0 auto;"/></body></html>
3. html 模板渲染工具類
import com.lowagie.text.DocumentException;import com.lowagie.text.pdf.BaseFont;import org.springframework.stereotype.Component;import org.thymeleaf.TemplateEngine;import org.thymeleaf.context.Context;import org.xhtmlrenderer.pdf.ITextFontResolver;import org.xhtmlrenderer.pdf.ITextRenderer;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;import javax.annotation.Resource;import java.io.*;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;/** * @Author:wangdi * @Date:2023/6/9 14:58 * @Des: HtmlToPdfUtil 轉(zhuǎn)換pdf工具類 */@Componentpublic class HtmlToPDFUtil { @Resource private TemplateEngine templateEngine; /** * 使用 Thymeleaf 渲染 HTML * * @param template HTML模板路徑 * @param params 渲染的參數(shù) * @return 返回渲染后的html代碼 * @throws Exception */ public String render(String template, Map<String, Object> params) { Context context = new Context(); if (params.size() > 0) { context.setVariables(params); } //將數(shù)據(jù)填充到模板里,開始處理模板 return templateEngine.process(template, context); } /** * 根據(jù)html生成pdf的base64格式 * * @param html * @return */ public static String getPDFBase64ByHtml(String html) throws DocumentException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream();//構(gòu)建字節(jié)輸出流 ITextRenderer renderer = new ITextRenderer(); ITextFontResolver fontResolver = renderer.getFontResolver(); //指定文件字體添加到PDF庫,指定字體不作為內(nèi)部字體,而是外部字體被加載 fontResolver.addFont("font/SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); renderer.setDocumentFromString(html); renderer.layout(); renderer.createPDF(baos); return new BASE64Encoder().encode(baos.toByteArray()); } /** * 根據(jù)pdf的base64格式和路徑生成pdf文件 * * @param base64 pdf的base64格式 * @param path 生成pdf的路徑 * @return */ public static String base64ToPDF(String base64, String path) { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String fileAdd = sdf.format(new Date()); //先判斷文件是否存在 path = path + "/" + fileAdd; String fileName = path + "/" + System.currentTimeMillis() + ".pdf";//新的文件名 BufferedInputStream bin = null; FileOutputStream fout = null; BufferedOutputStream bout = null; BASE64Decoder decoder = new BASE64Decoder(); try { byte[] bytes = decoder.decodeBuffer(base64); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); // 創(chuàng)建從底層輸入流中讀取數(shù)據(jù)的緩沖輸入流對(duì)象 bin = new BufferedInputStream(bais); //獲取文件夾路徑 File file = new File(path); //如果文件夾不存在則創(chuàng)建 if (!file.exists() && !file.isDirectory()) { file.mkdirs(); } // 創(chuàng)建到指定文件的輸出流 fout = new FileOutputStream(fileName); // 為文件輸出流對(duì)接緩沖輸出流對(duì)象 bout = new BufferedOutputStream(fout); byte[] buffers = new byte[1024]; int len = bin.read(buffers); while (len != -1) { bout.write(buffers, 0, len); len = bin.read(buffers); } // 刷新此輸出流并強(qiáng)制寫出所有緩沖的輸出字節(jié),必須這行代碼,否則有可能有問題 bout.flush(); //返回存儲(chǔ)的路徑 return fileName; } catch (IOException e) { e.printStackTrace(); } finally { try { bin.close(); fout.close(); bout.close(); } catch (IOException e) { e.printStackTrace(); } } return ""; }}
字體
SimSun.ttf 自行搜索下載
HTML中的字體,pdf不能識(shí)別,需添加字體文件
注意,在添加字體文件時(shí),需要確保字體文件的路徑正確,并且字體文件能夠被讀取到。此外,還需要確保字體文件的格式正確,可以使用BaseFont.IDENTITY_H指定字體編碼,使用BaseFont.NOT_EMBEDDED指定字體文件是否嵌入到PDF文件中。
ITextRenderer說明
ITextRenderer是一個(gè)基于iText庫的Java庫,它可以將HTML、XHTML或XML等文檔渲染成為PDF、XLS、PNG、JPEG等格式的文件。
ITextRenderer庫提供了一個(gè)
ITextRenderer
類,該類提供了豐富的API,用于將HTML、XHTML或XML文檔轉(zhuǎn)換成為PDF等格式的文件。該類內(nèi)部使用了iText庫的PDF生成和操作功能,同時(shí)也支持使用Flying Saucer庫對(duì)文檔進(jìn)行渲染和布局。使用ITextRenderer庫進(jìn)行PDF輸出的基本流程如下:
1)創(chuàng)建一個(gè)ITextRenderer對(duì)象;
2)使用setDocument()方法將要轉(zhuǎn)換的文檔設(shè)置到渲染器中;
3)使用layout()方法對(duì)文檔進(jìn)行排版布局;
4)使用createPDF()方法將文檔渲染為PDF,并輸出到輸出流或文件中。
ITextFontResolver說明
ITextFontResolver是ITextRenderer庫中的一個(gè)類,它用于管理和解析字體文件,為PDF生成提供字體支持。
在ITextRenderer庫中,當(dāng)使用HTML文檔生成PDF時(shí),由于PDF不支持HTML中使用的所有字體,因此需要在生成PDF之前將HTML中的字體替換為PDF支持的字體。ITextFontResolver提供了一個(gè)addFont()方法,該方法用于將字體文件添加到ITextFontResolver中進(jìn)行管理,以便在PDF生成時(shí)使用。
轉(zhuǎn)換為Base64說明
Base64是一種用于將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成文本數(shù)據(jù)的編碼方式,通過Base64編碼可以將圖片、音頻、視頻等二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成文本數(shù)據(jù),從而方便在網(wǎng)絡(luò)上傳輸。
4. 圖片轉(zhuǎn)Base64 工具類
import org.apache.commons.lang.StringUtils;import javax.xml.bind.DatatypeConverter;import java.io.*;import java.net.HttpURLConnection;import java.net.URL;/** * @Author:wangdi * @Date:2023/6/9 15:34 * @Des: ImgBase64Util 圖片轉(zhuǎn)Base64 工具類 */public class ImgBase64Util { public final static String IMG_PRE = "data:image/png;base64,"; public static void main(String[] args) throws Exception { //本地圖片地址 String url = "D:/Soft/IDEA/IDEA_PLUGINS/Img/727eee40a3202c6799fffe55c9d6a026.jpg"; //在線圖片地址 String string = "https://devpress.yssmx.com/489fad64a62648818eaaebc28e5c8659.jpg"; String str = ImageToBase64ByLocal(url); System.out.println(str); String ste = ImageToBase64ByOnline(string);// Base64Utils.Base64ToImage(str,"C:/Users/Administrator/Desktop/test1.jpg");// Base64Utils.Base64ToImage(ste, "C:/Users/Administrator/Desktop/test2.jpg"); } /** * 本地圖片轉(zhuǎn)換成base64字符串 * * @param imgFile 圖片本地路徑 * @return */ public static String ImageToBase64ByLocal(String imgFile) {// 將圖片文件轉(zhuǎn)化為字節(jié)數(shù)組字符串,并對(duì)其進(jìn)行Base64編碼處理 InputStream in = null; byte[] data = null; // 讀取圖片字節(jié)數(shù)組 try { in = new FileInputStream(imgFile); data = new byte[in.available()]; in.read(data); } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } return DatatypeConverter.printBase64Binary(data); } /** * 在線圖片轉(zhuǎn)換成base64字符串 * * @param imgURL 圖片線上路徑 * @return */ public static String ImageToBase64ByOnline(String imgURL) { ByteArrayOutputStream data = new ByteArrayOutputStream(); InputStream is = null; try { // 創(chuàng)建URL URL url = new URL(imgURL); byte[] by = new byte[1024]; // 創(chuàng)建鏈接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); is = conn.getInputStream(); // 將內(nèi)容讀取內(nèi)存中 int len = -1; while ((len = is.read(by)) != -1) { data.write(by, 0, len); } // 關(guān)閉流 } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (Exception e) { e.printStackTrace(); } } return DatatypeConverter.printBase64Binary(data.toByteArray());// // 對(duì)字節(jié)數(shù)組Base64編碼// BASE64Encoder encoder = new BASE64Encoder();// return encoder.encode(data.toByteArray()); } /** * base64字符串轉(zhuǎn)換成圖片 * * @param imgStr base64字符串 * @param imgFilePath 圖片存放路徑 * @return */ public static boolean Base64ToImage(String imgStr, String imgFilePath) { // 對(duì)字節(jié)數(shù)組字符串進(jìn)行Base64解碼并生成圖片 if (StringUtils.isEmpty(imgStr)) // 圖像數(shù)據(jù)為空 return false; OutputStream out = null; try { byte[] b = DatatypeConverter.parseBase64Binary(imgStr); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 調(diào)整異常數(shù)據(jù) b[i] += 256; } } out = new FileOutputStream(imgFilePath); out.write(b); out.flush(); return true; } catch (Exception e) { return false; } finally { try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } } }}
5. 測(cè)試使用
文章來源:http://www.zghlxwxcb.cn/news/detail-487943.html
@Autowiredprivate HtmlToPDFUtil htmlToPDFUtil;/* * 渲染pdf注意: * 要生成一個(gè)獨(dú)立的html文件 * 其中css樣式必須內(nèi)嵌,不可以單獨(dú)是css文件,否則會(huì)渲染不成功 * 圖片的處理采用base64方式進(jìn)行渲染,可以將圖片全部保存到項(xiàng)目里面,采用代碼轉(zhuǎn)換base64進(jìn)行塞參數(shù)渲染,或者直接在html中圖片就使用base64格式 * */@Testpublic void changeTaskReport() throws Exception { Map<String, Object> data = new HashMap(); data.put("name", "Alice"); data.put("age", 20); // 此處的圖片可以用相對(duì)路徑,配合Thread.currentThread().getContextClassLoader().getResource("").getPath(); 獲取路徑使用,注意測(cè)試類啟動(dòng)的和SpringBoot啟動(dòng)的路徑地址不一致 data.put("imgSrc", ImgBase64Util.IMG_PRE + ImgBase64Util.ImageToBase64ByLocal("C:\\Users\\wangdi13\\Desktop\\Snipaste_2023-06-09_15-43-25.png")); String html = htmlToPDFUtil.render("test.html", data); System.out.println(html); String base64 = HtmlToPDFUtil.getPDFBase64ByHtml(html); String pdfAdd = HtmlToPDFUtil.base64ToPDF(base64, "D:\\______________________________________WorkSpace\\demo-wy-test\\src\\main\\resources\\"); System.out.println(pdfAdd);}
接下一篇 SpringBoot Thymeleaf企業(yè)級(jí)真實(shí)應(yīng)用:使用Flying Saucer結(jié)合iText5將HTML界面數(shù)據(jù)轉(zhuǎn)換為PDF輸出(二) 設(shè)置多字體, 以及中文不顯示的問題文章來源地址http://www.zghlxwxcb.cn/news/detail-487943.html
到了這里,關(guān)于SpringBoot+Thymeleaf 后端轉(zhuǎn)html,pdf HTML生成PDF SpringBoot生成PDF Java PDF生成的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!