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); }
当你看清人们的真相,于是你知道了,你可以忍受孤独