springboot 基于 POI 填充 Word 模版

原地址:https://www.toutiao.com/i6886078325647737348/

根据用户订单信息来填充现有的Word模版,从而生成一个在线电子文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o8bbihF0-1614738488837)(images/screenshot_1609728719013.png)]

POI操作Word的常用属性

  • XWPFDocument:用来获取或者创建一个Word文档
  • XWPFParagraph:标题、文档、表格等
  • XWPFRun:同样风格的一段文本
  • XWPFTable:表格
  • XWPFTableRow:表格中的一行
  • XWPFTableCell:表格中的一个单元格

填充Word模版

引入POI包

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>

这里的变量值是 4.1.0。

获取文档对象

//通过文件读取
XWPFDocument document = new XWPFDocument(OPCPackage.open(filePath));

//通过文件流读取,in是InputStream对象
XWPFDocument document = new XWPFDocument(in);

获取到文档之后,就可以从中获取到对应的XWPFParagraph对象

List<XWPFParagraph> paragraphs = document.getParagraphs();

让后我们可以从XWPFParagraph获取到Text即段落中的内容,但是我们要替换段落中的内容的话必须在XWPFRun才行。所以需要循环遍历去处理

for (XWPFParagraph paragraph : paragraphs) {
    List<XWPFRun> runs = paragraph.getRuns();
    for (XWPFRun run : runs) {

    }
}

这里我们可以通过run.toString()获取到内容,并通过run.setText进行替换。在我们获取到文本之后,要匹配出对象的关键字,所以这里需要一个正则匹配

private static List<String> getKeywords(String source) {
        String regStr = "\\$\\{[a-zA-Z0-9]+\\}";
        List<String> matchStrs = new ArrayList<>();

        Pattern patten = Pattern.compile(regStr);
        Matcher matcher = patten.matcher(source);

        while (matcher.find()) { 
            matchStrs.add(matcher.group());
        }

        return matchStrs;
    }

我们通过getKeywords获取到模版中的关键字后,再从Map对象中去取出对应的值,然replace掉

for (XWPFParagraph paragraph : paragraphs) {
     List<XWPFRun> runs = paragraph.getRuns();
     for (XWPFRun run : runs) {
         String value=run.ToString();
          List<String> keywords = getKeywords(value);
        for (String keyword : keywords
        ) {
            String key = keyword.replace("${", "").replace("}", "");
            String keyValue = sourceTextMap.get(key);
            if (StringUtils.isEmpty(keyValue)) {
                keyValue = "";
            }
            value = value.replace(keyword, keyValue);
        }
        run.setText(value,0);

     }
 }

一般的内容可以通过${key}的方式来替换,那么遇到表格怎么办呢?我继续来处理表格

List<XWPFTable> tables = document.getTables();

我这里先只针对我的模版进行处理,如果是遇到多个XWPFTable那么就根据情况自行处理吧

for (int i = 1; i < tableList.size(); i++) {
    XWPFTableRow newRow = table.createRow();
    List<XWPFTableCell> cells = newRow.getTableCells();
    for (int j = 0; j < cells.size(); j++) {
        XWPFTableCell cell = cells.get(j);
        cell.setText(tableList.get(i - 1)[j]);
    }
}
if (!ObjectUtils.isEmpty(tableBottom)) {
    XWPFTableRow tableRow = table.createRow();
    List<XWPFTableCell> footerCells = tableRow.getTableCells();
    for (int j = 0; j < footerCells.size(); j++) {
        XWPFTableCell cell = footerCells.get(j);
        if (!StringUtils.isEmpty(tableBottom[j])) {
            XWPFParagraph paragraph = cell.addParagraph();
            XWPFRun xwpfRun = paragraph.createRun();
            xwpfRun.setText(tableBottom[j]);
            xwpfRun.setFontSize(12);
            xwpfRun.setFontFamily("黑体");
            xwpfRun.setBold(true);
            xwpfRun.setColor("000000");
        } else {
            cell.setText(tableBottom[j]);
        }

    }

}

这里就会根据我们的传入的tableList即表格数据进行填充。根据tableBottom数组来添加一些样式。最后来看看我们做出的效果,首先是用Swagger调用接口

{
    "fileName":"xxx订单导出.doc",
    "filePath":"order_template.docx",
    "headerContent":{
        "orderDate":"2020-03-26 10:25",
        "planDate":"202-03-27",
        "orderNo":"20200325000074645",
        "agreeNo":"80192000035",
        "orderUnitNo":"155283",
        "orderUnitName":"小卖部农业开发有限公司",
        "name":"IT界摸鱼专家",
        "phone":"138888888",
        "bankNo":"6666666666666666573",
        "owe":"小鸡炖蘑菇有限公司开发区分公司",
        "owePrice":"16775.90",
        "zh":"壹万伍仟捌佰贰拾伍圆零角零分",
        "isDiaplay":"",
        "memo":"小鸡炖蘑菇专用配送"
    },
    "tableList":[
        [
            "113029022",
            "小鸡炖蘑菇了不起",
            "2",
            "T",
            "50",
            "2000.00",
            "300000.00",
            ""
        ],
        [
            "113029044",
            "小鸡炖蘑菇真棒",
            "1.5",
            "T",
            "75",
            "3000.00",
            "50000.00",
            ""
        ],
        [
            "113029077",
            "小鸡炖蘑菇好耶",
            "1.275",
            "T",
            "85",
            "2020.50",
            "900000.50",
            "赠品"
        ],
        [
            "113040057",
            "小鸡炖蘑菇",
            "10.025",
            "T",
            "255",
            "12030.00",
            "200000.20",
            ""
        ]
    ],
    "tableBottom":[
            "合计",
            "壹万伍仟捌佰贰拾伍圆整",
            "55.275",
            "",
            "852",
            "",
            "2255114.00",
            "60.32T"
        ]
}

上面是我传参数,最后导出的Word文档是这样的

Java基于POI填充Word模版

当然,这里还有一些细节需要处理。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值