精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

分享服務端自定義生成PDF的幾種方案

jf_ro2CN3Fa ? 來源:Java知音 ? 作者:武哥 ? 2022-10-31 11:08 ? 次閱讀

廢話不多說直接進入正題,首先分析生成pdf場景及生成內容,考慮復用性和維護難度是我們當前開發工作的第一要務!

下面是調研的幾個主要方案:

一、itext 表單填充

使用方式:

itext表單填充方案是以pdf作為基礎模板,通過在pdf中嵌入表單元素組件的方式(需要使用pdf編輯工具),最后由程序進行數據填充并另存為pdf結果。

方案優缺點:

優點:代碼優雅,生成后格式變化影響極小。

缺點:原始模板變化需要重新生成pdf,重新編輯表單元素;不支持列表填充數據。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

視頻教程:https://doc.iocoder.cn/video/

二、freemarker + doc4J 基于Word 生成 PDF

使用方式:

首先將調整好格式的原始 word 導出為 XML 格式,編輯 XML 模板中需要填充元素的位置,最后由程序處理先由freemarker模板工具替換元素內容,再使用doc4J進行pdf導出。

方案優缺點:

優點:通用性強,基于模板引擎功能強大。

缺點:XML 格式的word真的有夠復雜,想要在此模板上調整樣式真的難上加難;由于系統不支持的原因需要導入中文字體庫;doc4J 部分 doc 元素不支持(例如直線),導出格式差異較大。

這可能是由于doc4J迭代問題無法保證新元素的支持,導出結果比較奔放。。。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

三、freemarker + aspose-words 導出PDF

使用方式:

類似于 freemarker+doc4J 方式,同樣需要編輯XML,導出格式相較doc4J而言有極大提升。

方案優缺點:

優點:通用性強,基于模板引擎功能強大,無需手工管理字體(macOS),代碼簡單,導出格式與模板基本無差異。

缺點:需要編輯 XML 模板;該方案不是免費版(當然有大神)。

受限于調試前期需要的修修改改,模板能給人整吐了,所以才有了下一個方案。

四、html + freemarker + itextpdf(html2pdf)

使用方式:

翻譯 word 為 html 頁面(當然就是手寫啦,還原度很重要!),html中模板元素插入(文字填充、列表循環 freemarker 支持的全都能寫),最后由程序處理先由freemarker模板工具替換元素內容,再使用html2pdf進行pdf導出。

方案優缺點:

優點:可維護性相較與上面方案都有極大提升(調試可見性,動態替換生效);通用性強,基于模板引擎功能強大;導出格式可控性較強;

缺點:需要中文字體庫。

這個方案是綜合以上多次踩坑的結果,結果是顯而易見的。

淺淺來一點代碼,省的大家到處找



com.itextpdf
itextpdf
5.5.13


com.itextpdf
html2pdf
3.0.3


org.xhtmlrenderer
flying-saucer-pdf-itext5
9.0.3


binarta.oss
groovy-template-enginex-freemarker
0.1.3


個人以為自己的代碼會自解釋,就不貼太多注釋了

importcn.hutool.core.io.FileUtil;
importcn.hutool.core.map.MapUtil;
importcom.google.common.collect.Lists;
importcom.itextpdf.text.pdf.BaseFont;
importfreemarker.cache.ByteArrayTemplateLoader;
importfreemarker.template.Configuration;
importfreemarker.template.Template;
importlombok.SneakyThrows;
importorg.xhtmlrenderer.pdf.ITextFontResolver;
importorg.xhtmlrenderer.pdf.ITextRenderer;

importjava.io.BufferedWriter;
importjava.io.ByteArrayOutputStream;
importjava.io.File;
importjava.io.StringWriter;
importjava.nio.charset.Charset;
importjava.nio.charset.StandardCharsets;
importjava.util.List;
importjava.util.Locale;
importjava.util.Map;
importjava.util.Objects;
importjava.util.function.Supplier;

