91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

jf_ro2CN3Fa ? 來源:Java知音 ? 作者:武哥 ? 2022-10-31 11:08 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

廢話不多說直接進(jìn)入正題,首先分析生成pdf場(chǎng)景及生成內(nèi)容,考慮復(fù)用性和維護(hù)難度是我們當(dāng)前開發(fā)工作的第一要?jiǎng)?wù)!

下面是調(diào)研的幾個(gè)主要方案:

一、itext 表單填充

使用方式:

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

方案優(yōu)缺點(diǎn):

優(yōu)點(diǎn):代碼優(yōu)雅,生成后格式變化影響極小。

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

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

項(xiàng)目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

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

二、freemarker + doc4J 基于Word 生成 PDF

使用方式:

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

方案優(yōu)缺點(diǎn):

優(yōu)點(diǎn):通用性強(qiáng),基于模板引擎功能強(qiáng)大。

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

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

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

三、freemarker + aspose-words 導(dǎo)出PDF

使用方式:

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

方案優(yōu)缺點(diǎn):

優(yōu)點(diǎn):通用性強(qiáng),基于模板引擎功能強(qiáng)大,無需手工管理字體(macOS),代碼簡(jiǎn)單,導(dǎo)出格式與模板基本無差異。

缺點(diǎn):需要編輯 XML 模板;該方案不是免費(fèi)版(當(dāng)然有大神)。

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

四、html + freemarker + itextpdf(html2pdf)

使用方式:

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

方案優(yōu)缺點(diǎn):

優(yōu)點(diǎn):可維護(hù)性相較與上面方案都有極大提升(調(diào)試可見性,動(dòng)態(tài)替換生效);通用性強(qiáng),基于模板引擎功能強(qiáng)大;導(dǎo)出格式可控性較強(qiáng);

缺點(diǎn):需要中文字體庫(kù)。

這個(gè)方案是綜合以上多次踩坑的結(jié)果,結(jié)果是顯而易見的。

淺淺來一點(diǎn)代碼,省的大家到處找



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


個(gè)人以為自己的代碼會(huì)自解釋,就不貼太多注釋了

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();

//導(dǎo)入需要字體庫(kù)的位置哦;simsun 為宋體
publicstaticfinalStringFRONT_PATH="/usr/share/fonts/simsun.ttc";

/**
*看明白的話只用這個(gè)方法就夠
*/
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);
//設(shè)置模板的編碼格式
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();
}

}

結(jié)

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





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • XML
    XML
    +關(guān)注

    關(guān)注

    0

    文章

    188

    瀏覽量

    34545
  • HTML
    +關(guān)注

    關(guān)注

    0

    文章

    280

    瀏覽量

    48582

