Java POI 操作word文档内容、表格


使用场景:基于.docx模板进行内容写入,内容替换

一、pom导入

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.0.0</version>
    </dependency>

二、直接上代码

word模板中${content} 注意只有在.docx用XWPFDocument才有效

2.1 内容替换

  /**
 * 获取document
 *
 */
    XWPFDocument document = null;
    try {
        document = new XWPFDocument(inputStream);
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }

2.1.1

/**
 * 替换段落里面的变量
 *
 * @param doc    要替换的文档
 * @param params 参数
 */
private  void replaceInPara(XWPFDocument doc, Map<String, String> params) {
    for (XWPFParagraph para : doc.getParagraphs()) {
        replaceInPara(para, params);
    }
}

2.1.2

 /**
 * 替换段落里面的变量
 *
 * @param para   要替换的段落
 * @param params 参数
 */
private  void replaceInPara(XWPFParagraph para, Map<String, String> params) {
    List<XWPFRun> runs;
    Matcher matcher;
    replaceText(para);//如果para拆分的不对,则用这个方法修改成正确的
    if (matcher(para.getParagraphText()).find()) {
        runs = para.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            XWPFRun run = runs.get(i);
            String runText = run.toString();
            matcher = matcher(runText);
            if (matcher.find()) {
                while ((matcher = matcher(runText)).find()) {
                    runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                }
                //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
                para.removeRun(i);
                para.insertNewRun(i).setText(runText);
            }
        }
    }
}

2.1.3

 /**
 * 替换文本内容
 * @param para
 * @return
 */
private  List<XWPFRun> replaceText(XWPFParagraph para) {
    List<XWPFRun> runs = para.getRuns();
    String str = "";
    boolean flag = false;
    for (int i = 0; i < runs.size(); i++) {
        XWPFRun run = runs.get(i);
        String runText = run.toString();
        if (flag || runText.equals("${")) {

            str = str + runText;
            flag = true;
            para.removeRun(i);
            if (runText.equals("}")) {
                flag = false;
                para.insertNewRun(i).setText(str);
                str = "";
            }
            i--;
        }

    }

    return runs;
}

2.2 表格操作

2.2.1 将特定格式字体颜色写入表格

      XWPFTable table = document.getTableArray(0);//获取当前表格
	  XWPFTableRow twoRow = table.getRow(2);//获取某一行
	  XWPFTableRow nextRow = table.insertNewTableRow(3);//插入一行
		
	    XWPFTableCell firstRowCellOne = firstRow.getCell(0);
        firstRowCellOne.removeParagraph(0);//删除默认段落,要不然表格内第一条为空行
        XWPFParagraph pIO2 =firstRowCellOne.addParagraph();
        XWPFRun rIO2 = pIO2.createRun();
        rIO2.setFontFamily("宋体");//字体
        rIO2.setFontSize(8);//字体大小
        rIO2.setBold(true);//是否加粗
        rIO2.setColor("FF0000");//字体颜色
        rIO2.setText("这是写入的内容");//
		rIO2.addBreak(BreakType.TEXT_WRAPPING);//软换行,亲测有效

2.2.2

	/**
 * 复制单元格和样式
 *
 * @param targetRow 要复制的行
 * @param sourceRow 被复制的行
 */
public  void createCellsAndCopyStyles(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
    targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());

    List<XWPFTableCell> tableCells = sourceRow.getTableCells();

    if (CollectionUtils.isEmpty(tableCells)) {
        return;

    }

    for (XWPFTableCell sourceCell : tableCells) {
        XWPFTableCell newCell = targetRow.addNewTableCell();

        newCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());

        List sourceParagraphs = sourceCell.getParagraphs();

        if (CollectionUtils.isEmpty(sourceParagraphs)) {
            continue;

        }

        XWPFParagraph sourceParagraph = (XWPFParagraph) sourceParagraphs.get(0);

        List targetParagraphs = newCell.getParagraphs();

        if (CollectionUtils.isEmpty(targetParagraphs)) {
            XWPFParagraph p = newCell.addParagraph();

            p.getCTP().setPPr(sourceParagraph.getCTP().getPPr());

            XWPFRun run = p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0);

            run.setFontFamily(sourceParagraph.getRuns().get(0).getFontFamily());

        } else {
            XWPFParagraph p = (XWPFParagraph) targetParagraphs.get(0);

            p.getCTP().setPPr(sourceParagraph.getCTP().getPPr());

            XWPFRun run = p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0);
            if (sourceParagraph.getRuns().size() > 0) {
                run.setFontFamily(sourceParagraph.getRuns().get(0).getFontFamily());
            }
        }
    }
}
#### 2.2.3
/**
 * 合并单元格
 *
 * @param table         表格对象
 * @param beginRowIndex 开始行索引
 * @param endRowIndex   结束行索引
 * @param colIndex      合并列索引
 */
public  void mergeCell(XWPFTable table, int beginRowIndex, int endRowIndex, int colIndex) {
    if (beginRowIndex == endRowIndex || beginRowIndex > endRowIndex) {
        return;
    }
    //合并行单元格的第一个单元格
    CTVMerge startMerge = CTVMerge.Factory.newInstance();
    startMerge.setVal(STMerge.RESTART);
    //合并行单元格的第一个单元格之后的单元格
    CTVMerge endMerge = CTVMerge.Factory.newInstance();
    endMerge.setVal(STMerge.CONTINUE);
    table.getRow(beginRowIndex).getCell(colIndex).getCTTc().getTcPr().setVMerge(startMerge);
    for (int i = beginRowIndex + 1; i <= endRowIndex; i++) {
        table.getRow(i).getCell(colIndex).getCTTc().getTcPr().setVMerge(endMerge);
    }
}

2.2.4

/**
 * insertRow 在word表格中指定位置插入一行,并将某一行的样式复制到新增行
 * @param copyrowIndex 需要复制的行位置
 * @param newrowIndex 需要新增一行的位置
 * */
public static void insertRow(XWPFTable table, int copyrowIndex, int newrowIndex) {
    // 在表格中指定的位置新增一行
    XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);
    // 获取需要复制行对象
    XWPFTableRow copyRow = table.getRow(copyrowIndex);
    //复制行对象
    targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());
    //或许需要复制的行的列
    List<XWPFTableCell> copyCells = copyRow.getTableCells();
    //复制列对象
    XWPFTableCell targetCell = null;
    for (int i = 0; i < copyCells.size(); i++) {
        XWPFTableCell copyCell = copyCells.get(i);
        targetCell = targetRow.addNewTableCell();
        targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());
        if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
            targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());
            if (copyCell.getParagraphs().get(0).getRuns() != null
                    && copyCell.getParagraphs().get(0).getRuns().size() > 0) {
                XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();
                cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold());
            }
        }
    }

}
  /**
 * 正则匹配字符串
 *
 * @param str
 * @return
 */
private  Matcher matcher(String str) {
    Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    return matcher;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM