【问题标题】:how to insert an element using docx4j如何使用 docx4j 插入元素
【发布时间】:2014-05-07 00:56:43
【问题描述】:

我有一个 .docx 文档,顶部有一些表格。这些包含需要替换的文本占位符,效果很好。但是,这些表之一需要重复并填充不同的值。我能够深度复制表格并将其添加到文档的末尾,但我不知道如何将其插入到适当的位置。我尝试在模板表的索引处添加副本,但这会在 LibreOffice 中出现“未知图形格式”错误,即使我删除了原始文件:

template.getMainDocumentPart().getContent().add(index, copy);
template.getMainDocumentPart().getContent().remove(table);

有什么想法吗?

编辑:

我在 Windows 框上创建了一个示例项目,但现在我得到一个 IndexOutOfBoundsException,因为该表不存在于主文档部分内容列表中(它被包裹在一个 JAXBElement 中)。请参阅下面的代码,这需要一个包含三个单独表格的文档,其中第一个表格中有一个单元格,其中包含文本“first”等。

package test;

import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Text;

import javax.xml.bind.JAXBElement;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Test {

    private WordprocessingMLPackage template;

    public void getTemplate(String name) {
        try {
            template = WordprocessingMLPackage.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(name));
        } catch (Exception e) {
        }
    }

    private List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
        List<Object> result = new ArrayList<Object>();
        if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
        if (obj.getClass().equals(toSearch))
            result.add(obj);
        else if (obj instanceof ContentAccessor) {
            List<?> children = ((ContentAccessor) obj).getContent();
            for (Object child : children) {
                result.addAll(getAllElementFromObject(child, toSearch));
            }
        }
        return result;
    }

    public void duplicate() {
        List<Object> tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class);
        for (Object table : tables) {
            List list = template.getMainDocumentPart().getContent();
        // Workaround for table being wrapped in JAXBElement
        // This simple code assumes table is present and top level
        int index = 0;
        for (Object o : list) {
            if (XmlUtils.unwrap(o)== table) {
                break;
            }
            index++;
        }
        List<Object> texts = getAllElementFromObject(table, Text.class);
        for (Object t : texts) {
            Text text = (Text) t;
            if (text.getValue().contains("second")) {
                Tbl copy = (Tbl) XmlUtils.deepCopy(table);
                template.getMainDocumentPart().getContent().add(index, copy);
                System.out.println(template.getMainDocumentPart().getXML());
                return;                    
            }
        }           }
    }

    public void save() {
        try {
            template.save(new File("out.docx"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.getTemplate("test.docx");
        test.duplicate();
        test.save();
    }

}

我不确定如何最好地处理这个问题。

【问题讨论】:

    标签: java docx docx4j


    【解决方案1】:

    听起来桌子里可能有图片?您是从其他 docx 中复制的吗?

    如果您只克隆了当前主文档部分的内容,并根据您的问题插入,那很好,不会导致您报告的错误。

    【讨论】:

    • 没有任何图像。现在我只是想复制一张表,所以不涉及第二份文件。我来看看生成的xml。
    • 使用 IndexOutOfBoundsException 的简单解决方法编辑了您的代码;它工作正常。 LibreOffice 中的任何“未知图形格式”错误要么无关,要么具有误导性。
    猜你喜欢
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    相关资源
    最近更新 更多