Java使用poi操作resource下的word文件

Java使用poi操作resource下的word文件

1、导入poi
<!-- poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.0</version>
</dependency>

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.0</version>
</dependency>
2、poi操作word工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author bcy
 * @date 2022/9/28
 */
@Slf4j
public class PoiWordUtils {

    /**
     * @param doc        docx解析对象
     * @param tableIndex 第几个表格
     */
    public static XWPFTable getTable(XWPFDocument doc, int tableIndex) {
        return doc.getTables().get(tableIndex);
    }

    /**
     * 为表格插入行数,此处不处理表头,所以从第二行开始
     *
     * @param table     需要插入数据的表格
     * @param tableList 插入数据集合
     * @param index     在几行后开始插入数据 1为第一行
     * @param cellNum   表格列数
     */
    public static void insertTable(XWPFTable table, List<String[]> tableList, int index, int cellNum) {
        //创建与数据一致的行数
        for (int i = 0; i < tableList.size(); i++) {
            XWPFTableRow targetRow = table.insertNewTableRow(index + i);
            for (int j = 0; j < cellNum; j++) {
                //添加新列
                XWPFTableCell newCell = targetRow.addNewTableCell();
                //设置垂直居中
                newCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                //设置水平居中
                CTTc cttc = newCell.getCTTc();
                CTP ctp = cttc.getPList().get(0);
                CTPPr ctppr = ctp.getPPr();
                if (ctppr == null) {
                    ctppr = ctp.addNewPPr();
                }
                CTJc ctjc = ctppr.getJc();
                if (ctjc == null) {
                    ctjc = ctppr.addNewJc();
                }
                //水平居中
                ctjc.setVal(STJc.CENTER);
                newCell.removeParagraph(0);
                //得到新单元格的段落
                List<XWPFParagraph> targetParagraphs = newCell.getParagraphs();
                //判断新单元格是否为空
                XWPFParagraph ph = StringUtils.isEmpty(newCell.getText()) ? newCell.addParagraph() : targetParagraphs.get(0);
                ph.removeRun(0);
                //设置段落居中
                ph.setAlignment(ParagraphAlignment.CENTER);
                //得到文本对象
                XWPFRun run = ph.getRuns().isEmpty() ? ph.createRun() : ph.getRuns().get(0);
                run.setFontFamily("方正仿宋简体");
                run.setFontSize(10);
                run.setText(tableList.get(i)[j]);
            }
        }
    }

    /**
     * 为表格指定行赋值
     *
     * @param table     需要插入数据的表格
     * @param cellDatas 插入数据集合
     * @param index     在几行后开始插入数据 1为第一行
     * @param cellNum   表格列数
     * @param startCell 起始列
     */
    public static void updateTable(XWPFTable table, String[] cellDatas, int index, int cellNum, int startCell) {
        XWPFTableRow row = table.getRow(index);
        for (int i = startCell; i < cellNum; i++) {
            XWPFTableCell cell = row.getCell(i);
            //设置垂直居中
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            //设置水平居中
            CTTc cttc = cell.getCTTc();
            CTP ctp = cttc.getPList().get(0);
            CTPPr ctppr = ctp.getPPr();
            if (ctppr == null) {
                ctppr = ctp.addNewPPr();
            }
            CTJc ctjc = ctppr.getJc();
            if (ctjc == null) {
                ctjc = ctppr.addNewJc();
            }
            //水平居中
            ctjc.setVal(STJc.CENTER);
            //得到单元格的段落
            List<XWPFParagraph> targetParagraphs = cell.getParagraphs();
            //判断新单元格是否为空
            XWPFParagraph ph = targetParagraphs.get(0);
            //设置段落居中
            ph.setAlignment(ParagraphAlignment.CENTER);
            //得到文本对象
            XWPFRun run = ph.getRuns().isEmpty() ? ph.createRun() : ph.getRuns().get(0);
            run.setFontFamily("方正仿宋简体");
            run.setFontSize(10);
            run.setText(cellDatas[i - startCell]);
        }
    }

