天天看點

Apache-POI解析Word模闆工具類

今天給大家帶來一個Apache-POI的Word解析工具。

public class WordTemplateParse {
    public static Boolean generate(Map<String, String> data, InputStream tempFileStream, OutputStream targetFileStream) {
        try {
            // 加載磁盤的 temp.docx 檔案
            XWPFDocument document = new XWPFDocument(tempFileStream);

            // 解析文檔中的【段落】的插值 ${..}
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                String text = paragraph.getText();
                // 如果該單元格為空就周遊下一個
                if (text == null || "".equals(text)) {
                    continue;
                }

                // 得到解析 ${...} 後的内容
                String newText = replaceByMap(text, null, data);
                // 判斷值是否改變,如果沒有改變就不做處理
                if (!text.equals(newText)) {
                    int runSize = paragraph.getRuns().size();
                    // 清空該段落所有值
                    for (int i = 0; i < runSize; i++) {
                        paragraph.removeRun(i);
                    }

                    XWPFRun run = paragraph.createRun();
                    run.setText(newText);
                }

            }

            // 解析文檔中【表格】的插值 ${..}
            // 擷取文檔中的表格
            List<XWPFTable> tables = document.getTables();
            for (XWPFTable table : tables) {
                // 得到所有行的集合并周遊
                List<XWPFTableRow> rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    // 得到所有列的集合并周遊
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 擷取整個單元格的值
                        String text = cell.getText();
                        // 如果該單元格為空就周遊下一個
                        if (text == null || "".equals(text)) {
                            continue;
                        }

                        // 得到解析 ${...} 後的内容
                        String newText = replaceByMap(text, null, data);
                        // 判斷值是否改變,如果沒有改變就不做處理
                        if (!text.equals(newText)) {
                            // 清空單元格内容
                            int paragraphsNums = cell.getParagraphs().size();
                            for (int i = 0; i < paragraphsNums; i++) {
                                cell.removeParagraph(i);
                            }
                            cell.setText(newText);
                        }
                    }
                }
            }

            // 将文檔寫入目标檔案中
            document.write(targetFileStream);
            // 關閉流
            tempFileStream.close();
            targetFileStream.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    // 如果根據正規表達式規則比對成功則替換,否則傳回原值
    private static String replaceByMap(String content, String regex, Map<String, String> map) {
        // 比對插值 ${...}
        if (regex == null) {
            regex = "\\$\\{[\\w\\W]+\\}";
        }

        // 初始化正則
        Pattern p = Pattern.compile(regex);
        Matcher matcher = p.matcher(content);

        // 找到比對的内容的 key
        if (matcher.find()) {
            // 提前key值
            String matchContent = matcher.group(0);
            int start = matchContent.indexOf("{");
            int end = matchContent.indexOf("}");

            // 擷取key
            String key = matchContent.substring(start + 1, end);

            // 從map中取出key的值
            String value = map.get(key);
            if (value == null) {
                return content;
            }

            // 得到替換後的值
            String newContent = matcher.replaceAll(value);
            return newContent;
        }

        // 沒有比對到,傳回原值
        return content;
    }

}
           

編寫一個測試類:

@Test
    public void test01() throws FileNotFoundException {
        // 資料
        TreeMap<String, String> data = new TreeMap<String, String>();
        data.put("id", "0001");
        data.put("number", "2");
        data.put("date", "2020-10-21");
        data.put("payee", "張三");
        data.put("user_of_payment", "裝置維修");
        data.put("capitalization_amount", "壹佰元整");
        data.put("lowercase_amount", "100");
        data.put("title", "這是憑據的标題==測試");
        data.put("footer", "這是底部的一段文本==測試");

        // 加載模型【模型】
        FileInputStream fis = new FileInputStream("src/main/resources/temp.docx");

        // 輸出位置【輸出】
        FileOutputStream fos = new FileOutputStream("src/main/resources/new_temp.docx");

        Boolean generate = WordTemplateParse.generate(data, fis, fos);
        System.out.println(generate);
    }
           
  • 這是一個Word的模闆:
    Apache-POI解析Word模闆工具類
  • 這是工具解析${…}後的樣子:
    Apache-POI解析Word模闆工具類

源代碼分享

連結:https://pan.baidu.com/s/1U1E9frZeIb9dOVCM1XWL2Q

提取碼:nlqd