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

代码:

public static OutputStream replaceBySteam(InputStream srcStream, String destPath, Map<String, String> map,String name,String id,HttpServletResponse response) throws Exception {
            XWPFDocument document = new XWPFDocument(srcStream);
        return replace(document, destPath, map, name, id, response);

    }
    private static OutputStream replace(XWPFDocument document, String destPath, Map<String, String> map, String name, String id, HttpServletResponse response) {
        OutputStream outStream = null;
        try {

            /**
             * 替换段落中的指定文字
             */
            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 (StringUtils.isBlank(oneparaString)){
                        continue;
                    }
                    for (Map.Entry<String, String> entry :
                            map.entrySet()) {
                        if(entry.getValue()!=null){
                            oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
                        }
                    }
                    run.setText(oneparaString, 0);
                }

            }


//            while (itPara.hasNext()) {
//                XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
//                Set<String> set = map.keySet();
//                Iterator<String> iterator = set.iterator();
//                while (iterator.hasNext()) {
//                    String key = iterator.next();
//                    List<XWPFRun> run = paragraph.getRuns();
//                    for (int i = 0; i < run.size(); i++) {
//                        if (run.get(i).getText(run.get(i).getTextPosition()) != null &&
//                                run.get(i).getText(run.get(i).getTextPosition()).equals(key)) {
//                            /**
//                             * 参数0表示生成的文字是要从哪一个地方开始放置,设置文字从位置0开始
//                             * 就可以把原来的文字全部替换掉了
//                             */
//                            run.get(i).setText(map.get(key), 0);
//                        }
//                    }
//                }
//            }

            /**
             * 替换表格中的指定文字
             */
            Iterator<XWPFTable> itTable = document.getTablesIterator();
            while (itTable.hasNext()) {
                XWPFTable table = (XWPFTable) itTable.next();
                int count = table.getNumberOfRows();
                for (int i = 0; i < count; i++) {
                    XWPFTableRow row = table.getRow(i);
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        for (Map.Entry<String, String> e : map.entrySet()) {
                            if (cell.getText().equals(e.getKey())) {
                                cell.removeParagraph(0);
                                cell.setText(e.getValue());
                            }
                        }
                    }
                }
            }
//            outStream = response.getOutputStream();
//            FileOutputStream outStream = null;
            outStream = new FileOutputStream(destPath+name+".docx");

            document.write(outStream);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return outStream;
    }

出错原因:

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

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

解决方法

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

2.文本编辑器打开xml,找到要替换的属性占位符,手动处理.

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

如果还不行,可以在换一种段落的替换方式.

第一种:

while (itPara.hasNext()) { // XWPFParagraph paragraph = (XWPFParagraph) itPara.next(); // Set<String> set = map.keySet(); // Iterator<String> iterator = set.iterator(); // while (iterator.hasNext()) { // String key = iterator.next(); // List<XWPFRun> run = paragraph.getRuns(); // for (int i = 0; i < run.size(); i++) { // if (run.get(i).getText(run.get(i).getTextPosition()) != null && // run.get(i).getText(run.get(i).getTextPosition()).equals(key)) { // /** // * 参数0表示生成的文字是要从哪一个地方开始放置,设置文字从位置0开始 // * 就可以把原来的文字全部替换掉了 // */ // run.get(i).setText(map.get(key), 0); // } // } // } // }

第二种:

while (itPara.hasNext()) { XWPFParagraph paragraph = itPara.next(); List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { String oneparaString = run.getText(run.getTextPosition()); if (StringUtils.isBlank(oneparaString)){ continue; } for (Map.Entry<String, String> entry : map.entrySet()) { if(entry.getValue()!=null){ oneparaString = oneparaString.replace(entry.getKey(), entry.getValue()); } } run.setText(oneparaString, 0); } }

猜你喜欢

转载自blog.csdn.net/it_zhang_PG/article/details/82256478