原文標(biāo)題:服務(wù)端自定義生成PDF的幾種方案

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何為 Vision Five 2 編譯自定義 Linux 內(nèi)核?

    Vision Five 2 的 Debian 用戶指南只提供了半頁關(guān)于如何編譯自己的內(nèi)核的相當(dāng)稀疏的內(nèi)容。僅從該文檔中,我無法制作我的自定義內(nèi)核。那里的信息似乎相當(dāng)不完整。如果有人能提供一些
    發(fā)表于 02-24 07:44

    OPC UA 服務(wù)端用戶認(rèn)證的底層邏輯:哈希與加鹽應(yīng)用詳解

    摘要在基于UnifiedAutomationSDK開發(fā)OPCUA服務(wù)端時(shí),用戶認(rèn)證(UserAuthentication)是安全體系的第一道防線。除了傳輸層的加密通道外,服務(wù)端如何安全地存儲(chǔ)和驗(yàn)證
    的頭像 發(fā)表于 01-15 17:29 ?172次閱讀
    OPC UA <b class='flag-5'>服務(wù)端</b>用戶認(rèn)證的底層邏輯:哈希與加鹽應(yīng)用詳解

    電能質(zhì)量監(jiān)測(cè)裝置可自定義監(jiān)測(cè)時(shí)段嗎?

    電能質(zhì)量監(jiān)測(cè)裝置普遍支持自定義監(jiān)測(cè)時(shí)段,現(xiàn)代中高端裝置還具備分時(shí)差異化監(jiān)測(cè)與靈活觸發(fā)能力,可按時(shí)間、事件或混合策略定制采集與存儲(chǔ),兼顧精度、效率與存儲(chǔ)成本。 一、自定義監(jiān)測(cè)時(shí)段的核心實(shí)現(xiàn)方式 1.
    的頭像 發(fā)表于 12-10 16:49 ?1089次閱讀

    電能質(zhì)量在線監(jiān)測(cè)裝置的自定義監(jiān)測(cè)時(shí)段功能有哪些應(yīng)用場(chǎng)景?

    電能質(zhì)量在線監(jiān)測(cè)裝置的 自定義監(jiān)測(cè)時(shí)段功能 ,核心價(jià)值是通過 “按需配置監(jiān)測(cè)時(shí)間、采樣頻率和數(shù)據(jù)策略”,實(shí)現(xiàn)精準(zhǔn)監(jiān)測(cè)、資源優(yōu)化與數(shù)據(jù)針對(duì)性分析,其應(yīng)用場(chǎng)景覆蓋工業(yè)生產(chǎn)、商業(yè)運(yùn)營(yíng)、電網(wǎng)運(yùn)維、特殊保障等
    的頭像 發(fā)表于 12-10 14:01 ?432次閱讀
    電能質(zhì)量在線監(jiān)測(cè)裝置的<b class='flag-5'>自定義</b>監(jiān)測(cè)時(shí)段功能有哪些應(yīng)用場(chǎng)景?

    無圖形界面模式下自定義檢查工具的應(yīng)用

    此前文章已介紹 ANSA 中的自定義檢查工具。本文將探討該功能在無圖形界面(No-GUI)模式下的應(yīng)用,旨在滿足標(biāo)準(zhǔn)化工作流程的需求,適用于需要高度自動(dòng)化的前處理場(chǎng)景。通過集成自定義檢查,用戶可實(shí)現(xiàn)工作流程的高效自動(dòng)化運(yùn)行。
    的頭像 發(fā)表于 11-30 14:13 ?607次閱讀
    無圖形界面模式下<b class='flag-5'>自定義</b>檢查工具的應(yīng)用

    AMD利用可重構(gòu)FPGA設(shè)備Moku實(shí)現(xiàn)自定義激光探測(cè)解決方案

    摘要本文介紹了AdvancedMicroDevices,AMD公司如何基于可重構(gòu)FPGA設(shè)備自定義激光探測(cè)解決方案,替代傳統(tǒng)的儀器配置,通過靈活且可定制的FPGA設(shè)備Moku提供更高效和靈活的激光
    的頭像 發(fā)表于 11-20 17:28 ?1750次閱讀
    AMD利用可重構(gòu)FPGA設(shè)備Moku實(shí)現(xiàn)<b class='flag-5'>自定義</b>激光探測(cè)解決<b class='flag-5'>方案</b>

    采用匯編指示符來使用自定義指令

    、采用.insn匯編指示符實(shí)現(xiàn)risc-v自定義指令。這種方式可以指定工具來選擇寄存器,也可以自己選定寄存器。指令格式如下(引自gnu 匯編器手冊(cè)): 演示案例可以查看芯來官方案例,這里
    發(fā)表于 10-28 06:02

    LOTO示波器自定義解碼功能—CANFD解碼

    LOTO示波器軟件更新了自定義解碼功能,并在bilibili上傳了演示視頻,視頻鏈接: https://www.bilibili.com/video/BV1wq3ezjEjQ
    的頭像 發(fā)表于 07-11 10:34 ?1087次閱讀
    LOTO示波器<b class='flag-5'>自定義</b>解碼功能—CANFD解碼

    大彩講堂:VisualTFT軟件如何自定義圓形進(jìn)度條

    VisualTFT軟件如何自定義圓形進(jìn)度條
    的頭像 發(fā)表于 07-07 17:10 ?1680次閱讀
    大彩講堂:VisualTFT軟件如何<b class='flag-5'>自定義</b>圓形進(jìn)度條

    KiCad 中的自定義規(guī)則(KiCon 演講)

    “ ?Seth Hillbrand 在 KiCon US 2025 上為大家介紹了 KiCad 的規(guī)則系統(tǒng),并詳細(xì)講解了自定義規(guī)則的設(shè)計(jì)與實(shí)例。? ” ? 演講主要圍繞 加強(qiáng) KiCad 中的自定義
    的頭像 發(fā)表于 06-16 11:17 ?2210次閱讀
    KiCad 中的<b class='flag-5'>自定義</b>規(guī)則(KiCon 演講)

    HarmonyOS應(yīng)用自定義鍵盤解決方案

    自定義鍵盤是一種替換系統(tǒng)默認(rèn)鍵盤的解決方案,可實(shí)現(xiàn)鍵盤個(gè)性化交互。允許用戶結(jié)合業(yè)務(wù)需求與操作習(xí)慣,對(duì)按鍵布局進(jìn)行可視化重構(gòu)、設(shè)置多功能組合鍵位,使輸入更加便捷和舒適。在安全防護(hù)層面,自定義鍵盤可以
    的頭像 發(fā)表于 06-05 14:19 ?2436次閱讀

    如何使用自定義設(shè)置回調(diào)函數(shù)?

    你好,我正在嘗試編寫自己的自定義設(shè)置回調(diào)函數(shù),并使用 fastEnum=false。 是否有任何代碼示例或資料可供我參考? void CyU3PUsbRegisterSetupCallback
    發(fā)表于 05-21 06:11

    LabVIEW運(yùn)動(dòng)控制(三):EtherCAT運(yùn)動(dòng)控制器的高效加工指令自定義封裝

    LabVIEW高效加工指令自定義封裝
    的頭像 發(fā)表于 04-08 13:49 ?3683次閱讀
    LabVIEW運(yùn)動(dòng)控制(三):EtherCAT運(yùn)動(dòng)控制器的高效加工指令<b class='flag-5'>自定義</b>封裝

    MIMXRT1176如何在MBDT中正確實(shí)現(xiàn)自定義LUT?

    我正在嘗試創(chuàng)建自定義 LUT,但不確定如何進(jìn)行。默認(rèn)閃存類型為 ISSI IS25WP064A-JBLE,但我想使用 FM25V02A-GTR。我嘗試用我自己的 LUT 條目修改生成的文件
    發(fā)表于 04-08 07:56

    MKW45B41Z客戶無法從服務(wù)器獲取服務(wù)是為什么?

    。MKW45B41Z (自定義板) 充當(dāng)中央設(shè)備客戶角色。MKW45 客戶掃描外圍設(shè)備(NRF 連接)設(shè)備并連接到外圍設(shè)備(NRF 連接)設(shè)備。連接 MKW45(自定義板卡)后,客
    發(fā)表于 03-28 07:40