poi-tl 生成 word 文件(插入文字、圖片、表格、圖表)

文章說明

本篇文章主要通過代碼案例的方式,展示 poi-tl 生成 docx 文件的一些常用操作,主要涵蓋以下內容 :

  • 插入文本字符(含樣式、超鏈接)
  • 插入圖片
  • 插入表格
  • 引入標簽(通過可選文字的方式,這種方式也可以實現插入圖片和插入表格)

當然 poi-tl 官方也有很詳細的介紹,官網文檔地址:https://deepoove.com/poi-tl/

項目初始化【必讀】

項目創建好之后第一件事當然是引入依賴啦。

下面是 maven 引入的依賴,如果使用 Gradle 自行轉成 Gradle 依賴。

<!-- poi 依賴 -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.5</version>
</dependency>
<!-- poi-tl -->
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.2</version>
</dependency>

在 poi-tl 生成 docx 文件時,先搞清楚三個問題:

  1. 定義 docx 模板文件:要生成怎么樣的文件,自行創建一個 docx 的模板文件
  2. 定義模板文件的數據:向模板文件中,添加數據
  3. 生成文件位置:實際開發中大多會通過網絡的方式傳遞,這里只展示生成在本地文件

本篇文章展示一些關鍵代碼,為了減少冗余,我們可以定義一個生成 docx 的工具類 PoitlUtils:

