Java 使用 Apache POI 在 Word 文档中批量替换文本、本地图片、网络图片等

Apache POI库简介

Apache POI是一个强大的Java库,专门用于处理Microsoft Office格式的文档,包括Excel和Word文件。
它提供了一整套丰富的API,能够让开发者轻松在Java应用中进行文档的读写、编辑和生成。
通过Apache POI,你可以操作Excel电子表格中的单元格、图表和数据透视表,以及Word文档中的文本、表格和格式设置。

Maven

在项目的pom.xml文件中添加以下Maven依赖,以便在项目中使用Apache POI库和Log4j进行日志记录:

<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi</artifactId>
     <version>5.2.3</version>
 </dependency>
 <dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>5.2.3</version>
 </dependency>
 <dependency>
     <groupId>org.apache.logging.log4j</groupId>
     <artifactId>log4j-core</artifactId>
     <version>2.20.0</version>
 </dependency>
 <dependency>
     <groupId>org.apache.logging.log4j</groupId>
     <artifactId>log4j-api</artifactId>
     <version>2.20.0</version>
 </dependency>

这些依赖项包括处理Excel和Word文档所需的poi和poi-ooxml,以及log4j用于日志记录。

核心代码示例

下面的示例代码展示了如何使用Apache POI在Word文档中进行文本替换。我们将读取一个Word文档,在其中搜索特定的关键字,并将其替换为指定的内容,然后保存修改后的文档。

  public static void replaceWord(String srcPath, String destPath, HashMap<String, Object> map) {
        if (srcPath == null || destPath == null || map == null || map.isEmpty()) {
            throw new IllegalArgumentException("Invalid input parameters");
        }

        try (XWPFDocument document = new XWPFDocument(new FileInputStream(srcPath));
             FileOutputStream outStream = new FileOutputStream(destPath)) {

            replaceTextAndImagesInDocument(document, map);

            // 写入修改后的文档
            document.write(outStream);
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("IO Exception: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("Error processing the document: " + e.getMessage());
        }
    }

    private static void replaceTextAndImagesInDocument(XWPFDocument document, HashMap<String, Object> map) throws Exception {
        Set<String> keys = map.keySet();

        // 替换段落中的文本和图片
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            replaceTextAndImagesInRun(paragraph.getRuns(), keys, map);
        }

        // 替换表格中的文本和图片
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        replaceTextAndImagesInRun(paragraph.getRuns(), keys, map);
                    }
                }
            }
        }
    }

    private static void replaceTextAndImagesInRun(List<XWPFRun> runs, Set<String> keys, HashMap<String, Object> map) throws Exception {
        for (XWPFRun run : runs) {
            if (run != null) {
                String text = run.getText(0);  // 获取当前 run 的文本

                if (text != null) {
                    // 遍历每个占位符,确保逐个替换文本和图片
                    for (String key : keys) {
                        Object replacement = map.get(key);

                        // 替换文本(文本占位符的替换)
                        if (text.contains(key) && replacement instanceof String) {
                            String replacementStr = (String) replacement;

                            // 判断是否为网络图片 URL
                            if (replacementStr.startsWith("http://") || replacementStr.startsWith("https://")) {
                                // 替换图片占位符
                                run.setText("", 0);  // 清除占位符文本
                                try (InputStream inputStream = new URL(replacementStr).openStream()) {
                                    run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, replacementStr, Units.toEMU(100), Units.toEMU(100)); // 设置图片大小
                                } catch (IOException e) {
                                    System.err.println("Error downloading image from URL: " + replacementStr);
                                }
                            } else if (replacementStr.endsWith(".png") || replacementStr.endsWith(".jpg")) {
                                // 替换本地图片占位符
                                run.setText("", 0);  // 清除占位符文本
                                try (InputStream inputStream = new FileInputStream(replacementStr)) {
                                    run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, replacementStr, Units.toEMU(100), Units.toEMU(100)); // 设置图片大小
                                }
                            } else {
                                // 替换文本占位符
                                text = text.replace(key, replacementStr);  // 替换文本中的占位符
                                run.setText(text, 0);  // 更新 run 的文本
                            }
                        }
                    }
                }
            }
        }
    }

调用示例

在使用该方法时,你可以指定源文档路径、目标文档路径以及包含要替换内容的HashMap:

HashMap<String, Object> replacements = new HashMap<>();
replacements.put("${name}", "John Doe");
replacements.put("${date}", "2024-09-02");
replacements.put("${local-image}", "D:/face/test/31.png");
replacements.put("${http-image}", "https://p3.itc.cn/images01/20230925/43d7f951f84549d69fdaa790d1d5dbeb.png");

replaceWord("template.docx", "output.docx", replacements);

测试结果

运行上述代码后,你可以看到指定的占位符被替换为新的内容,文档内容已成功更新:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

通过这种方式,你可以灵活地在Java应用中自动化Word文档的编辑任务。

可以使用Apache POIWord文档添加水印。下面是添加水印的示例代码: ```java import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; public class AddWatermarkToWord { public static void main(String[] args) throws IOException { // 读取模板文件 InputStream is = AddWatermarkToWord.class.getResourceAsStream("template.docx"); XWPFDocument doc = new XWPFDocument(is); // 添加水印 for (XWPFParagraph p : doc.getParagraphs()) { for (XWPFRun r : p.getRuns()) { String text = r.getText(0); if (text != null && text.contains("水印")) { r.setText(text.replace("水印", ""), 0); r.getCTR().addNewRPr().addNewNoProof(); r.getCTR().getRPr().addNewColor().setVal("C0C0C0"); r.getCTR().getRPr().addNewSz().setVal(48L); r.getCTR().getRPr().addNewRFonts().setAscii("宋体"); r.getCTR().getRPr().addNewRFonts().setHAnsi("宋体"); r.getCTR().getRPr().addNewRFonts().setCs("宋体"); r.getCTR().getRPr().addNewVertAlign().setVal(org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun.SUPERSCRIPT); } } } // 保存文档 FileOutputStream out = new FileOutputStream("output.docx"); doc.write(out); out.close(); doc.close(); } } ``` 在上面的代码,我们首先读取一个模板文件 `template.docx`,然后遍历文档的每个段落和运行,找到包含“水印”的文本,然后设置文本的格式,使其成为一个水印。最后将修改后的文档保存到 `output.docx` 文件得注意的是,上面的代码只能在使用 docx 格式的 Word 文档上添加水印,如果要在使用 doc 格式的 Word 文档上添加水印,可以使用 HWPF API。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值