    /**
     * 替换段落里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    public static void replaceParams(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph paragraph;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            replaceParam(paragraph, params);
        }
    }

    /**
     * 在制定标志位插入段落
     *
     * @param doc
     * @param datas
     * @param flag
     */
    public static void insertParagraph(XWPFDocument doc, List<String[]> datas, String flag) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph ph;
        while (iterator.hasNext()) {
            ph = iterator.next();
            String paragraphText = ph.getParagraphText();
            if (StringUtils.equals(paragraphText, flag)) {
                ph.removeRun(0);
                for (int i = 0; i < datas.size(); i++) {
                    for (int j = 0; j < datas.get(i).length; j++) {
                        XWPFRun run = ph.insertNewRun(j);
                        run.setFontFamily("方正仿宋简体");
                        run.setFontSize(10);
                        run.addTab();
                        run.setText(datas.get(i)[j]);
                        if (j < datas.get(i).length - 1) {
                            run.addBreak(BreakClear.ALL);
                        }
                    }
                }
            }
        }
    }

    /**
     * 替换所有表格里面的变量
     *
     * @param doc 要替换的文档
     */
    public static void replaceAllTableParams(XWPFDocument doc, Map<String, Object> testMap) {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
            if (matcher(table.getText()).find()) {
                rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        paras = cell.getParagraphs();
                        for (XWPFParagraph para : paras) {
                            replaceParam(para, testMap);
                        }
                    }
                }
            }
        }
    }

    /**
     * 替换表格里面的变量
     */
    public static void replaceTableParams(XWPFTable table, Map<String, Object> testMap) {
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
        if (matcher(table.getText()).find()) {
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceParam(para, testMap);
                    }
                }
            }
        }
    }

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

    public static Matcher matcher(String str) {
        return pattern.matcher(str);
    }

    /**
     * 替换段落里面的变量
     *
     * @param paragraph 要替换的段落
     * @param params    参数
     */
    public static void replaceParam(XWPFParagraph paragraph, Map<String, Object> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        StringBuilder runText = new StringBuilder();
        if (matcher(paragraph.getParagraphText()).find()) {
            runs = paragraph.getRuns();
            int j = runs.size();
            for (int i = 0; i < j; i++) {
                runText.append(runs.get(0).toString());
                //保留最后一个段落,在这段落中替换值,保留段落样式
                if (!((j - 1) == i)) {
                    paragraph.removeRun(0);
                }
            }
            matcher = matcher(runText.toString());
            if (matcher.find()) {
                while ((matcher = matcher(runText.toString())).find()) {
                    runText = new StringBuilder(matcher.replaceFirst(MapUtils.getString(params, matcher.group(1))));
                }
                runs.get(0).setText(runText.toString(), 0);
            }
        }

    }

    /**
     * word单元格列合并 都以0开始计算
     *
     * @param table     表格
     * @param row       合并列所在行
     * @param startCell 开始列
     * @param endCell   结束列
     */
    public static void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {
        for (int i = startCell; i <= endCell; i++) {
            XWPFTableCell cell = table.getRow(row).getCell(i);
            if (i == startCell) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * word单元格行合并
     *
     * @param table    表格
     * @param col      合并行所在列
     * @param startRow 开始行
     * @param endRow   结束行
     */
    public static void mergeCellsVertically(XWPFTable table, int col, int startRow, int endRow) {
        for (int i = startRow; i <= endRow; i++) {
            XWPFTableCell cell = table.getRow(i).getCell(col);
            if (i == startRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

}
3、在resource目录下新建word(后缀为docx)

在这里插入图片描述

4、读取test.docx文件
InputStream is = this.getClass().getClassLoader().getResourceAsStream("word/test.docx");
XWPFDocument doc = new XWPFDocument(is);

List<POIXMLDocumentPart> relations = doc.getRelations();
relations.forEach((t) -> {
    System.out.println(t.toString());
});
5、解决No valid entries or contents found, this is not a valid OOXML (Office Open XML) file报错
<plugins>
<!-- 让maven不编译docx文件,但仍将其打包 -->
    <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
           <configuration>
               <nonFilteredFileExtensions>
                   <nonFilteredFileExtension>docx</nonFilteredFileExtension>
               </nonFilteredFileExtensions>
           </configuration>
    </plugin>
</plugins>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值