import com.deepoove.poi.XWPFTemplate;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;/*** @author 17279*/
public class PoitlUtils {/*** @param templateData 生成模板文件所需的所有數據* @param templateFilePath 模板文件路徑(這里讀取的是 resources 下的文件)* @param outputFilePath 模板文件輸入的地址*/public static void generateWordFile(Map<String, Object> templateData, String templateFilePath, String outputFilePath) {// 讀取模板文件try (InputStream templateIn = PoitlUtils.class.getResourceAsStream(templateFilePath)) {// 生成模板文件XWPFTemplate template = XWPFTemplate.compile(templateIn).render(templateData);template.writeAndClose(new FileOutputStream(outputFilePath));// 這個目的是:生成文件之后調用 cmd 打開本地文件,實際生產不需要該操作// Runtime.getRuntime().exec(String.format("cmd /c %s", outputFilePath));} catch (IOException e) {e.printStackTrace();}}
}

這里使用的所有 docs 模板文件,我都存放在 resources 的目錄下。

在這里插入圖片描述

插入文本

str_demo.docx 文件,文本使用 {{xxx}} 設置占位符:

{{str1}}	
{{str2}}
{{str3}}
{{str4}}
{{?strArr1}}{{=#this}} {{/strArr1}}

案例代碼:

// 模板文件
String templateFilePath = "/word_template/str_demo.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 直接插入 Stringput("str1", "直接插入 String");// 插入含有樣式的文本put("str2", Texts.of("插入含有樣式的文").color("ff0000").create());// 插入含超鏈接的文本put("str3", Texts.of("插入含有樣式的文").link("http://www.shijialeya.top/").create());// 傳入一個對象put("str4", Arrays.asList("鍵盤敲破", "工資過萬"));// 遍歷文本put("strArr1", Arrays.asList("派大星", "瘸老板", "海綿寶寶", "章魚哥", "蟹老板"));
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:

在這里插入圖片描述

要注意 docx 文件上的 {{xxx}} xxx 的前后不要有空格,如果將外面的文字復制到 word 可能會自動加空格。

插入圖片

img_demo.docx 文件,圖片通過 {{@xxx}} 設置占位符:

{{@img1}}{{@img2}}{{@img3}}{{@img4}}{{?imgArr1}}{{@#this}}  {{/imgArr1}}

案例代碼:

// 模板文件
String templateFilePath = "/word_template/img_demo.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 直接插入本地圖片(默認圖片的寬度與文檔的寬度一致)// put("img1", "C:/Users/17279/Pictures/head.jpg");// 插入本地圖片,并設置圖片大小put("img1", Pictures.ofLocal("C:/Users/17279/Pictures/head.jpg").size(100, 100).create());// 通過流的形式寫入圖片put("img2", Pictures.ofStream(new FileInputStream("C:/Users/17279/Pictures/head.jpg"), PictureType.JPEG).size(150, 150).create());// 寫入網絡圖片put("img3", Pictures.ofUrl("http://file.shijialeya.top/head.jpg", PictureType.JPEG).size(170, 170).create());// 寫入通過 Java 生成的圖片put("img4", Pictures.ofBufferedImage(new BufferedImage(190, 190, BufferedImage.TYPE_BYTE_GRAY), PictureType.PNG).size(190, 190).create());// 遍歷圖片put("imgArr1", new ArrayList<Object>() {{add(Pictures.ofLocal("C:/Users/17279/Pictures/head.jpg").size(100, 100).create());add(Pictures.ofLocal("C:/Users/17279/Pictures/head.jpg").size(100, 100).create());add(Pictures.ofLocal("C:/Users/17279/Pictures/head.jpg").size(100, 100).create());}});
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:

在這里插入圖片描述

插入表格

tab_demo.docx 文件,圖片通過 {{#xxx}} 設置占位符:

{{#tab1}}{{#tab2}}{{#tab3}}合同名稱	{{tab4.contractName}}
合同時間	{{tab4.contractDate}}	合同金額	{{tab4.money}}
合同公司	{{tab4.company}}

在這里插入圖片描述

案例代碼:

// 模板文件
String templateFilePath = "/word_template/tab_demo.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 插入一個基礎表格String[][] tabData1 = {new String[]{"姓名", "性別", "年齡"},new String[]{"派大星", "16", "男"},new String[]{"章魚哥", "35", "男"}};put("tab1", Tables.of(tabData1).create());// 插入一個含有樣式的表格Tables.TableBuilder tabData2 = Tables// 創建一個指定寬度的表格(docx 文檔的 80% 寬度).ofPercentWidth("80%")// 表格設為水平居中.center()// 設置表格邊框.border(BorderStyle.builder()// 邊框樣式.withType(XWPFTable.XWPFBorderType.DOUBLE)// 邊框顏色.withColor("ff0000")// 邊框粗細(邊框為線條類型才會有效).withSize(12).build());tabData2.addRow(Rows.of("姓名", "性別", "年齡")// 設置文字顏色.textColor("FFFFFF")// 設置對應表格的背景顏色.bgColor("4472C4")// 文字居中.center().create());tabData2.addRow(Rows.of("派大星", "16", "男").create());put("tab2", tabData2.create());// 合并單元格String[][] tabData3 = {new String[]{"姓名", "性別", "年齡"},new String[]{"派大星", "16", "男"},new String[]{"章魚哥", "35", "男"},new String[]{"共2人", null, null},};put("tab3", Tables.of(tabData3)// 添加單元格合并規則.mergeRule(MergeCellRule.builder()// [縱坐標, 橫坐標] 索引從零開始,合并 [3, 0] 到 [3, 2] 位置的表格.map(MergeCellRule.Grid.of(3, 0), MergeCellRule.Grid.of(3, 2)).build()).create());// 對應格式一定的表格,直接采用字符串替換即可put("tab4", new HashMap<String, Object>() {{put("contractName", "第一季度財務報告");put("contractDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));put("company", "xxx有限責任公司");put("money", 10089.33);}});
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:在這里插入圖片描述

引入標簽

插入圖片

上面也有插入圖片的方式,但是通過引入標簽的方式插入圖片時,可以先在 word 模板文件中提前編輯好圖片的樣式,通過替換圖片的方式,會保留原本設置好的樣式。

在 docx 模板文件中先插入一張圖片,并且調整好圖片的樣式,之后右鍵圖片選擇【查看可選文字】,在可選文字中通過 {{xxx}} 的方式填寫屬性名稱。

【特別提醒】貌似 WPS 沒有可選文字的功能,不確定是不是 WPS 版本的原因,反正我沒找到可選文字。

因此我特地把 WPS 卸載之后換成了 Office 工具。

在這里插入圖片描述

案例代碼:

// 模板文件
String templateFilePath = "/word_template/quote_demo01.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 直接插入本地圖片,這里會保留模板文件的圖片樣式put("label1", Pictures.ofLocal("C:/Users/17279/Pictures/head.jpg").create());
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:

在這里插入圖片描述

插入單系列圖表

單系列圖表指的是餅圖(3D餅圖)、圓環圖等。

同引入標簽插入圖片一樣,在插入圖表的時候,需要在 docx 模板中創建一個單系列的圖表,設置好樣式,之后右鍵圖表選擇【查看可選文字】,在可選文字中通過 {{xxx}} 的方式填寫屬性名稱。

在這里插入圖片描述

案例代碼:

// 模板文件
String templateFilePath = "/word_template/quote_demo02.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 添加單系列圖表的表格數據put("label2", Charts.ofSingleSeries("商品類型", new String[]{"電器類", "數碼類", "生活用品類", "食品類", "其他"}).series("數量", new Integer[]{30, 8, 25, 11, 3}).create());
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:

在這里插入圖片描述

插入多系列圖表

多系列圖表指的是條形圖(3D條形圖)、柱形圖(3D柱形圖)、面積圖(3D面積圖)、折線圖(3D折線圖)、雷達圖、散點圖等。

模板文件如下:

在這里插入圖片描述

案例代碼:

// 模板文件
String templateFilePath = "/word_template/quote_demo03.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 添加單系列圖表的表格數據put("label3", Charts.ofMultiSeries("銷售額", new String[]{"第一季度", "第二季度", "第三季度", "第四季度"}).addSeries("電器類", new Integer[]{22, 25, 28, 25}).addSeries("數碼類", new Integer[]{5, 10, 8, 4}).addSeries("其他", new Integer[]{30, 42, 22, 33}).create());
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:在這里插入圖片描述

插入組合圖表

組合圖表指的是由多系列圖表(柱形圖、折線圖、面積圖)組合而成的圖表。

模板文件如下:

在這里插入圖片描述

案例代碼:

// 模板文件
String templateFilePath = "/word_template/quote_demo04.docx";
// 輸出文件
String outputFilePath = "D:/output.docx";
// 插入文本數據
Map<String, Object> templateData = new HashMap<String, Object>() {{// 添加單系列圖表的表格數據put("label4", Charts.ofComboSeries("汽車銷售額", new String[]{"第一季度", "第二季度", "第三季度", "第四季度"})// 添加柱狀圖數據.addBarSeries("比亞迪", new Double[]{12.3, 11.5, 9.7, 12.0}).addBarSeries("廣汽", new Double[]{6.2, 5.8, 5.7, 6.6}).addBarSeries("小米", new Double[]{0.0, 0.0, 10.2, 11.2})// 添加折線圖數據.addLineSeries("國內均值", new Double[]{10.0, 12.2, 11.2, 9.8}).addLineSeries("全球均值", new Double[]{8.3, 10.2, 10.0, 8.8}).create());
}};
// 文件生成
PoitlUtils.generateWordFile(templateData, templateFilePath, outputFilePath);

文檔效果:

在這里插入圖片描述

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

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

相關文章

俄羅斯防空系統

俄羅斯的S系列防空系統是一系列先進的地對空導彈系統&#xff0c;旨在防御各類空中威脅&#xff0c;包括飛機、無人機、巡航導彈和彈道導彈。以下是幾種主要的S系列防空系統&#xff1a; 1. **S-300系統**&#xff1a; - **S-300P**&#xff1a;最早期的版本&#xff0c;用…

翻譯造句練習

翻譯練習 翻譯 1&#xff1a;經常做運動會提高人的自信 翻譯 2&#xff1a;教學的質量對學生成績有很大的影響。 翻譯 3&#xff1a;家長和老師應該努力去減少小孩看電視的時間。 翻譯 4&#xff1a;經濟的下滑&#xff08;economic slowdown&#xff09;導致失業率的上升 翻譯…

大模型和數據庫最新結合進展

寫在前面 本文主要內容是上次接受 infoQ 訪談&#xff0c;百度智能云朱潔老師介紹了大模型和 AI 結合相關話題&#xff0c;這次整體再刷新下&#xff0c;給到對這個領域感興趣的同學。 當前&#xff0c;百度智能云云數據庫特惠專場開始&#xff01;熱銷規格新用戶免費使用&am…

Android中ViewModel+LiveData+DataBinding的配合使用(kotlin)

Android 中 ViewModel、LiveData 和 Data Binding 的配合使用&#xff08;Kotlin&#xff09; 摘要 本文將介紹如何在 Android 開發中結合使用 ViewModel、LiveData 和 Data Binding 進行數據綁定和狀態更新。我們將詳細探討這三者之間的關系&#xff0c;并展示如何在 Kotlin…

最逼真的簡易交通燈設計

最逼真的簡易交通燈設計 需要資料的請在文章末尾獲取&#xff08;有問題可以私信我哦~~&#xff09; 01 資料內容 Proteus仿真文件程序源碼實物制作&#xff0c;代碼修改&#xff0c;功能定制&#xff08;需額外收費&#xff0c;價格實惠&#xff0c;歡迎咨詢&#xff09; …

實驗場:在幾分鐘內使用 Elasticsearch 進行 RAG 應用程序實驗

作者&#xff1a;來自 Elastic Joe McElroy, Serena Chou 什么是 Playground&#xff08;實驗場&#xff09;&#xff1f; 我們很高興發布我們的 Playground 體驗 —- 一個低代碼界面&#xff0c;開發人員可以在幾分鐘內使用自己的私人數據探索他們選擇的 LLM。 在對對話式搜…

41割隊伍

上海市計算機學會競賽平臺 | YACSYACS 是由上海市計算機學會于2019年發起的活動,旨在激發青少年對學習人工智能與算法設計的熱情與興趣,提升青少年科學素養,引導青少年投身創新發現和科研實踐活動。https://www.iai.sh.cn/problem/387 題目描述 給定 ??n 個數字 ??1,?…

一周小計(1):實習初體驗

實習的第一周&#xff0c;從最開始的配環境做好準備工作&#xff0c;到拉項目熟悉項目&#xff0c;然后自己去寫需求&#xff0c;每一步都有很大收獲&#xff0c;得到很多人幫助真的好感謝&#xff0c;以下是個人這幾天的記錄與感想。 &#xff08;這個其實是我寫的周報&#x…

Hi3861 OpenHarmony嵌入式應用入門--LiteOS Semaphore做同步使用

信號量作為同步使用 創建一個Semaphore對象&#xff0c;并指定一個初始的計數值&#xff08;通常稱為“許可”或“令牌”的數量&#xff09;。這個計數值表示當前可用的資源數量或可以同時訪問共享資源的線程數。當一個線程需要訪問共享資源時&#xff0c;它會嘗試從Semaphore…

加油站可視化:打造智能化運營與管理新模式

智慧加油站可視化通過圖撲 HT 構建仿真的三維模型&#xff0c;將加油站的布局、設備狀態、人員活動等信息動態呈現。管理者可以通過直觀的可視化界面實時監控和分析運營狀況&#xff0c;快速做出決策&#xff0c;提高管理效率和安全水平&#xff0c;推動加油站向智能化管理轉型…

后端之路第三站(Mybatis)——結合案例講Mybatis怎么操作sql

先講一下準備工作整體流程要做什么 我們要基于一個員工管理系統作為案例&#xff0c;進行員工信息的【增、刪、改、查】 原理就是用Mybatis通過java語言來執行sql語句&#xff0c;來達到【增、刪、改、查】 一、準備工作 1、引入數據庫數據 首先我們把一個員工、部門表的數…

【51單片機入門】速通定時器

文章目錄 前言定時器是什么初始化定時器初始化的大概步驟TMOD寄存器C/T寄存器 觸發定時器中斷是什么中斷函數定時器點亮led 總結 前言 在嵌入式系統的開發中&#xff0c;定時器是一個非常重要的組成部分。它們可以用于產生精確的時間延遲&#xff0c;或者在特定的時間間隔內觸…

對外發布的PDF文檔進行數字證書簽名的重要性?

對外發布的PDF文檔進行數字證書簽名具有以下幾個重要性&#xff1a; 身份驗證&#xff1a;數字簽名可以證明文檔的來源&#xff0c;即確認文檔的簽署者身份。這如同在紙質文檔上手寫簽名或加蓋公章&#xff0c;但更安全可靠&#xff0c;因為數字簽名是基于加密技術&#xff0c;…

Java--常用類APl(復習總結)

前言: Java是一種強大而靈活的編程語言&#xff0c;具有廣泛的應用范圍&#xff0c;從桌面應用程序到企業級應用程序都能夠使用Java進行開發。在Java的編程過程中&#xff0c;使用標準類庫是非常重要的&#xff0c;因為標準類庫提供了豐富的類和API&#xff0c;可以簡化開發過…

【接口自動化測試】第三節.實現項目核心業務接口自動化

文章目錄 前言一、實現登錄接口對象封裝和調用 1.0 登錄接口的接口測試文檔 1.1 接口對象層&#xff08;封裝&#xff09; 1.2 測試腳本層&#xff08;調用&#xff09;二、課程新增接口對象封裝和調用 2.0 課程新增接口的接口測試文檔 2.1 接口對象層…

AVL樹模擬

1.概念 雖然二叉搜索樹可以縮短查找的效率&#xff0c;但如果數據有序或者接近有序時二叉搜索樹樹將退化為單支樹&#xff0c;查找元素相當于在順序表中搜索元素&#xff0c;效率低下。AVL 樹是具有一下性質的二叉搜索樹&#xff1a; 1.它的左右子樹都是AVL樹 2.左右子…

Mac 如何安裝 wget

1.安裝 Homebrew2.安裝 wget3.檢測 wget 是否安裝成功 1.安裝 Homebrew 在安裝 wget 之前需要安裝一個適用于 mac 的包管理器 Homebrew&#xff0c;打開 mac 終端執行如下命令進行安裝&#xff1a; /usr/bin/ruby -e "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/h…

【Git】GitIgnore不生效

這里可能有兩種原因&#xff0c;一個沒有刷新Git緩存&#xff0c;二是Git忽略規則有問題 更新Git緩存 git rm -r --cached . git add . git commit -m "modify git ignore rule"Ignore規則 檢查下忽略文件的目錄表示是否正確 XXX忽略任意目錄下名為XXX的文件 …

新手第一個漏洞復現:MS17-010(永恒之藍)

文章目錄 漏洞原理漏洞影響范圍復現環境復現步驟 漏洞原理 漏洞出現在Windows SMB v1中的內核態函數srv!SrvOs2FeaListToNt在處理FEA&#xff08;File Extended Attributes&#xff09;轉換時。該函數在將FEA list轉換成NTFEA&#xff08;Windows NT FEA&#xff09;list前&am…

【Golang - 90天從新手到大師】Day14 - 方法和接口

一&#xff0e; go方法 go方法&#xff1a;在函數的func和函數名間增加一個特殊的接收器類型&#xff0c;接收器可以是結構體類型或非結構體類型。接收器可以在方法內部訪問。創建一個接收器類型為Type的methodName方法。 func (t Type) methodName(parameter list) {}go引入…