1、導入maven依賴
<!-- 引入Poi依賴 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.0.1</version> </dependency>
2、WordUtils
public class WordUtil { /** * 根據模板生成新word文檔 * 判斷表格是需要替換還是需要插入,判斷邏輯有$為替換,表格無$為插入 * @param inputUrl 模板存放地址 * @param outputUrl 新文檔存放地址 * @param textMap 需要替換的信息集合 * @param tableList 需要插入的表格信息集合 * @return 成功返回true,失敗返回false */ public static boolean changWord(String inputUrl, String outputUrl, Map<String, String> textMap, List<String[]> tableList) { //模板轉換默認成功 boolean changeFlag = true; try { //獲取docx解析對象 XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl)); //解析替換文本段落對象 changeText(document, textMap); //解析替換表格對象 changeTable(document, textMap, tableList); //生成新的word File file = new File(outputUrl); FileOutputStream stream = new FileOutputStream(file); document.write(stream); stream.close(); } catch (IOException e) { e.printStackTrace(); changeFlag = false; } return changeFlag; } /** * 替換段落文本 * @param document docx解析對象 * @param textMap 需要替換的信息集合 */ private static void changeText(XWPFDocument document, Map<String, String> textMap){ //獲取段落集合 List<XWPFParagraph> paragraphs = document.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { //判斷此段落時候需要進行替換 String text = paragraph.getText(); if(checkText(text)){ List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { //替換模板原來位置 run.setText(changeValue(run.toString(), textMap),0); } } } } /** * 替換表格對象方法 * @param document docx解析對象 * @param textMap 需要替換的信息集合 * @param tableList 需要插入的表格信息集合 */ private static void changeTable(XWPFDocument document, Map<String, String> textMap, List<String[]> tableList){ //獲取表格對象集合 List<XWPFTable> tables = document.getTables(); for (XWPFTable table : tables) { //只處理行數大於等於2的表格,且不循環表頭 if (table.getRows().size() > 1) { //判斷表格是需要替換還是需要插入,判斷邏輯有$為替換,表格無$為插入 if (checkText(table.getText())) { List<XWPFTableRow> rows = table.getRows(); //遍歷表格,並替換模板 eachTable(rows, textMap); } else { insertTable(table, tableList); } } } } /** * 遍歷表格 * @param rows 表格行對象 * @param textMap 需要替換的信息集合 */ private static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){ for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { //判斷單元格是否需要替換 if(checkText(cell.getText())){ List<XWPFParagraph> paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { run.setText(changeValue(run.toString(), textMap),0); } } } } } } /** * 為表格插入數據,行數不夠添加新行 * @param table 需要插入數據的表格 * @param tableList 插入數據集合 */ private static void insertTable(XWPFTable table, List<String[]> tableList){ //創建行,根據需要插入的數據添加新行,不處理表頭 for(int i = 1; i < tableList.size(); i++){ XWPFTableRow row =table.createRow(); } //遍歷表格插入數據 List<XWPFTableRow> rows = table.getRows(); for(int i = 1; i < rows.size(); i++){ XWPFTableRow newRow = table.getRow(i); List<XWPFTableCell> cells = newRow.getTableCells(); for(int j = 0; j < cells.size(); j++){ XWPFTableCell cell = cells.get(j); cell.setText(tableList.get(i-1)[j]); } } } /** * 判斷文本中時候包含$ * @param text 文本 * @return 包含返回true,不包含返回false */ private static boolean checkText(String text){ boolean check = false; if(text.indexOf("$")!= -1){ check = true; } return check; } /** * 匹配傳入信息集合與模板 * @param value 模板需要替換的區域 * @param textMap 傳入信息集合 * @return 模板需要替換區域信息集合對應值 */ private static String changeValue(String value, Map<String, String> textMap){ Set<Map.Entry<String, String>> textSets = textMap.entrySet(); for (Map.Entry<String, String> textSet : textSets) { //匹配模板與替換值 格式${key} String key = "${"+textSet.getKey()+"}"; if(value.indexOf(key)!= -1){ value = textSet.getValue(); } } //模板未匹配到區域替換為空 if(checkText(value)){ value = ""; } return value; } }
3、測試
@Test void testWord(){ //模板文件地址 String inputUrl = "E:\\liangd\\other\\dailyTemplate.docx"; //新生產的模板文件 String outputUrl = "E:\\liangd\\other\\daily\\demo.docx"; Map<String, String> testMap = new HashMap<String, String>(); testMap.put("username", "小明"); testMap.put("dailyTime", "2020-12-31"); testMap.put("title", "測試"); List<String[]> testList = new ArrayList<String[]>(); testList.add(new String[]{"1","1AA","1BB","1CC"}); testList.add(new String[]{"2","2AA","2BB","2CC"}); testList.add(new String[]{"3","3AA","3BB","3CC"}); testList.add(new String[]{"4","4AA","4BB","4CC"}); boolean b = WordUtil.changWord(inputUrl, outputUrl, testMap, testList); if (b){ System.out.println("創建成功"); }else { System.out.println("創建失敗"); } }
注:創建模板文件需要另存為docx格式,需要替換的文本地方用 ${} 替換