Java實(shí)現(xiàn)將數(shù)據(jù)導(dǎo)出為Word文檔的方法步驟
我們?cè)陂_(kāi)發(fā)一些系統(tǒng)的時(shí)候,例如OA系統(tǒng),經(jīng)常能遇到將審批單數(shù)據(jù)導(dǎo)出為word和excel文檔的需求,導(dǎo)出為excel是比較簡(jiǎn)單的,因?yàn)閑xcel有單元格來(lái)供我們定位數(shù)據(jù)位置,但是word文檔的格式不像表格那樣可以輕松的定位,要想將數(shù)據(jù)導(dǎo)出為一些帶有圖片和表格的這種結(jié)構(gòu)復(fù)雜的word文檔該怎樣實(shí)現(xiàn)呢。
poi-tl 1是一款可以幫助我們實(shí)現(xiàn)這種功能的Java開(kāi)源項(xiàng)目,它把POI和Freemarker相結(jié)合,可以基于我們繪制好的word文檔模板來(lái)填充數(shù)據(jù)進(jìn)去,然后生成新的word文檔。
例如,我們要生成一個(gè)差旅行程單,首先要繪制這樣的一個(gè)word文檔模板,用{{name}}
代表姓名進(jìn)行占位,姓名就是普通文字類型,以此類推。tripList
作為渲染行程表格的數(shù)據(jù)源的名字,是ArrayList集合類型,放在表格的表頭,用[from]
表示tripList
集合中每個(gè)元素的from
屬性的值,渲染到當(dāng)前行的某一列上,以此類推。最后的三個(gè)簽署對(duì)應(yīng)的是領(lǐng)導(dǎo)的簽名筆跡圖片,圖片類型要用變量名前多一個(gè)@
的形式{{@****Pin}}
來(lái)表示
如果表格中某一列是圖片,則表示為
[@變量]
模板繪制好以后,開(kāi)始使用poi-tl工具生成word文檔,首先新建maven項(xiàng)目,引入poi-tl的依賴和需要的其他依賴,然后將這個(gè)繪制好的word模板文件放在工程的根目錄下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>poi-tl</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> </dependencies> </project>
然后,新建一個(gè)Entity類: org.example.TravelApplyExportVO
package org.example; import com.deepoove.poi.data.PictureRenderData; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor public class TravelApplyExportVO { private String no; private String name; private String dept; private String employeeNo; private String start; private String end; private String days; private String address; private String reason; /** * com.deepoove.poi.data.PictureRenderData 代表圖片 */ private PictureRenderData applyPin; private PictureRenderData bossPin; private PictureRenderData leaderPin; private String date; /** * 用于渲染表格的集合 */ private List<Route> tripList = new ArrayList<>(); @Data @AllArgsConstructor @NoArgsConstructor public static class Route { private String from; private String to; private String flight; private String depTime; private String arrTime; private String cabin; } }
新建測(cè)試類: org.example.Main,用poi-tl組件基于剛剛繪制的word模板生成一個(gè)差旅行程單
package org.example; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.Pictures; import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; import lombok.SneakyThrows; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; public class Main { @SneakyThrows public static void main(String[] args) { TravelApplyExportVO vo = new TravelApplyExportVO(); vo.setNo("202500001"); vo.setName("lzj"); vo.setDept("技術(shù)部"); vo.setEmployeeNo("00000001"); vo.setStart("2025-01-01"); vo.setEnd("2025-02-01"); vo.setDays("30"); vo.setAddress("中國(guó)香港"); vo.setReason("系統(tǒng)維護(hù)"); // 在項(xiàng)目根路徑讀取筆跡圖片,并設(shè)置大小 PictureRenderData data1 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img2.png"))) .size(120, 60) .create(); PictureRenderData data2 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png"))) .size(120, 60) .create(); PictureRenderData data3 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png"))) .size(120, 60) .create(); vo.setApplyPin(data1 ); vo.setBossPin( data2); vo.setLeaderPin( data3); vo.setDate("2025-01-10"); // 行程List,最終渲染到文檔的表格中 vo.setTripList(new ArrayList<TravelApplyExportVO.Route>() { { add(new TravelApplyExportVO.Route("BJX","ZQZ","ZH5643","2025-01-01 15:00","2025-01-01 16:00","E")); add(new TravelApplyExportVO.Route("ZQZ","CDE","JUH6532","2026-01-01 15:00","2025-12-01 16:00","A")); add(new TravelApplyExportVO.Route("BJX","ZQZ","KJU0954","2027-01-01 15:00","2025-05-01 16:00","Q")); } }); LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); // !!將tripList通過(guò)表格來(lái)渲染 Configure config = Configure.builder() .bind("tripList", policy) .build(); XWPFTemplate template = XWPFTemplate .compile("模板.docx", config) .render(vo); template.writeAndClose(Files.newOutputStream(Paths.get("output.docx"))); } }
然后領(lǐng)導(dǎo)簽名筆記圖片素材img.png
,img2.png
也需要放進(jìn)工程根目錄下
都完成后,執(zhí)行main()
方法測(cè)試,程序運(yùn)行結(jié)束后,將在根路徑生成文件output.docx,打開(kāi)就是我們想要的效果了。
到此這篇關(guān)于Java實(shí)現(xiàn)將數(shù)據(jù)導(dǎo)出為Word文檔的方法步驟的文章就介紹到這了,更多相關(guān)Java數(shù)據(jù)導(dǎo)出為Word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring框架JavaMailSender發(fā)送郵件工具類詳解
這篇文章主要為大家詳細(xì)介紹了Spring框架JavaMailSender發(fā)送郵件工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04SpringBoot部署在tomcat容器中運(yùn)行的部署方法
這篇文章主要介紹了SpringBoot部署在tomcat容器中運(yùn)行的部署方法,需要的朋友可以參考下2018-10-10ElasticSearch學(xué)習(xí)之Es集群Api操作示例
這篇文章主要為大家介紹了ElasticSearch學(xué)習(xí)之Es集群Api操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01java?WebSocket?服務(wù)端實(shí)現(xiàn)代碼
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動(dòng)發(fā)送信息給客戶端,這篇文章主要介紹了java?WebSocket?服務(wù)端代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02基于 SASL/SCRAM 讓 Kafka 實(shí)現(xiàn)動(dòng)態(tài)授權(quán)認(rèn)證的方法
在大數(shù)據(jù)處理和分析中?Apache Kafka?已經(jīng)成為了一個(gè)核心組件,本文將從零開(kāi)始部署?ZooKeeper?和?Kafka?并通過(guò)配置?SASL/SCRAM?和?ACL(訪問(wèn)控制列表)來(lái)增強(qiáng)?Kafka?的安全性,需要的朋友可以參考下2024-07-07SpringBoot整合Spring?Security過(guò)濾器鏈加載執(zhí)行流程源碼分析(最新推薦)
Spring?Boot?對(duì)于?Spring?Security?提供了自動(dòng)化配置方案,可以使用更少的配置來(lái)使用?Spring?Security,這篇文章主要介紹了SpringBoot整合Spring?Security過(guò)濾器鏈加載執(zhí)行流程源碼分析,需要的朋友可以參考下2023-02-02MyBatis中的collection兩種使用方法及效率比較
collection主要是應(yīng)對(duì)表關(guān)系是一對(duì)多的情況,本文主要介紹了MyBatis中的collection兩種使用方法及效率比較,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06java執(zhí)行SQL語(yǔ)句實(shí)現(xiàn)查詢的通用方法詳解
這篇文章主要介紹了java執(zhí)行SQL語(yǔ)句實(shí)現(xiàn)查詢的通用方法詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12