You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XWPFDocument追加内容至Word文件时遇异常求助

帮你搞定POI操作Word的这两个问题!

先拆解下你遇到的两个核心问题:

  1. org.apache.poi.EmptyFileException:这锅得甩给你构造函数里的writeToWord()方法!你一上来就用FileOutputStream打开目标Word文件,这操作会直接把原有文件清空成0字节,之后再去读这个空文件,POI可不就给你抛空文件异常了嘛。
  2. java.lang.NullPointerException:因为第一步文件读取失败,doc对象没初始化成功,后面的para和run自然都是null,你调用setText()的时候去访问null对象的方法,不触发空指针才怪~

下面是修复后的完整代码,我给你标了关键修改点,一眼就能看懂:

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.util.Units;

public class tester{
    FileOutputStream fos = null;
    XWPFDocument doc = null;
    XWPFParagraph para = null;
    XWPFRun run = null;
    File file = null;

    public tester() {
        try {
            file = new File("WordDocWithImage.docx");
            // 👉 关键修改1:先读文件再搞输出流!
            if (file.exists() && file.length() > 0) {
                // 文件存在且非空,读取现有内容
                doc = new XWPFDocument(OPCPackage.open(file));
            } else {
                // 文件不存在/为空,新建文档
                doc = new XWPFDocument();
            }
            para = doc.createParagraph();
            run = para.createRun();
            para.setAlignment(ParagraphAlignment.CENTER);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("failed to create file");
        }
    }

    // 👉 关键修改2:输出流挪到最后再创建,别提前清空文件!
    public void prepareOutputStream() throws FileNotFoundException {
        fos = new FileOutputStream("WordDocWithImage.docx");
    }

    public void setText(String text) {
        // 👉 加个空判断,防止初始化失败崩掉
        if (run != null) {
            run.setText(text);
        }
    }

    public void takeScreenshot() throws IOException, AWTException, InvalidFormatException {
        if (run == null) {
            throw new IllegalStateException("Run对象没初始化好哦,先检查文件读取逻辑~");
        }
        Robot robot = new Robot();
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(screenFullImage, "jpeg", baos);
        baos.flush();
        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
        run.addBreak();
        run.addPicture(bis, XWPFDocument.PICTURE_TYPE_JPEG, "image file", Units.toEMU(450), Units.toEMU(250));
        bis.close();
        baos.close();
    }

    public void writeToFile() {
        try {
            if (doc != null && fos != null) {
                doc.write(fos);
                fos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        tester t = new tester();
        try {
            System.out.println("Taking first ss");
            t.setText("First Text");
            t.takeScreenshot();
            System.out.println("Taking second ss");
            t.setText("Second Text");
            t.takeScreenshot();
            // 👉 关键修改3:最后再准备输出流写入,避免提前清空文件
            t.prepareOutputStream();
            t.writeToFile();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

核心修改要点总结:

  • 调整文件操作顺序:先检查并读取现有文件(存在且非空的话),绝对不能先开输出流清空文件,不然读的时候直接凉透。
  • 重构输出流逻辑:把输出流的创建移到所有内容都准备好之后,最后写入文件的时候再操作,这样不会破坏原有文件内容。
  • 加空指针防护:在使用run这类关键对象前先判断非空,就算初始化出问题也不会直接崩掉,还能给你明确的提示。
  • 优化资源管理:确保各种流都正确关闭,避免内存泄漏。

这样改完之后,不管是给现有Word文件追加内容,还是文件不存在时新建文件,都能正常工作啦~

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:28:26