使用Apache POI和POI-OOXML实现word模板文档自动填充功能

 最近接到一个新的需求,用户创建好模板文件保存到模板库,然后使用在线文档编辑器打开模板时,将系统数据填充到模板文件并生成新的word文件,然后在线编辑,研究使用Apache POI和POI-OOXML实现了这个功能。

Maven依赖

        <!-- Apache POI 和 POI-OOXML -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>

自动填充的接口

import org.apache.poi.xwpf.usermodel.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/fill")
public class WordFillController {

    @PostMapping("/wordFill")
    public ResponseEntity<?> wordFill() {
        String templatePath = "E:\\word\\template.docx";
        String outputPath = "E:\\word\\output.docx";

        // 待填充进模板的数据
        Map<String, String> data = new HashMap<>();
        data.put("name", "张三");
        data.put("sex", "男");
        data.put("age", "18");

        Map<String, String> data1 = new HashMap<>();
        data1.put("name", "张三1");
        data1.put("sex", "男1");
        data1.put("age", "20");

        Map<String, String> data2 = new HashMap<>();
        data2.put("name", "李四");
        data2.put("sex", "男");
        data2.put("age", "21");

        Map<String, String> data3 = new HashMap<>();
        data3.put("name", "王五");
        data3.put("sex", "女");
        data3.put("age", "45");

        List<Map<String, String>> dataList = Arrays.asList(data1, data2, data3);

        try (
                // 从模板文件创建word文档对象
                XWPFDocument doc = new XWPFDocument(Files.newInputStream(Paths.get(templatePath)));
                // 文件输出流
                FileOutputStream fos = new FileOutputStream(outputPath)
        ) {

            replacePlaceholders(doc, data);// 替换占位符
            fillTable(doc, dataList);// 填充表格
            // 将文档写入输出流
            doc.write(fos);
            // 刷新输出流
            fos.flush();

            return ResponseEntity.ok().build();
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    private void replacePlaceholders(XWPFDocument doc, Map<String, String> data) {
        // 遍历文档中的段落,替换占位符
        doc.getParagraphs().forEach(paragraph -> {
            // 遍历段落中的文本,替换占位符
            paragraph.getRuns().forEach(run -> {
                // 获取文本内容
                String text = run.getText(0);
                // 判断文本是否包含占位符,如果包含,则替换占位符
                if (text != null && text.contains("${")) {
                    for (Map.Entry<String, String> entry : data.entrySet()) {
                        text = text.replace("${" + entry.getKey() + "}", entry.getValue());
                    }
                    // 设置替换后的文本
                    run.setText(text, 0);
                }
            });
        });
    }

    private void fillTable(XWPFDocument doc, List<Map<String, String>> dataList) {
        XWPFTable table = doc.getTables().get(0); // 获取第一个表格

        // 获取表格的模板行(假设表格的第一行是标题行,第二行为模板行)
        XWPFTableRow templateRow = table.getRow(1);

        // 添加新的行,并删除模板行
        for (Map<String, String> data : dataList) {
            XWPFTableRow newRow = table.createRow();

            // 手动创建每个单元格,并复制模板行的样式
            for (int i = 0; i < templateRow.getTableCells().size(); i++) {
                XWPFTableCell templateCell = templateRow.getCell(i);
                XWPFTableCell newCell = newRow.getCell(i);
                if (newCell == null) {
                    newCell = newRow.createCell();
                }

                // 复制模板行单元格的样式,不复制内容
                copyCellStyleWithoutText(templateCell, newCell);

                // 填充数据
                switch (i) {
                    case 0:
                        newCell.setText(data.get("name"));
                        break;
                    case 1:
                        newCell.setText(data.get("sex"));
                        break;
                    case 2:
                        newCell.setText(data.get("age"));
                        break;
                }
            }
        }

        // 删除模板行
        table.removeRow(1);
    }

    private void copyCellStyleWithoutText(XWPFTableCell sourceCell, XWPFTableCell targetCell) {
        // 复制单元格的样式,但不复制文本内容
        targetCell.getParagraphs().forEach(paragraph -> {
            XWPFParagraph sourceParagraph = sourceCell.getParagraphs().get(0);
            paragraph.setAlignment(sourceParagraph.getAlignment());
            paragraph.setVerticalAlignment(sourceParagraph.getVerticalAlignment());

            if (!sourceParagraph.getRuns().isEmpty()) {
                XWPFRun sourceRun = sourceParagraph.getRuns().get(0);
                XWPFRun targetRun = paragraph.createRun();

                targetRun.setBold(sourceRun.isBold());
                targetRun.setItalic(sourceRun.isItalic());
                targetRun.setFontFamily(sourceRun.getFontFamily());
                targetRun.setFontSize(sourceRun.getFontSize());
            }
        });

        // 复制单元格背景色等样式
        targetCell.setColor(sourceCell.getColor());
        targetCell.setVerticalAlignment(sourceCell.getVerticalAlignment());
    }
}

word模板

调用接口后生成的新文件

poi-ooxml-5.2.2.jar是一个Java库,用于操作Microsoft Office Open XML(OOXML)格式的文档。它是Apache POI项目的一部分,POI是一个开源的Java库,用于读取、创建和修改各种格式的Office文档poi-ooxml-5.2.2.jar提供了一系列类和方法,用于处理OOXML格式的文档,包括.xlsx电子表格文件和.docx文档文件。使用这个库,我们可以读取和提取文档中的数据,修改和创建新的文档,添加、删除或修改单元格、行、列、图表、图像等元素。它还支持文本格式设置、样式、公式计算等功能使用poi-ooxml-5.2.2.jar,我们可以通过编程方式对OOXML文档进行自动化处理。例如,我们可以读取电子表格中的数据,并进行各种计算和分析,或者将数据导出到其他格式。我们还可以创建自定义的模板文件,填充数据并生成新的文档poi-ooxml-5.2.2.jar是在Apache许可证下发布的,所以我们可以免费使用它,并集成到我们的Java应用程序中。它是一个功能强大且广泛使用的库,被许多开发人员和企业用于处理Office文档。无论是处理大量数据还是进行高级文档操作,poi-ooxml-5.2.2.jar都可以提供方便和高效的解决方案。 总之,poi-ooxml-5.2.2.jar是一个处理Microsoft Office Open XML格式文档的Java库,它可以帮助我们读取、创建和修改xlsx和docx文档,提供了丰富的功能和灵活性,能够满足各种对于OOXML文档的处理需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值