publicclassHtmlToPdfUtil{

privatestaticfinalByteArrayTemplateLoaderTEMPLATE_LOADER=newByteArrayTemplateLoader();

//導入需要字體庫的位置哦;simsun 為宋體
publicstaticfinalStringFRONT_PATH="/usr/share/fonts/simsun.ttc";

/**
*看明白的話只用這個方法就夠
*/
publicstaticByteArrayOutputStreamhtmlToPdf(StringtemplateName,SupplierloadTemplateSupplier,MapmodeViewMap){

Stringhtml=xmlFormat(templateName,loadTemplateSupplier,modeViewMap);

returnhtmlToPdf(html);
}

@SneakyThrows
publicstaticByteArrayOutputStreamhtmlToPdf(StringhtmlStr){
ByteArrayOutputStreamoutputStream=newByteArrayOutputStream();
ITextRendererrenderer=newITextRenderer();
renderer.setDocumentFromString(htmlStr);
ITextFontResolverresolver=renderer.getFontResolver();
//添加字體,解決中文不顯示的問題
resolver.addFont(FRONT_PATH,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(outputStream);
returnoutputStream;
}


publicstaticStringxmlFormat(StringtemplateName,SupplierloadTemplateSupplier,MapmodeViewMap){
if(Objects.isNull(TEMPLATE_LOADER.findTemplateSource(templateName))){
synchronized(TEMPLATE_LOADER){
if(Objects.isNull(TEMPLATE_LOADER.findTemplateSource(templateName))){
TEMPLATE_LOADER.putTemplate(templateName,loadTemplateSupplier.get());
}
}
}
returnxmlFormat(templateName,modeViewMap);
}

@SneakyThrows
publicstaticStringxmlFormat(StringtemplateName,MapmodeViewMap){
Configurationcfg=newConfiguration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
//指定FreeMarker模板文件的位置
cfg.setTemplateLoader(TEMPLATE_LOADER);
//設置模板的編碼格式
cfg.setEncoding(Locale.CHINA,Charset.defaultCharset().name());
//獲取模板文件template
Templatetemplate=cfg.getTemplate(templateName,Charset.defaultCharset().name());
StringWriterstringWriter=newStringWriter();

BufferedWriterwriter=newBufferedWriter(stringWriter);
template.process(modeViewMap,writer);
returnstringWriter.toString();
}

}

解決這個問題的核心思路方案其實一直沒變,變化的只是工具,一定要思路清晰!





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • XML
    XML
    +關注

    關注

    0

    文章

    188

    瀏覽量

    33047
  • HTML
    +關注

    關注

    0

    文章

    277

    瀏覽量

    34574

原文標題:服務端自定義生成PDF的幾種方案

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    TPS659xx應用程序自定義工具

    電子發燒友網站提供《TPS659xx應用程序自定義工具.pdf》資料免費下載
    發表于 11-06 10:02 ?0次下載
    TPS659xx應用程序<b class='flag-5'>自定義</b>工具

    美國硅谷高防服務自定義解析

      隨著互聯網技術的快速發展,數據安全成為了企業和個人關注的重點。美國硅谷作為全球科技創新的中心之一,其高防服務器技術也在不斷發展,為企業和個人提供更加安全可靠的網絡環境。本文將介紹什么是高防服務器及其自定義選項的重要性。
    的頭像 發表于 09-27 10:10 ?120次閱讀

    創建自定義的基于閃存的引導加載程序(BSL)

    電子發燒友網站提供《創建自定義的基于閃存的引導加載程序(BSL).pdf》資料免費下載
    發表于 09-19 10:50 ?0次下載
    創建<b class='flag-5'>自定義</b>的基于閃存的引導加載程序(BSL)

    NVIDIA AI Foundry 為全球企業打造自定義 Llama 3.1 生成式 AI 模型

    Foundry 提供從數據策管、合成數據生成、微調、檢索、防護到評估的全方位生成式 AI 模型服務,以便部署自定義 Llama 3.1 NVIDIA NIM 微
    發表于 07-24 09:39 ?685次閱讀
    NVIDIA AI Foundry 為全球企業打造<b class='flag-5'>自定義</b> Llama 3.1 <b class='flag-5'>生成</b>式 AI 模型

    如何使用云服務器刷寫自定義固件?

    我們正在嘗試在沒有以前刷新固件的情況下刷新我們的自定義固件。所以里面有原裝AT固件。 當模塊連接到 WiFi 和互聯網時,在 AT CIUPDATE 之后一切正常。但它正在下載/更新您的原始
    發表于 07-15 08:23

    服務端測試包括什么類型

    服務端測試是確保軟件系統在服務器端正常運行和滿足性能要求的重要環節。本文將詳細介紹服務端測試的類型、方法和最佳實踐。 1. 服務端測試的定義
    的頭像 發表于 05-30 16:03 ?653次閱讀

    服務端測試是web測試嗎為什么

    服務端測試和Web測試是兩個不同的概念,但它們在軟件開發和測試過程中是相互關聯的。本文將詳細解釋這兩個概念以及它們之間的關系。 服務端測試 服務端測試主要關注服務器端的軟件組件,這些組
    的頭像 發表于 05-30 15:30 ?565次閱讀

    服務端測試和客戶測試區別在哪

    服務端測試和客戶測試是軟件開發過程中的兩個重要環節,它們分別針對服務器端和客戶的軟件進行測試。本文將詳細介紹服務端測試和客戶
    的頭像 發表于 05-30 15:27 ?2765次閱讀

    服務端的測試主要是測什么內容

    服務端測試是軟件開發過程中的一個重要環節,主要目的是確保服務端程序的穩定性、性能、安全性和可靠性。 功能測試 功能測試是服務端測試的基礎,主要驗證服務端程序是否按照需求實現了所有功能。
    的頭像 發表于 05-30 15:24 ?3723次閱讀

    HarmonyOS開發案例:【 自定義彈窗】

    基于ArkTS的聲明式開發范式實現了三種不同的彈窗,第一種直接使用公共組件,后兩種使用CustomDialogController實現自定義彈窗
    的頭像 發表于 05-16 18:18 ?1296次閱讀
    HarmonyOS開發案例:【 <b class='flag-5'>自定義</b>彈窗】

    TSMaster 自定義 LIN 調度表編程指導

    LIN(LocalInterconnectNetwork)協議調度表是用于LIN總線通信中的消息調度的一種機制,我們收到越來越多來自不同用戶希望能夠通過接口實現自定義LIN調度表的需求。所以在
    的頭像 發表于 05-11 08:21 ?614次閱讀
    TSMaster <b class='flag-5'>自定義</b> LIN 調度表編程指導

    微軟Dev Home應用提供自定義文件管理支持

    據悉,Microsoft 近期發布了 0.13 版 Dev Home 應用程序,除修復多項 BUG 外,還新增了自定義文件資源管理器功能。該應用支持用戶在應用內創建虛擬機,利用微軟旗下的 Hyper V 技術生成本地虛擬機。
    的頭像 發表于 04-26 11:15 ?421次閱讀

    HarmonyOS開發實例:【自定義Emitter】

    使用[Emitter]實現事件的訂閱和發布,使用[自定義彈窗]設置廣告信息。
    的頭像 發表于 04-14 11:37 ?976次閱讀
    HarmonyOS開發實例:【<b class='flag-5'>自定義</b>Emitter】

    鴻蒙ArkUI實例:【自定義組件】

    組件是 OpenHarmony 頁面最小顯示單元,一個頁面可由多個組件組合而成,也可只由一個組件組合而成,這些組件可以是ArkUI開發框架自帶系統組件,比如?`Text`?、?`Button`?等,也可以是自定義組件,本節筆者簡單介紹一下自定義組件的語法規范。
    的頭像 發表于 04-08 10:17 ?604次閱讀

    博途用戶自定義庫的使用

    博途官方提供了很多庫,比如:基本函數庫、通信庫、安全庫、驅動庫等等,用戶可以使用庫中的函數/函數塊來完成具體的控制任務。除了官方的庫,我們也可以創建自己的庫(用戶自定義庫)。比如,把項目
    的頭像 發表于 12-25 10:08 ?880次閱讀
    博途用戶<b class='flag-5'>自定義</b>庫的使用