POI 替换 word 关键字并保留样式

  针对 docx ,处理正文、表格、标头中的坐标替换。

public static void copyAndReplace(String oldPath, String newPath, Map<String, String> dict) throws Exception {
        FileOutputStream outStream = null;
        try {
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(oldPath));
            List<XWPFParagraph> list = document.getParagraphs();
            //基本内容替换
            replaceInAllParagraphs(list, dict);
            //表格内容替换添加
            replaceInTables(document.getTables(), dict);
            //页眉内容替换添加
            List<XWPFHeader> headerList = document.getHeaderList();
            for (XWPFHeader xwpfHeader : headerList) {
                List<XWPFParagraph> listParagraph = xwpfHeader.getListParagraph();
                replaceInAllParagraphs(listParagraph, dict);
            }
            outStream = new FileOutputStream(newPath);
            document.write(outStream);
            System.out.println(newPath + " 文档生成完成");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (outStream != null) {
                    outStream.flush();
                    outStream.close();
                }
            } catch (IOException ie) {
                ie.printStackTrace();
            }
        }
    }

    //复制样式
    private static void setStyle(XWPFRun oldXWPFRun, XWPFRun newXWPFRun) {
        newXWPFRun.setFontSize(oldXWPFRun.getFontSize());
        newXWPFRun.setFontFamily(oldXWPFRun.getFontFamily());
        newXWPFRun.setBold(oldXWPFRun.isBold());
        newXWPFRun.setColor(oldXWPFRun.getColor());
        newXWPFRun.setUnderline(oldXWPFRun.getUnderline());
    }

    public static void replaceInAllParagraphs(List<XWPFParagraph> xwpfParagraphList, Map<String, String> params) {
        for (XWPFParagraph paragraph : xwpfParagraphList) {
            if (paragraph.getText() == null || paragraph.getText().length() == 0) continue;
            for (String key : params.keySet()) {
                // 对每一段进行多次处理,处理一段中多次出现关键字的情况
                while (paragraph.getText().contains(key)) {
                    replaceInParagraph(paragraph, key, params.get(key));
                }
            }
        }
    }

    /**
     * 替换段落中的字符串
     *
     * @param xwpfParagraph
     * @param oldString
     * @param newString
     */
    public static void replaceInParagraph(XWPFParagraph xwpfParagraph, String oldString, String newString) {
        Map<String, String> pos_map = findSubRunPosInParagraph(xwpfParagraph, oldString);
        int startPoint = Integer.valueOf(pos_map.get("start_pos"));
        int endPoint = Integer.valueOf(pos_map.get("end_pos"));
        if (pos_map != null) {
            List<XWPFRun> runs = xwpfParagraph.getRuns();
            XWPFRun modelRun = runs.get(endPoint);
            XWPFRun xwpfRun = xwpfParagraph.insertNewRun(endPoint + 1);
            String text = pos_map.get("pre_text");
            while (text.contains(oldString)) text = text.replace(oldString, newString);
            xwpfRun.setText(text);
            if (modelRun.getFontSize() != -1)
                xwpfRun.setFontSize(modelRun.getFontSize());//默认值是五号字体,但五号字体getFontSize()时,返回-1
            xwpfRun.setFontFamily(modelRun.getFontFamily());
            for (int i = endPoint; i >= startPoint; i--) {
                xwpfParagraph.removeRun(i);
            }
        }
    }


    /**
     * 找到段落中子串的起始XWPFRun下标和终止XWPFRun的下标
     *
     * @param xwpfParagraph
     * @param substring
     * @return
     */
    public static Map<String, String> findSubRunPosInParagraph(XWPFParagraph xwpfParagraph, String substring) {
        List<XWPFRun> runs = xwpfParagraph.getRuns();
        int start_pos = 0;
        int end_pos = 0;
        String subtemp = "";
        for (int i = 0; i < runs.size(); i++) {
            subtemp = "";
            start_pos = i;
            for (int j = i; j < runs.size(); j++) {
                if (runs.get(j).getText(runs.get(j).getTextPosition()) == null) continue;
                subtemp += runs.get(j).getText(runs.get(j).getTextPosition());
                if (subtemp.contains(substring)) {
                    end_pos = j;
                    Map<String, String> map = new HashMap<>();
                    map.put("start_pos", String.valueOf(start_pos));
                    map.put("end_pos", String.valueOf(end_pos));
                    String preText = "";
                    for (int k = start_pos; k <= end_pos; k++) preText += runs.get(k).toString();
                    map.put("pre_text", preText);
                    return map;
                }
            }
        }
        return null;
    }


    /**
     * 替换所有的表格
     *
     * @param xwpfTableList
     * @param params
     */
    public static void replaceInTables(List<XWPFTable> xwpfTableList, Map<String, String> params) {
        for (XWPFTable table : xwpfTableList) {
            replaceInTable(table, params);

        }
    }

    /**
     * 替换一个表格中的所有行
     *
     * @param xwpfTable
     * @param params
     */
    public static void replaceInTable(XWPFTable xwpfTable, Map<String, String> params) {
        List<XWPFTableRow> rows = xwpfTable.getRows();
        replaceInRows(rows, params);
    }


    /**
     * 替换表格中的一行
     *
     * @param rows
     * @param params
     */
    public static void replaceInRows(List<XWPFTableRow> rows, Map<String, String> params) {
        for (int i = 0; i < rows.size(); i++) {
            XWPFTableRow row = rows.get(i);
            replaceInCells(row.getTableCells(), params);
        }
    }

    /**
     * 替换一行中所有的单元格
     *
     * @param xwpfTableCellList
     * @param params
     */
    public static void replaceInCells(List<XWPFTableCell> xwpfTableCellList, Map<String, String> params) {
        for (XWPFTableCell cell : xwpfTableCellList) {
            replaceInCell(cell, params);
        }
    }

    /**
     * 替换表格中每一行中的每一个单元格中的所有段落
     *
     * @param cell
     * @param params
     */
    public static void replaceInCell(XWPFTableCell cell, Map<String, String> params) {
        List<XWPFParagraph> cellParagraphs = cell.getParagraphs();
        replaceInAllParagraphs(cellParagraphs, params);
    }

 

posted @ 2021-10-30 15:08  牛有肉  阅读(1688)  评论(0编辑  收藏  举报