简体   繁体   English

如何使用docx4j插入元素

[英]how to insert an element using docx4j

I have a .docx document with some tables at the top. 我有一个.docx文档,顶部有一些表。 These contain text placeholders that need replaced, which works fine. 这些包含需要替换的文本占位符,效果很好。 However, one of these tables needs to be repeated and filled with different values. 但是,这些表之一需要重复并用不同的值填充。 I am able to deep copy the table and add it to the end of the document, but I don't know how to insert it at the appropriate location. 我能够深度复制表格并将其添加到文档的末尾,但是我不知道如何将其插入适当的位置。 I tried adding the copy at the index of the template table, but that gives a "unknown graphics format" error in LibreOffice, even when I remove the original: 我尝试将副本添加到模板表的索引处,但是即使删除了原始文档,LibreOffice也会出现“未知图形格式”错误:

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

Any thoughts? 有什么想法吗?

Edit: 编辑:

I created an example project on a Windows box, but now I get a IndexOutOfBoundsException as the table is not present in the main document part content list (it is wrapped in a JAXBElement instead). 我在Windows盒子上创建了一个示例项目,但是现在我得到了IndexOutOfBoundsException,因为该表不存在于主文档部件内容列表中(而是包装在JAXBElement中)。 See code below, this takes a document with three separate tables where the first one has a cell with the text "first" in it, etc. 参见下面的代码,这将获得一个包含三个单独表的文档,其中第一个表具有一个单元格,其中带有文本“ 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();
    }

}

I'm not sure how to best deal with this. 我不确定如何最好地处理这个问题。

Sounds like the table might have images in it? 听起来桌子上可能有图像吗? Are you copying it from another docx? 您要从其他docx复制吗?

If you have only cloned content of the current main document part, and inserted as per your question, that would be fine and won't cause the error you report. 如果您仅克隆了当前主文档部分的内容,并根据您的问题进行了插入,那很好,不会导致您报告错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM