使用xdocreport導出word

之前java總用freemaker進行導出,但是改xml實在是太繁瑣了,這次找了另一個工具進行體驗.

一、簡單導出

pom引入

 <dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.core</artifactId><version>2.0.6</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document</artifactId><version>2.0.6</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template</artifactId><version>2.0.6</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document.docx</artifactId><version>2.0.6</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId><version>2.0.6</version></dependency>

導出代碼

public void genDoc() {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;HttpServletResponse response = attributes.getResponse();try (InputStream inputStream = POICacheManager.getFile("template.docx")) {// 3. 讀取模板,創建 IXDocReport 對象IXDocReport report = XDocReportRegistry.getRegistry().loadReport(inputStream, TemplateEngineKind.Freemarker);// 4. 創建上下文,設置變量(你可以按需擴展)IContext context = report.createContext();context.put("name", "張三");//編輯域代碼 ctrl F9 類別選 郵件合并 域名mergefield 域代碼后面填 ${name}// 設置響應頭,準備輸出 Word 文件response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");response.setHeader("Content-Disposition", "attachment; filename=generated-document.docx");// 5. 生成 Word 并寫入響應輸出流try (OutputStream out = response.getOutputStream()) {report.process(context, out);}} catch (Exception e) {log.error(">>> 生成 Word 失敗:", e);// 手動返回錯誤信息try {response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);response.getWriter().write("生成文檔失敗:" + e.getMessage());} catch (Exception ex) {log.error(">>> 寫回錯誤信息失敗", ex);}}}

在resource目錄新建word文件名為template.docx

打開template.docx

輸入任意字符,然后 Ctrl+9插入域,然后右鍵編輯域,類別選 郵件合并 域名選mergefield 域代碼后面填 ${name} 保存后用上面的代碼導出

導出后可以看到域代碼位置被填充為張三了。

二、進階用法

1.動態表格行

分兩種情況處理

(1)第一列為序號列

將第一列填充3個域??

"@before-row[#list productInfoList as item]" 
${item?index+1} 
@after-row[/#list] 

第二列 填充實際的字段即可

${item.name}

(2)第一列不序號列

將上文中的序號表達式${item?index+1}?換成你想填充的表達式,如

${item.code} 

其他處理跟上賣弄一樣

在java中的定義,先定義實體,然后context.put即可

//假設之前定義了productInfo實體,實體有code name等字段
List<ProductInfo> productInfoList = new ArrayList();
...context.put("productInfoList", productInfoList );

2.圖片

圖片不用域,在要導入的地方插入一張圖片,然后建立書簽,建立書簽的方法如下

選中文檔中的某張圖片,單擊【插入】菜單下【鏈接】子菜單中的【書簽】。

這里的書簽名跟上面的域變量名類似

java代碼

//根據文件讀取
IImageProvider iImageProvider = new FileImageProvider(file, false);
context.put("pic", iImageProvider);//dataurlbase64的字符串,不含前綴
byte[] imageBytes = Base64.getDecoder().decode(base64Image);
//創建 ByteArrayImageProvider 實例
ByteArrayImageProvider imageProvider = new ByteArrayImageProvider(imageBytes, "png");
context.put("pic", imageProvider );

3.條件顯示隱藏

使用if標簽,下面是3個域

[#if data.ccUser??] 申請人:${data.ccUser } [/#if]

可以看到兩個if標簽域包裹了文字和變量

4.空值處理

空值直接使用會報錯,可使用表達式

${tx.amount!}

或者

${tx.amount?if_exists}

上面表達式表示有值填充,無值不填充

5.單元格合并

實現起來比較復雜,在模板中先合并,然后對多列使用第一節的動態表格行基本上可以實現按層級合并,如果是跨列合并,比較復雜的合并目前還沒找到好的解決方案?或許需要考慮原生freemaker或者poi-tl?

6.關鍵字

在實體中應盡量避免使用以下關鍵字

length?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86074.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86074.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86074.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vscode里如何用git

打開vs終端執行如下&#xff1a; 1 初始化 Git 倉庫&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 倉庫 git add . 3 使用 git commit 命令來提交你的更改。確保在提交時加上一個有用的消息。 git commit -m "備注信息" 4 …

C++.OpenGL (2/64)你好,三角形(Hello Triangle)

你好,三角形(Hello Triangle) 繪制流程概覽 #mermaid-svg-MvIGIovxiuKVfzy8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MvIGIovxiuKVfzy8 .error-icon{fill:#552222;}#mermaid-svg-MvIGIovxiuKVfzy8 .error…

汽車安全體系:FuSa、SOTIF、Cybersecurity 從理論到實戰

汽車安全&#xff1a;功能安全&#xff08;FuSa&#xff09;、預期功能安全&#xff08;SOTIF&#xff09;與網絡安全(Cybersecurity) 從理論到實戰的安全體系 引言&#xff1a;自動駕駛浪潮下的安全挑戰 隨著自動駕駛技術從L2向L4快速演進&#xff0c;汽車安全正從“機械可靠…

N2語法 列挙、話題提出

1&#xff0c;&#xff5e;やら&#xff5e;やら  接続&#xff1a;名詞、辭書形  意味&#xff1a;…啦…啦&#xff08;列舉代表性的事物&#xff09;  例文&#xff1a;     家に帰って料理やら洗濯やら何もしなければならない。     帰國前、買い物やら荷造りや…

深入理解React Hooks的原理與實踐

深入理解React Hooks的原理與實踐 引言 React Hooks 自 2018 年 React 16.8 發布以來&#xff0c;徹底改變了前端開發者的編碼方式。它通過函數式組件提供了狀態管理和生命周期等功能&#xff0c;取代了傳統的類組件&#xff0c;使得代碼更加簡潔、復用性更強。然而&#xff…

RockyLinux9.6搭建k8s集群

博主介紹&#xff1a;?全網粉絲5W&#xff0c;全棧開發工程師&#xff0c;從事多年軟件開發&#xff0c;在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰&#xff0c;博主也曾寫過優秀論文&#xff0c;查重率極低&#xff0c;在這方面有豐富的經驗…

鏈游技術破壁:NFT資產確權與Play-to-Earn經濟模型實戰

鏈游技術破壁&#xff1a;NFT資產確權與Play-to-Earn經濟模型實戰 ——從「投機泡沫」到「可持續生態」的技術重構 一、NFT確權技術革新&#xff1a;從鏈上存證到動態賦權 跨鏈確權架構 全鏈互操作協議&#xff1a;采用LayerZero協議實現以太坊裝備與Solana土地的跨鏈組合&…

Java下載文件(特殊字符編碼處理)

當你在這個問題上花費了數小時而解決不了&#xff0c;你才會知道這篇文章對你的幫助 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; import org.springframewo…

TDengine 高級功能——讀緩存

簡介 在物聯網&#xff08;IoT&#xff09;和工業互聯網&#xff08;IIoT&#xff09;大數據應用場景中&#xff0c;實時數據的價值往往遠超歷史數據。企業不僅需要數據處理系統具備高效的實時寫入能力&#xff0c;更需要能快速獲取設備的最新狀態&#xff0c;或者對最新數據進…

YOLO在C#中的完整訓練、驗證與部署方案

YOLO在C#中的完整訓練、驗證與部署方案 C# 在 YOLO 部署上優勢明顯&#xff08;高性能、易集成&#xff09;&#xff0c;但訓練能力較弱&#xff0c;通常需結合 Python 實現。若項目對開發效率要求高且不依賴 C# 生態&#xff0c;建議全程使用 Python&#xff1b;若需深度集成…

pikachu靶場通關筆記17 CSRF關卡03-CSRF(Token)

目錄 一、CSRF原理 二、CSRF Token 三、源碼分析 四、CSRF Token tracker插件 1、插件簡介 2、插件安裝 五、滲透實戰 1、用戶登錄 2、修改個人信息 3、bp攔截報文 4、bp改報文探測 5、配置CSRF-Token-Tracer 6、bp改包成功 7、查看CSRF Token Tracker配置 本系…

C#面試問題81-100

85. What are anonymous types? 匿名類型是在需要的地方直接定義的類型&#xff0c;甚至都 不給它命名。它非常適合我們這種用例——類型小且臨時&#xff0c;而且我們無意在其 他地方使用它 匿名類型是直接從 System.Object 派生的類對象。它們不能轉換為任何 其他類型。●…

【Ragflow】25.Ragflow-plus開發日志:excel文件解析新思路/公式解析適配

引言 RagflowPlus v0.3.0 版本中&#xff0c;增加了對excel文件的解析支持&#xff0c;但收到反饋&#xff0c;說效果并不佳。 以下測試文件內容來自群友反饋提供&#xff0c;數據已脫敏處理。 經系統解析后&#xff0c;分塊效果如下&#xff1a; 可以看到&#xff0c;由于該…

VS2022下C++ Boost庫安裝與使用使用

一.Boost概述 1.簡介 Boost 是一個廣泛使用的 C 庫集合&#xff0c;提供了許多高質量、可移植、高效的工具和組件&#xff0c;被視為 C 標準庫的延伸。自 1998 年成立以來&#xff0c;Boost 已成為 C 社區的核心資源&#xff0c;許多 Boost 庫通過實踐驗證后被納入 C 標準&am…

內嵌式mqtt server

添加moquette依賴 <dependency><groupId>io.moquette</groupId><artifactId>moquette-broker</artifactId><version>0.17</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>…

php執行后報502,無錯誤提示的排查和解決

文章目錄 一、闡述問題二、開始排查1.執行代碼展示2.PHP層面排查問題3.系統層面排查問題1. 分析系統日志2. core dump 分析2.1 core dump 是什么2.2 core dump 配置 并 生成 core 文件2.3 gdb 解析 core 文件 4. 問題解決 三、贈送內容四、總結 一、闡述問題 這個問題花了我起…

MySQL 核心知識點解析

最近正在復習Java八股&#xff0c;所以會將一些熱門的八股問題&#xff0c;結合ai與自身理解寫成博客便于記憶 InnoDB 和 MyISAM 的區別 特性InnoDBMyISAM事務支持支持ACID事務不支持事務鎖機制行級鎖表級鎖外鍵支持支持不支持崩潰恢復有crash-safe能力無存儲結構聚簇索引非…

CppCon 2015 學習:Comparison is not simple, but it can be simpler.

What is comparison? 這段文字是從計算機科學、編譯器設計或系統優化的角度來定義和評價“比較&#xff08;comparison&#xff09;”這個操作&#xff1a; 1. Pervasive&#xff08;無處不在&#xff09; 比較操作在編程中極為常見&#xff0c;存在于&#xff1a; 分支語句&…

RocketMQ入門5.3.2版本(基于java、SpringBoot操作)

一、RocketMQ概述 RocketMQ是一款由阿里巴巴于2012年開源的分布式消息中間件&#xff0c;旨在提供高吞吐量、高可靠性的消息傳遞服務。主要特點有&#xff1a; 靈活的可擴展性 海量消息堆積能力 支持順序消息 支持多種消息過濾方式 支持事務消息 支持回溯消費 支持延時消…

VR線上展廳特點分析與優勢

VR線上展廳&#xff1a;特點、優勢與實際應用 VR線上展廳&#xff0c;作為虛擬現實&#xff08;VR&#xff09;技術在展示行業的創新應用&#xff0c;正逐步改變著傳統的展覽方式。通過模擬真實的物理環境&#xff0c;為參觀者提供身臨其境的展覽體驗&#xff0c;成為展示行業…