Java工具类 (3)------>WordUtils------>利用Poi根据模板生成新的word文档
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格式,需要替换的文本地方用 ${} 替换