有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Merge word(docx)文档与DOCX4J:如何复制图像?

我需要将两个(或更多个)word文档(docx)与docx4j合并。我的合并方法是从一个文档中复制所有正文子项并附加到另一个文档中。然后,我只是重新安排一些东西。我已经用了两年了,就我的目的而言,它很好

下面是一个简单的例子:

首先。docx=简单文本
第二docx=简单文本+图像

    File first = new File("first.docx");
    File second = new File("second.docx");

    WordprocessingMLPackage f = WordprocessingMLPackage.load(first);
    WordprocessingMLPackage s = WordprocessingMLPackage.load(second);

    List body = s.getMainDocumentPart().getJAXBNodesViaXPath("//w:body", false);
    for(Object b : body){
        List filhos = ((org.docx4j.wml.Body)b).getContent();
        for(Object k : filhos)
            f.getMainDocumentPart().addObject(k);
    }

    List blips = s.getMainDocumentPart().getJAXBNodesViaXPath("//a:blip", false);
    for(Object el : blips){
        try {
            CTBlip blip = (CTBlip) el;

            RelationshipsPart parts = s.getMainDocumentPart().getRelationshipsPart();
            Relationship rel = parts.getRelationshipByID(blip.getEmbed());

            RelationshipsPart docRels = f.getMainDocumentPart().getRelationshipsPart();

            rel.setId(null);
            docRels.addRelationship(rel);
            blip.setEmbed(rel.getId());

            f.getMainDocumentPart().addTargetPart(s.getParts().getParts().get(new PartName("/word/"+rel.getTarget())));

        } catch (Exception ex){}
    }

    File saved = new File("saved.docx");
    f.save(saved);

    Desktop.getDesktop().open(saved);

问题是我什么时候存钱。这些错误出现了:

    org.docx4j.openpackaging.exceptions.Docx4JException: Failed to add parts from relationships of /
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:390)
at org.docx4j.openpackaging.io3.Save.save(Save.java:192)
at org.docx4j.openpackaging.packages.OpcPackage.save(OpcPackage.java:441)
at org.docx4j.openpackaging.packages.OpcPackage.save(OpcPackage.java:406)

Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Failed to add parts from relationships of /word/document.xml
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:390)
at org.docx4j.openpackaging.io3.Save.savePart(Save.java:442)
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:385)
... 4 more

Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Failed to put binary part
at
org.docx4j.openpackaging.io3.stores.ZipPartStore.saveBinaryPart(ZipPartStore.java:398)
at org.docx4j.openpackaging.io3.Save.savePart(Save.java:418)
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:385)
... 6 more

Caused by: java.io.IOException: part '/word/media/image1.jpg' not found
at
org.docx4j.openpackaging.io3.stores.ZipPartStore.saveBinaryPart(ZipPartStore.java:361)
... 8 more

Exception in thread "main" org.docx4j.openpackaging.exceptions.Docx4JException: Failed to add parts from relationships of /
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:390)
at org.docx4j.openpackaging.io3.Save.save(Save.java:192)
at org.docx4j.openpackaging.packages.OpcPackage.save(OpcPackage.java:441)
at org.docx4j.openpackaging.packages.OpcPackage.save(OpcPackage.java:406)

Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Failed to add parts from relationships of /word/document.xml
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:390)
at org.docx4j.openpackaging.io3.Save.savePart(Save.java:442)
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:385)
... 4 more

Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Failed to put binary part
at
org.docx4j.openpackaging.io3.stores.ZipPartStore.saveBinaryPart(ZipPartStore.java:398)
at org.docx4j.openpackaging.io3.Save.savePart(Save.java:418)
at org.docx4j.openpackaging.io3.Save.addPartsFromRelationships(Save.java:385)
... 6 more

Caused by: java.io.IOException: part '/word/media/image1.jpg' not found
at
org.docx4j.openpackaging.io3.stores.ZipPartStore.saveBinaryPart(ZipPartStore.java:361)
... 8 more

这里有解决问题的线索吗

1)我不想要,这太糟糕了。 2) docx4j的商业(企业)版本可以做到这一点,但我正在寻找自由和开放源码软件

谢谢


共 (2) 个答案

  1. # 1 楼答案

    在将光点添加到f之前操纵s中的光点。换句话说,交换for循环的顺序

    然后在你的光点操作中,你需要做的是:

    • 获得感兴趣的部分
    • Rel Rel=f.getMainDocumentPart()。addTargetPart
    • 从rel更新blip中的relId。盖蒂

    现在,将s的内容添加到f中。您可以使用addAll来完成这项工作,而无需嵌套循环。而且只有一个身体对象,所以不需要外部循环

    显然,这个答案仅限于处理CTBlip,然后只处理嵌入的CTBlip。合并docx文件的完整解决方案还有很多

    注意:我在docx4j Enterprise中编写了合并文档的代码

  2. # 2 楼答案

    在这里,我们结合了一个真正的工作代码:

    List<Object> blips = s.getMainDocumentPart().getJAXBNodesViaXPath("//a:blip", false);
    for (Object el : blips) {
        try {
    
            CTBlip blip = (CTBlip) el;
            RelationshipsPart parts = s.getMainDocumentPart().getRelationshipsPart();
            Relationship rel = parts.getRelationshipByID(blip.getEmbed());
            Part part = parts.getPart(rel);
    
            if (part instanceof ImagePngPart)
                System.out.println(((ImagePngPart) part).getBytes());
            if (part instanceof ImageJpegPart)
                System.out.println(((ImageJpegPart) part).getBytes());
            if (part instanceof ImageBmpPart)
                System.out.println(((ImageBmpPart) part).getBytes());
            if (part instanceof ImageGifPart)
                System.out.println(((ImageGifPart) part).getBytes());
            if (part instanceof ImageEpsPart)
                System.out.println(((ImageEpsPart) part).getBytes());
            if (part instanceof ImageTiffPart)
                System.out.println(((ImageTiffPart) part).getBytes());
    
            Relationship newrel = f.getMainDocumentPart().addTargetPart(part, AddPartBehaviour.RENAME_IF_NAME_EXISTS);
    
            blip.setEmbed(newrel.getId());
            f.getMainDocumentPart().addTargetPart(s.getParts().getParts().get(new PartName("/word/" + rel.getTarget())));
    
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    

    这个片段在docx中从s文档到f文档拍摄带有装饰的图像。 Sysouts之所以需要,是因为我忘记了一个原因,但没有它,lib无法确定图像的mime