3

我有一个 Word 文件,如下所示:

您不需要了解内容,只需看一下我的占位符<env><applikationsabkürzung>. 这些占位符有 10 页,现在我应该用其他内容替换它们。黑色和黄色方框是公司图片,我不会分享。

现在我开始阅读整个docx4j 文档并在一段时间后生成以下代码:

public void manipulateWord(String path, String env, String appl) {
    try {
        WordprocessingMLPackage wpml = WordprocessingMLPackage.load(new File(path));

        MainDocumentPart mdp = wpml.getMainDocumentPart();

        List<Object> content = mdp.getContent();

        // Include all Strings to replace
        HashMap<String, String> mappings = new HashMap<String, String>();
        mappings.put("<env>", env);
        mappings.put("<applikationsabkürzung>", appl);

        for (Object object : content) {
            Text textElement = (Text) object;
            String textToReplace = textElement.getValue();
            if (mappings.keySet().contains(textToReplace)) {
                textElement.setValue(mappings.get(textToReplace));
            }
        }

        wpml.save(new File("C:\\Users\\kristina\\Desktop\\outputfile.docx"));

    } catch (Docx4JException e) {
        LOG.error(e);
    }

一些解释:

  • String path就是上图中文件的路径
  • String env是应该替换的值<env>
  • String appl是应该替换的值<applikationsabkürzung>

但是当我运行该方法时,什么也没有发生,我的控制台只打印一些信息。如果它们很重要,我会编辑帖子,但我不这么认为。

那么我的错在哪里?它会那样工作吗?不久前,我绝望了……

4

1 回答 1

3

MainDocumentPart.getContent()将返回主文档流中的所有 OpenXml 组件(如页眉和页脚有自己的元素)。您的代码假设结果List<Object> content将是Text元素的集合,但不一定如此。例如,一个典型的(简单)文档结构是这样的:

P  // Paragraph element
    -> R  // Run element
        -> Text  // Text element

......所以getContent(),很可能,一开始就会吐出一大堆P物体。

有几种方法可以遍历 docx4 文件——有关更多信息,请参见主 docx4j 站点——但下面的方法中显示了一种方法。您可以MaindocumentPart作为第一个对象传入,也可以Text.class作为要搜索的对象类型传入。这应该有助于识别Text包含您的映射值之一的所有元素:

public 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;
}
于 2013-08-23T18:21:24.637 回答