XPages - docx4j - 用文本替换书签

时间:2014-07-28 15:16:46

标签: java xpages docx4j

我在XPage应用程序中使用docx4j来创建包含XPage内容的Word文档。 Word文档(.docx格式)是基于模板(.dotx格式)创建的。我的.dotx模板中的一个书签如下:

<w:p>
<w:bookmarkStart w:name="Fachkompetenz" w:id="0"/>
<w:bookmarkEnd w:id="0"/>
</w:p>

使用功能

private static 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; 
    }

我可以通过调用

来获取p对象
List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), P.class);

或CTBookmark对象调用

List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), P.class);

但是,一旦我有了这些对象,我就不知道如何添加文本(XPage内容)来替换书签。我已经阅读了尽可能多的关于这个主题的互联网,但找不到任何方法这样做。有没有人有任何建议?

2 个答案:

答案 0 :(得分:2)

如果可以,您可能想重新考虑您的方法。

由于书签是&#34;点&#34;标签,更换内容并不容易。例如,开始标记可以位于顶级段落中,而结束标记位于表格单元格中!

您可能会发现内容控制数据绑定效果更好。

也就是说,假设您的书签开始和结束都是单个p(根据您的示例x​​ml),您可以尝试以下方法:

  1. 找到书签开始元素
  2. 使用getParent访问包含它的列表
  3. 遍历列表以查找结束元素
  4. 替换2个列表条目之间的内容
  5. 在步骤4,您将要插入包含文本(w:t)的新运行(w:r)对象。您可以将示例docx上传到docx4j webapp以生成代码。

    BookmarksReplaceWithText.java可能会有所帮助。

答案 1 :(得分:0)

我设法通过使用以下功能解决了这个问题。它可能在将来需要重构,但现在可以使用:

private void replaceParagraph(String placeholder, String textToAdd, WordprocessingMLPackage template) {


        List<Object> paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class);

        for (Object p : paragraphs) {  
            RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
            new TraversalUtil(p, rt);

            for (CTBookmark content : rt.getStarts()) {  

                if (content.getName().equals(placeholder)) {  

                    List<Object> theList = null;
                    if (content.getParent() instanceof P) {
                    theList = ((ContentAccessor)(content.getParent())).getContent();
                    } else {
                    continue; 
                    }

                    if (textToAdd == ""){ 

                        int index = theList.indexOf(content);
                        Object removed = theList.remove(index);
                    } else {
                    org.docx4j.wml.R run = factory.createR();
                    org.docx4j.wml.Text t2 = factory.createText();
                    run.getContent().add(t2);   
                    t2.setValue(textToAdd);
                    theList.add(0, run); 
                    break;
                    } 
                } 
            }  

        } 

    }
杰森,谢谢你的帮助。