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

求助:将MS Word格式XML数据存入Apache POI的XWPFDocument报错

问题描述

尝试将MS Word格式的XML数据存入Apache POI的XWPFDocument时执行出错,以下是编写的代码,求正确读取并存储这类文件的方法。

原代码

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

public class WordMerger {

    public static void main(String[] args) {

        try {
            // Open the first document
            XWPFDocument doc1 = new XWPFDocument(new FileInputStream("document1.xml"));

            // Open the second document
            XWPFDocument doc2 = new XWPFDocument(new FileInputStream("document2.xml"));

            // Iterate through the paragraphs of the second document
            for (XWPFParagraph p : doc2.getParagraphs()) {

                // Create a new paragraph in the first document
                XWPFParagraph newParagraph = doc1.createParagraph();

                // Iterate through the runs of the current paragraph in the second document
                for (XWPFRun r : p.getRuns()) {

                    // Create a new run in the new paragraph of the first document
                    XWPFRun newRun = newParagraph.createRun();

                    // Copy the text and formatting of the current run to the new run
                    newRun.setText(r.getText(0));
                    newRun.setBold(r.isBold());
                    newRun.setItalic(r.isItalic());
                    newRun.setUnderline(r.getUnderline());
                    newRun.setColor(r.getColor());
                    newRun.setFontFamily(r.getFontFamily());
                    newRun.setFontSize(r.getFontSize());
                }
            }

            // Save the merged document
            doc1.write(new FileOutputStream("merged_document.xml"));

            // Close the documents
            doc1.close();
            doc2.close();

            System.out.println("Documents merged successfully!");

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

问题分析与解决方案

1. 基础语法错误修正

原代码中注释未添加//,会直接导致编译失败,已在上述代码中补全。

2. XML文件类型适配问题

XWPFDocument默认仅支持完整的OOXML格式文件(.docx)或Flat OPC XML格式(将整个docx包打包为单个XML),如果你的XML属于以下两种情况,需要针对性处理:

情况A:XML是docx解压后的单个document.xml

这种XML只是docx包中的核心内容,缺少OOXML所需的包结构和元数据,无法直接用XWPFDocument读取,需先构建完整的OPCPackage:

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

// 构建临时OPCPackage
OPCPackage pkg = OPCPackage.create(new File("temp.docx"));
// 将单个document.xml添加到OOXML包的正确路径
PackagePart docPart = pkg.createPart(
    new org.apache.poi.openxml4j.opc.PackageName("/word/document.xml"),
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
);
// 写入XML内容
try (OutputStream out = docPart.getOutputStream()) {
    FileInputStream in = new FileInputStream("document1.xml");
    byte[] buffer = new byte[1024];
    int len;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
    in.close();
}
// 添加必要的样式关系(避免格式丢失)
pkg.getPartsByName("/word/document.xml").get(0).addRelationship(
    new org.apache.poi.openxml4j.opc.PackageName("/word/styles.xml"),
    PackageRelationshipTypes.STYLES,
    "styles"
);
// 从OPCPackage创建XWPFDocument
XWPFDocument doc1 = new XWPFDocument(pkg);

情况B:XML是Word 2003的WordML格式

这种旧格式XML需先转换为docx格式再处理,可使用Apache POI的WordToXWPFConverter:

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToXWPFConverter;

// 读取WordML文档
HWPFDocument hwpfDoc = new HWPFDocument(new FileInputStream("document1.xml"));
// 转换为XWPFDocument
XWPFDocument doc1 = new XWPFDocument();
WordToXWPFConverter converter = new WordToXWPFConverter(doc1);
converter.processDocument(hwpfDoc);
hwpfDoc.close();

3. 合并逻辑优化

原代码仅复制了Run的基础格式,可补充段落格式复制以保留更多排版信息:

// 复制段落对齐、缩进、间距等格式
newParagraph.setAlignment(p.getAlignment());
newParagraph.setIndentationLeft(p.getIndentationLeft());
newParagraph.setIndentationRight(p.getIndentationRight());
newParagraph.setSpacingBefore(p.getSpacingBefore());
newParagraph.setSpacingAfter(p.getSpacingAfter());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:05:32