基于Java實現(xiàn)模板填充Word
Java實現(xiàn)按模板填充word
本文講解的需求是:我們需要把數(shù)據(jù)庫中的某些數(shù)據(jù)按照 產(chǎn)品經(jīng)理提供的 word模板,把數(shù)據(jù)表中的一些內(nèi)容根據(jù)模板填充到 word 模板,然后把 word 模板 再以 pdf 的形式 導(dǎo)出,我們 可以根據(jù)自己的需求來進行一個研究,也可以 只以word的形式導(dǎo)出。
下面這段代碼:
模板文件,我們是模板文件放到了 resources包 (資源根) 下的 static 目錄下面
首先定義了輸出臨時word的路徑 (因為我們的目標是最終獲得 pdf 文件,如果你是想要獲得 word 就可以直接是 你的目標存儲位置)
定義了 我們 pdf 的最終 的 下載的路徑
(在項目中一般是前端給我們傳過來的 下載的路徑,我們不需要自己 設(shè)置,我們可以通過 response 進行獲取)
// 清楚模板緩存 response.reset(); //傳給前端 response.setCharacterEncoding("UTF-8"); // 設(shè)置編碼格式 //設(shè)置Header字段 // 文件名 String fileName = "模板.docx"; String encodedFileName = URLEncoder.encode(fileName, "UTF-8"); // 對文件名進行編碼 response.setHeader("Content-disposition", "attachment;filename=" + encodedFileName); // 獲得輸出流 OutputStream out = response.getOutputStream(); template.write(out);
下面就是定義我們想要填充的數(shù)據(jù),注意,我們在做word 模板填充的時候是 使用的 poi 依賴,所以 value 必須是 String 類型的
這些數(shù)據(jù)是我自己 設(shè)置的一些假數(shù)據(jù) ,在真實的需求中,我們就需要從數(shù)據(jù)庫中獲取了
然后調(diào)用了 兩種方法 分別進行不同的操作
// 這個是 模板填充word的方法 fillWordTemplate(templatePath, outputWordPath, map); /** 第一個參數(shù)是 模板文件 第二個參數(shù)是 輸出的 word 的路徑 就是模板填寫完畢之后,下載到哪里 第三個參數(shù)就是對應(yīng)的 數(shù)據(jù)的關(guān)系了 */
Files.deleteIfExists(Paths.get(outputWordPath)); //在目標是 pdf 文件時,幫助我們刪除掉 word 文件
@Test public void testWORDPDF() throws IOException { //得到靜態(tài)包下的模板文件 String templatePath = "/static/測試文檔.docx"; // 輸出臨時Word文件路徑(用于后續(xù)轉(zhuǎn)換為PDF) String outputWordPath = "D:\\Users\\lenovo\\Desktop\\模板.docx"; //給出pdf 下載到的路徑 項目中通過 response.getOutputStream() 獲取 String PDFpath = "D:\\Users\\lenovo\\Desktop\\測試.pdf"; //模擬要填充的數(shù)據(jù) 項目中從數(shù)據(jù)庫獲取,但是要保證,填充的數(shù)據(jù)一定要是 String 類型 Map<String, String> map = new HashMap<>(); map.put("username", "野原新之助"); map.put("year", "5歲"); map.put("text", "優(yōu)點:活潑、好動、樂觀、可愛、標新立異,運動神經(jīng)好(每次跟河村豹跑步都不喘氣,而且可以做很多高難度動作),體貼卻不坦率。\n" + "缺點:挑食,好色、頑皮、早熟、健忘、遲鈍(有時看情況)、愛耍賤。\n" + "喜好:\n" + "喜歡的動畫人物有動感超人、鋼彈勇士、肥嘟嘟左衛(wèi)門(小新的自創(chuàng)角色)、鉛筆小新(播出后深受小新和自己的朋友歡迎,但父母卻很抗議)。\n" + "喜歡的運動有劍道(學(xué)習(xí)劍道目的也只是打贏代代木這個強敵)、足球、躲避球、棒球。(有時將光屁屁舞當(dāng)成運動)、拳擊(在《這就是青春》這一篇章中小新成為國中生時的愛好)、游泳。\n" + "喜歡的動作是光屁屁超人舞(也稱露屁屁外星人)、大象舞、把媽媽的內(nèi)衣內(nèi)褲套在頭上、學(xué)動感超人大笑、發(fā)射動感光波、摸頭害羞的笑。 [1]\n" + "喜歡的食物有巧克力餅干(日本商店有售,而且是小新代言的)、納豆拌飯、咖喱、火鍋、炸薯條、刨冰、冰淇淋、布丁、蛋糕、洋芋片(薯片)、仙貝(等零食)、壽司等。\n" + "喜歡的飲料有100%純果汁、可樂、綠茶(濃一點的) pus light(瓶子上有這個標識)。\n" + "喜歡的歌手是唱《動感超人》主題曲的那位叔叔。\n" + "喜歡的動物有小白(撿來的流浪狗,全名為野原小白)、小雞(被小新取名為:麻雀) 、貓(被小新取名為:問號),大象,倉鼠(正男家倉鼠生小寶寶拜托小新養(yǎng)一只,被小新取名馬來亞,另外一只貓(被小新取名為瑪莉蓮,是松阪老師家的貓)。\n" + "喜歡的電影作品有《動感超人》,《鋼達姆勇士》。\n" + "喜歡的人有大原娜娜子、金有民子、小椿。\n" + "喜歡女生的要胸部大,15歲以上且臉蛋可愛漂亮、身材好。 [1]\n" + "厭惡:\n" + "討厭的食物有青椒、胡蘿卜、不加蔥的納豆和加蔥的味增湯、西蘭花、洋蔥。"); //填充模板 // 將填充后的Word文檔轉(zhuǎn)換為PDF try { this.fillWordTemplate(templatePath, outputWordPath, map); this.wordToPdf(outputWordPath, PDFpath); // //下面可以添加代碼實現(xiàn)下載的邏輯,比如通過響應(yīng)流返回給客戶端 System.out.println("PDF文件已生成,路徑為:" + PDFpath); } catch (Exception e) { e.printStackTrace(); } Files.deleteIfExists(Paths.get(outputWordPath)); //刪除臨時文件 }
下面這個方法是 word 模板填充后下載的方法
首先 我們制定了一個 模板 并且設(shè)置了標記 ${ } ;注意這里和你的 word 模板是相照應(yīng)的,你想要把數(shù)據(jù)填充后到哪里你就需要怎樣進行照應(yīng)
//例如 word 用戶:${username}
因為我們的模板文件是在 resources 包下面 (這里符合真實的項目場景)所以我們要先獲取到
InputStream is = ResourceLoader.class.getResourceAsStream(templatePath); //這里通過 ResourceLoader 這個類并且通過反射得到 流之后,通過我們 模板文件在resources包的源根的路徑得到文件的輸入流
我們創(chuàng)立的模板對象 template
然后我們就通過 XWPFTemplate.compile(模板文件輸入流,模板標記填充數(shù)據(jù)) 方法進行模板填充
這里我用了一個 緩沖文件 tempFile 來幫我過度一下,因為我后面要進行一些樣式的操作(玩一些花活)
所以就把模板填充好的文件給寫入到了 tempFile // template.writeToFile(String.valueOf(tempFile));// 寫入文件
下面的操作就是一些花活,可以不看,一般用不到
這里首先獲得的是 緩沖文件的輸入流
然后創(chuàng)建的 緩沖文件的 word 文檔對象
然后就是遍歷 其中的段落 ,在遍歷得到文本內(nèi)容
如果內(nèi)容不為空的話就進行一些樣式改造
顏色 藍色 字號 12 字體 楷體 間距 10
并把段落 設(shè)置為靠左對齊
最后就是刪除緩沖文件
把 word 文檔對象下載到 定義的路徑中去
public void fillWordTemplate(String templatePath, String outputWordPath, Map dataMap) throws Exception { ConfigureBuilder builder = Configure.builder(); builder.buildGramer("${", "}"); // 設(shè)置 模板標記 XWPFTemplate template; // 創(chuàng)建模板對象 //得到模板文件 InputStream is = ResourceLoader.class.getResourceAsStream(templatePath); System.out.println("is = " + is); // 自定義段落樣式(設(shè)置字體為宋體,字號為12,顏色為紅色) template = XWPFTemplate.compile(is, builder.build()).render(dataMap); File tempFile = File.createTempFile("temp", ".docx"); template.writeToFile(String.valueOf(tempFile));// 寫入文件 FileInputStream fis = new FileInputStream(tempFile); XWPFDocument xwpfDocument = new XWPFDocument(fis); for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) { for (XWPFRun run : paragraph.getRuns()) { if (run.getText(0) != null) { run.setColor("0000FF"); run.setFontSize(12); run.setFontFamily("楷體"); run.setTextPosition(10);// 設(shè)置文本間距 //設(shè)置內(nèi)容為 水平居中 } } //設(shè)置內(nèi)容為 靠左對齊 paragraph.setAlignment(ParagraphAlignment.LEFT); } tempFile.delete(); xwpfDocument.write(Files.newOutputStream(Paths.get(outputWordPath))); xwpfDocument.close(); template.close(); is.close(); }
下面的方法是 word 轉(zhuǎn)換成為 pdf 的方法
使用了 aspose-words 庫(通過 LocalConverter 相關(guān)類來操作)將 Word 文件轉(zhuǎn)換為 PDF 文件
首先 傳入的兩個參數(shù) 第一個是 word 模板填充好的文件的下載路徑 第二個參數(shù)是 pdf 要下載到的目標路徑
然后我們就獲得 文件輸入流 和 pdf 文件的輸出流
然后我們通過 構(gòu)造器模式 構(gòu)造了一個 aspose-words 庫中的一個 轉(zhuǎn)換器對象
//實際的執(zhí)行操作 converter.convert(doc).as(DocumentType.DOC).to(outputStream).as(DocumentType.PDF).execute(); //將 doc 文件 doc類型的 轉(zhuǎn)換成為 pdf 類型的 轉(zhuǎn)換到 輸出流中 //方法的返回結(jié)果就是 轉(zhuǎn)換是否成功
成功 我們把 轉(zhuǎn)換器關(guān)閉
關(guān)閉doc 輸入流、pdf 輸出流
public void wordToPdf(String inputWordPath, String outputPdfPath) { try { InputStream doc = Files.newInputStream(Paths.get(inputWordPath)); OutputStream outputStream = Files.newOutputStream(Paths.get(outputPdfPath)); IConverter converter = LocalConverter.builder().build(); boolean flag = converter.convert(doc).as(DocumentType.DOC).to(outputStream).as(DocumentType.PDF).execute(); if (flag) { converter.shutDown(); } doc.close(); outputStream.close(); System.out.println("PDF文件已生成,路徑為:" + outputPdfPath); } catch (Exception e) { e.printStackTrace(); } }
需要的Maven依賴
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> <scope>test</scope> <exclusions> <exclusion> <artifactId>poi</artifactId> <groupId>org.apache.poi</groupId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.2</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.documents4j</groupId> <artifactId>documents4j-local</artifactId> <version>1.1.6</version> </dependency> <dependency> <groupId>com.documents4j</groupId> <artifactId>documents4j-transformer-msoffice-word</artifactId> <version>1.1.6</version> </dependency>
到此這篇關(guān)于基于Java實現(xiàn)模板填充Word的文章就介紹到這了,更多相關(guān)Java模板填充Word內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java算法之Math.random()隨機概率玩法實例演示
最近打算整理排序算法,發(fā)現(xiàn)很有必要準備一下生成隨機數(shù)的工具類,下面這篇文章主要給大家介紹了關(guān)于java算法之Math.random()隨機概率玩法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-05-05springboot 自定義異常并捕獲異常返給前端的實現(xiàn)代碼
在開發(fā)中,如果用try catch的方式,每個方法都需要單獨實現(xiàn),為了方便分類異常,返回給前端,采用了@ControllerAdvice注解和繼承了RuntimeException的方式來實現(xiàn),具體實現(xiàn)內(nèi)容跟隨小編一起看看吧2021-11-11Java設(shè)計模式模板方法(Template)原理解析
這篇文章主要介紹了Java設(shè)計模式模板方法(Template)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11