【问题标题】:XPages - docx4j - replacing a bookmark with textXPages - docx4j - 用文本替换书签
【发布时间】:2014-07-28 15:16:46
【问题描述】:

我在 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 内容)来替换书签。我已经在互联网上阅读了有关此主题的所有内容,但找不到任何方法。有人有什么建议吗?

【问题讨论】:

    标签: java xpages docx4j


    【解决方案1】:

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

    由于书签是“点”标签,要替换它们的内容并不容易。例如,开始标签可以在顶级段落中,而结束标签可以在表格单元格中!

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

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

    1. 找到书签开始元素
    2. 使用 getParent 访问包含它的列表
    3. 遍历列表以找到结束元素
    4. 替换两个列表条目之间的内容

    在第 4 步,您需要插入包含文本 (w:t) 的新运行 (w:r) 对象。您可以将示例 docx 上传到 docx4j webapp 以生成代码。

    BookmarksReplaceWithText.java 可能会有所帮助。

    【讨论】:

    • 你有任何我可以使用内容控制数据绑定的例子吗?
    • 对于创作时间,请尝试链接在 opendope.org/implementations.html 的 Word 加载项
    • 我只是想在创建文档时将模板中的书签替换为文本。我曾想象这会相对简单,但似乎并非如此!感谢您的建议杰森。
    • 好吧,如果您的书签开始和结束在单个 p 中(根据您的示例 xml),那么它很简单。这取决于您是否可以确定该假设成立。
    【解决方案2】:

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

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

    杰森,谢谢你的帮助。

    【讨论】:

      猜你喜欢
      • 2012-11-10
      • 2013-04-08
      • 2015-07-13
      • 2016-03-24
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2015-10-19
      • 1970-01-01
      相关资源
      最近更新 更多