You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Apache POI Docx:向已有文档页眉插入图片报错求助

解决向Word文档页眉插入图片后文件损坏的问题

我来帮你排查下问题所在,你的代码里有几个关键问题导致生成的Word文档损坏打不开:

  • 变量名拼写错误:你定义的页眉策略变量是headerPolicy,但后面调用getDefaultHeader()时写成了headerFooterPolicy,这会导致编译错误(如果没修正直接运行,可能会抛出未定义变量的异常,进而生成不完整的损坏文件)。
  • 手动修改BlipID画蛇添足run.addPicture()方法已经自动完成了图片的嵌入、关联ID的生成和绑定工作,你手动遍历获取BlipID并设置setEmbed()的操作,会覆盖掉正确的关联关系,直接破坏文档的内部结构,这是文件打不开的核心原因。
  • 未处理默认页眉不存在的情况:如果原Word文档没有默认页眉,getDefaultHeader()会返回null,此时直接调用createParagraph()会抛出空指针异常,导致生成的文件不完整。
  • 流资源未正确管理:直接调用in.close()fos.close()可能会因为异常导致流未关闭,进而损坏文件,建议使用try-with-resources自动管理资源。

修正后的代码

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import java.io.*;

public class AddHeaderImage {
    public static void main(String[] args) {
        // 使用try-with-resources自动管理输入输出流
        try (FileInputStream docIn = new FileInputStream("test.docx");
             XWPFDocument docx = new XWPFDocument(docIn);
             FileOutputStream fos = new FileOutputStream("test_headerImg.docx")) {

            XWPFHeaderFooterPolicy headerPolicy = docx.getHeaderFooterPolicy();
            XWPFHeader header;

            // 处理默认页眉不存在的情况,创建新的默认页眉
            if (headerPolicy == null) {
                // 创建页眉页脚策略
                headerPolicy = docx.createHeaderFooterPolicy();
                header = headerPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
            } else {
                header = headerPolicy.getDefaultHeader();
                if (header == null) {
                    header = headerPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
                }
            }

            // 创建段落并设置对齐方式
            XWPFParagraph parNew = header.createParagraph();
            parNew.setAlignment(ParagraphAlignment.LEFT);

            // 创建Run并添加图片
            XWPFRun run = parNew.createRun();
            String pathImg = "FILE/logo/logo_top.jpg";
            try (InputStream imgIn = new FileInputStream(pathImg)) {
                // addPicture方法会自动处理图片嵌入和关联,无需手动设置BlipID
                run.addPicture(imgIn, XWPFDocument.PICTURE_TYPE_JPEG, "logo", Units.toEMU(150), Units.toEMU(50));
            }

            // 写入修改后的文档
            docx.write(fos);
            System.out.println("页眉图片添加成功!");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键修改说明

  1. 修复了变量名拼写错误,确保调用的是正确的headerPolicy对象。
  2. 移除了手动设置BlipID的代码,依赖run.addPicture()的自动处理逻辑。
  3. 增加了对headerPolicyheader为null的判断,当原文档没有页眉时自动创建。
  4. 使用try-with-resources包裹所有流资源,确保无论是否发生异常,流都会被正确关闭,避免文件损坏。

内容的提问来源于stack exchange,提问作者Lof

火山引擎 最新活动