【问题标题】:Word document mergers using Apache POI generating ' file corrupt error' after mergerWord 文档合并使用 Apache POI 合并后生成“文件损坏错误”
【发布时间】:2020-04-11 13:07:00
【问题描述】:

大家好,请注意,这似乎与previous post 有类似的问题——但那里发布的解决方案并不能解决我的错误。

我的要求是,

1) 加载多个word文档和 2)将word文档合并为一个word文档。

各位,我已经能够使用 Apache POI API 合并文件了。但是,一旦我尝试打开合并的文件,Microsoft Word 会生成以下错误,

“Word 在 final.docx 中发现不可读的内容。是否要恢复此文档的内容?如果您信任此文档的来源,请单击是。”

请注意,在我单击“是”后,Microsoft Word 能够完全恢复文件;结果文件已正确合并。但是,如果可能的话,我想消除文件损坏错误警告。

我的合并类代码清单,

package rx.reportgenerator.gh;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
/**
 *
 * @author kwadwooteng-amoko
 */
public class WordMerge {



    private final OutputStream merger;
    private final List<InputStream> docs;
    private XWPFDocument first;



    public WordMerge(OutputStream result) {
        this.merger = merger;
        docs = new ArrayList<>();
    }

    public void add(InputStream document) throws Exception{            
        docs.add(document);
        OPCPackage src = OPCPackage.open(document);
        XWPFDocument xDocument = new XWPFDocument(src);     
        XWPFParagraph paragraph = xDocument.createParagraph();
        paragraph.setPageBreak(true);
        if(docs.size() == 1){
            first = xDocument;
        } else {            
            CTBody xBody = xDocument.getDocument().getBody();
            first.getDocument().addNewBody().set(xBody);            
        }        
    }

    public void doMerge() throws Exception{
        first.write(merger);                
    }

    public void close() throws Exception{
        merger.flush();
        merger.close();
        for (InputStream input : inputs) {
            input.close();
        }
    }   

}

据我所知,我的库依赖项都是最新的:

不知道为什么代码会产生错误。尽管合并准确地完成了。你能帮帮我吗

【问题讨论】:

  • 您的代码所做的是将多个body 元素附加到/word/document.xml。但是合并Word*.docx文件并不是那么简单。 body 元素可以在/word/numbering.xml 中引用不同的编号,在/word/styles.xml 中引用不同的样式,在/word/fontTable.xml 中引用不同的字体,...,在/word/media/ 中引用不同的媒体等等。因此,错误导致在该 *.docx 文件中不存在的附加 body 元素之一中的引用。那是因为您没有合并其他文档部分,也没有更新/word/_rels/document.xml.rels
  • 好的,谢谢。我正在做的是合并一组文档,这些文档都基于相同的模板。样式相同,编号机制相同,字体也相同。这仍然会影响文档吗
  • “这还会影响文档吗?”:嗯,看起来,因为你遇到了那个错误。如前所述,简单地将多个 body 元素附加到 /word/document.xmlnot 合并 *.docx 文件。 Word 本身不会将多个body 元素附加到一个document。在CT_DocumentOffice Open XML XML Schema 中,body 元素具有maxOccurs="1" 集。那么不同的媒体、图表……呢?你怎么能确定没有人添加不同的编号、字体或其他内容?
  • 谢谢。那么问题是否存在
  • 遍历源文档的所有IBodyElements 并获取它们所需的设置。然后将这些IBodyElements 作为新元素添加到目标文档的正文中并设置设置。一项非常复杂和具有挑战性的任务。

标签: java ms-word apache-poi docx netbeans-8


【解决方案1】:

不确定这个问题是否已经解决。但是,由于我刚刚遇到了与此错误相同的问题,因此我想与其他人分享我的解决方案:

在word文件中使用apache poi生成空表单元格时,也会出现同样的错误。出于某种原因,word 不喜欢那些空单元格。在我为表中的所有空单元格添加 .addParagraph() 后,错误消失了。来源:https://bz.apache.org/bugzilla/show_bug.cgi?id=65292

【讨论】:

    猜你喜欢
    • 2018-12-06
    • 1970-01-01
    • 2019-02-02
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多