java使用poi操作word文档(段落、表格、页眉、页脚)

本文介绍了使用Apache POI库实现Word文档中段落、表格内容以及页眉页脚的动态替换技术,包括不同类型的处理方法和示例代码,适合数据驱动的文档更新需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在工作中我接触到的word类型主要有三种类型,分别是段落、表格、表格中的段落,这三种有可能同时出现,下面的内容会分别给出这几种类型的解决方案,以及页眉、页脚的填充。

表格中的段落就是指下图中这种一个单元格中有行并且有多个需要填充的地方。
在这里插入图片描述

poi填充word原理其实是识别word模板中的值,然后进行替换,一般会以${xxx}作为标记

依赖

        <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>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.0</version>
        </dependency>

1.段落

        Map<String, String> map = new HashMap<>();
        map.put("aaa","122");//map的key为模板中替换的对象,value为替换的值
        InputStream is = this.getClass().getResourceAsStream("/demo.docx");
        XWPFDocument document = new XWPFDocument(is);
        Set<String> set = map.keySet();
        Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();//获取word段落
        while (itPara.hasNext()) {
            XWPFParagraph paragraph = itPara.next();//获取段落
            Iterator<String> iterator = set.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();//获取key
                List<XWPFRun> run = paragraph.getRuns();//获取行
                for (int i = 0; i < run.size(); i++) {
                    //如果key等于word中的值,就替换
                    if (run.get(i).getText(run.get(i).getTextPosition()) != null &&
                            run.get(i).getText(run.get(i).getTextPosition()).equals(key)) {
                        run.get(i).setText(map.get(key), 0);//0指从第一个字符开始替换
                    }
                }
            }
        }
        //导出文件存在本地
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        document.write((OutputStream) byteArrayOutputStream);
        String filePath = "D://uploads/demo/";//存储目的地
        String fileName = "demo";//文件名称
        File file = new File(filePath + fileName + ".docx");
        //如果不存在文件夹则创建
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        FileOutputStream outputStream = new FileOutputStream(filePath + fileName +  ".docx");
        outputStream.write(byteArrayOutputStream.toByteArray());
        outputStream.flush();
        outputStream.close();

2.表格

        Map<String, String> map = new HashMap<>();
        map.put("aaa","122");//map的key为模板中替换的对象,value为替换的值
        InputStream is = this.getClass().getResourceAsStream("/demo.docx");
        WPFDocument document = new XWPFDocument(is);
        List<XWPFTable> tables = document.getTables();//获取表格
        Set<String> set = map.keySet();
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();//获取行
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();//获取单元格
                for (XWPFTableCell cell : cells) {
                    for (String s : set) {
                        //判断行是否包含map中的key,若包含,则用value替换行中key的内容
                        if (cell.getText().contains(s)) {
                            //用来存储替换后的行数据
                            String replace = "";
                            replace = cell.getText().replace(s, map.get(s));
                            //删除原来的行
                            cell.removeParagraph(0);
                            //新增一行
                            XWPFParagraph para = cell.addParagraph();
                            para.setSpacingBetween(1);
                            //填充数据
                            cell.setText(replace);
                        }
                    }
                }
            }
        }
        //导出文件存在本地
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        document.write((OutputStream) byteArrayOutputStream);
        String filePath = "D://uploads/demo/";//存储目的地
        String fileName = "demo";//文件名称
        File file = new File(filePath + fileName + ".docx");
        //如果不存在文件夹则创建
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        FileOutputStream outputStream = new FileOutputStream(filePath + fileName +  ".docx");
        outputStream.write(byteArrayOutputStream.toByteArray());
        outputStream.flush();
        outputStream.close();

3.表格中的段落(可通用普通表格),精髓在这,其他与上同

           for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();//获取行
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();//获取单元格
                for (XWPFTableCell cell : cells) {
                    //用以判断是否有值更改
                    int a = 0;
                    //记录单元格原值
                    String replace = cell.getText();
                    for (String s : set) {
                        //判断单元格的值是否包含key
                        if (cell.getText().contains(s)) {
                            a = 1;
                            //替换key
                            replace = replace.replace(s, map.get(s));
                        }
                    }
                    //有替换值
                    if (a == 1) {
                        //获取当前单元格行数
                        int size = cell.getParagraphs().size();
                        for (int i = 0; i < size; i++) {
                            //删除原数据
                            cell.removeParagraph(0);
                        }
                        //这个字符截取需要提前在word模板中在需要回车的地方加上'|',不然的话是不会换行的
                        String[] jdcl = replace.split("\\|");
                        for (int i = 0; i < jdcl.length; i++) {
                            XWPFParagraph xwpfParagraph = cell.addParagraph();//新建段落
                            XWPFRun run = xwpfParagraph.createRun();//新建行
                            run.setText(jdcl[i]);赋值
                        }
                    }
                }
            }
         }
        }

4.页眉、页脚
页眉与页脚的处理方式其实与上述内容都是类似的,只是获取word不同位置的内容而已
页眉

        Map<String, String> map = new HashMap<>();
        map.put("${a}","123");
        InputStream is = this.getClass().getResourceAsStream("/demo.docx");
        XWPFDocument document = new XWPFDocument(is);
        List<XWPFHeader> headerList = document.getHeaderList();
        for (XWPFHeader xwpfHeader : headerList) {
            List<XWPFParagraph> paragraphs = xwpfHeader.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (int i = 0; i < runs.size(); i++) {
                    for (String s : set) {
                        if (runs.get(i).getText(runs.get(i).getTextPosition()) != null &&
                                runs.get(i).getText(runs.get(i).getTextPosition()).contains(s)) {
                            String replace = runs.get(i).getText(runs.get(i).getTextPosition()).replace(s, map.get(s));
                            runs.get(i).setText(replace, 0);
                        }
                    }
                }
            }
        }

页脚


       Map<String, String> map = new HashMap<>();
       map.put("${a}","123");
       InputStream is = this.getClass().getResourceAsStream("/demo.docx");
       XWPFDocument document = new XWPFDocument(is);
       List<XWPFFooter> footerList = document.getFooterList();
       for (XWPFFooter xwpfFooter : footerList) {
            List<XWPFParagraph> paragraphs = xwpfFooter.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (int i = 0; i < runs.size(); i++) {
                    for (String s : set) {
                        if (runs.get(i).getText(runs.get(i).getTextPosition()) != null &&
                                runs.get(i).getText(runs.get(i).getTextPosition()).contains(s)) {
                            String replace = runs.get(i).getText(runs.get(i).getTextPosition()).replace(s, map.get(s));
                            runs.get(i).setText(replace, 0);
                        }
                    }
                }
            }
        }
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值