解决poi操作docx替换${}占位符不成功的过程

来源:互联网 发布:python cst时间转换 编辑:程序博客网 时间:2024/06/04 23:27

先贴个代码

 public static boolean replaceAndGenerateWord(String srcPath, String destPath, Map<String, String> map) throws IOException {        String[] sp = srcPath.split("\\.");        String[] dp = destPath.split("\\.");        // 判断文件有无扩展名        if (sp.length <= 0 || dp.length <= 0) {            return false;        }        if (                !sp[sp.length - 1].equalsIgnoreCase("docx")                        &&                        !(                                sp[sp.length - 1].equalsIgnoreCase("doc")                                        && dp[dp.length - 1].equalsIgnoreCase("doc")                        )                ) {            return false;        }        // 比较文件扩展名        if (sp[sp.length - 1].equalsIgnoreCase("docx")) {            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(srcPath));            // 替换段落中的指定文字            Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();            while (itPara.hasNext()) {                XWPFParagraph paragraph = itPara.next();                List<XWPFRun> runs = paragraph.getRuns();                for (XWPFRun run : runs) {                    String oneparaString = run.getText(run.getTextPosition());                    if (StringUtil.isBlank(oneparaString)){                        continue;                    }                    for (Map.Entry<String, String> entry :                            map.entrySet()) {                        oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());                    }                    run.setText(oneparaString, 0);                }            }            // 替换表格中的指定文字            Iterator<XWPFTable> itTable = document.getTablesIterator();            while (itTable.hasNext()) {                XWPFTable table = itTable.next();                int rcount = table.getNumberOfRows();                for (int i = 0; i < rcount; i++) {                    XWPFTableRow row = table.getRow(i);                    List<XWPFTableCell> cells = row.getTableCells();                    for (XWPFTableCell cell : cells) {                        String cellTextString = cell.getText();                        for (Map.Entry<String, String> e : map.entrySet()) {                            cellTextString = cellTextString.replace(e.getKey(), e.getValue());                        }                        cell.removeParagraph(0);                        cell.setText(cellTextString);                    }                }            }            FileOutputStream outStream = new FileOutputStream(destPath);            document.write(outStream);            outStream.close();            return true;        }        // doc只能生成doc,如果生成docx会出错        if ((sp[sp.length - 1].equalsIgnoreCase("doc"))                && (dp[dp.length - 1].equalsIgnoreCase("doc"))) {            HWPFDocument document = new HWPFDocument(new FileInputStream(srcPath));            Range range = document.getRange();            for (Map.Entry<String, String> entry : map.entrySet()) {                range.replaceText(entry.getKey(), entry.getValue());            }            FileOutputStream outStream = new FileOutputStream(destPath);            document.write(outStream);            outStream.close();            return true;        }        return false;    }

1.在段落替换部分,最小单位是XWPFRun,XWPFRun是一个XML节点,包含了各种样式,属性和文字

2.从XWPFRun中取出文字进行替换,失败的原因就是:${company}被分割在了数个XWPFRun里面,替换失败,看图:




解决办法:修改节点

1.word打开原docx文件,取消各种拼写检查,另存为 xml文件

2.文本编辑器打开xml,找到要替换的属性占位符,处理成如下样子:


3.保存xml,用word打开xml,另存为,docx

4.愉快地跑代码吧!