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