2

我需要使用 Apache POI 将 word 文档中的占位符替换为图像。我可以使用 Apache poi 在 word 文档中插入图片。但我不知道如何用图像替换占位符。有人可以帮忙吗?

我知道如果我们通过 docx4j 或其他 API 来做这件事会很容易,我只能使用 Apache poi。

4

1 回答 1

1

它可以完成,但我相信您当前必须插入原始 XML 才能完成它。这个连题“在word文档中插入图片”有基本思路。您可以只使用 POI 需要的库,而不是 dom4j。如果您查看 XWPFRun 上添加图片的方法的源代码,它也在尝试添加原始 XML。但是,如果您使用该方法,它会在写回磁盘时使您的文档不可读。因此,您必须使用 XWPFDocument 级别的方法将图片添加到文档中,该方法返回图片的生成 ID。然后将原始 XML 添加到包含该 ID 的运行中,就像示例链接一样。
我们解决问题的方法是让我们的用户在他们的 Word 文档文件中插入一个占位符图像而不是文本。然后,我们:添加要在文档级别插入的替换图像,使用图像的大小作为标准找到包含占位符图像的运行,然后使用交换的新图像的 ID 获取并替换该运行的 XML。如只要占位符和替换图像的大小相同,就可以了。如果您需要在替换后调整图像的大小,您可以以相同的方式操作 XML 大小值。我更喜欢我们的解决方案,因为它不太容易受到 Word doc XML 格式更改的影响,然后为图片插入您自己的完整 XML。干杯

    InputStream newImageIS = getImageForCorporation(corporationID);

    String relationID = run.getParagraph().getDocument().addPictureData(newImageIS, Document.PICTURE_TYPE_GIF);
    replaceRunImageData(run, relationID);

private void replaceRunImageData(XWPFRun run, String relationID) {
    CTGraphicalObjectData graph = run.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic()
            .getGraphicData();

    String currentGraphicXML = graph.toString();

    String originalID = RegularExpressionUtil.capture("<a:blip r:embed=\"(\\w+)\"", currentGraphicXML);

    String newXML = StringUtils.replace(currentGraphicXML, originalID, relationID);

    try {
        graph.set(XmlToken.Factory.parse(newXML));
    } catch (XmlException e) {
        throw new RuntimeException(e);
    }

    replaced = true;
}

我们通过搜索每个运行的符合以下标准的嵌入图片列表来确定要替换的图像运行。我们尝试使用图像的名称作为标准,但我们发现如果将占位符图像从一个 Word 文档复制到另一台 PC 上的另一个 Word 文档,则会丢失名称。

private boolean isRunForExistingImage(XWPFPicture pic) {
    if (pic == null || pic.getCTPicture() == null || pic.getCTPicture().getSpPr() == null
            || pic.getCTPicture().getSpPr().getXfrm() == null
            || pic.getCTPicture().getSpPr().getXfrm().getExt() == null) {
        return false;
    }

    long x = pic.getCTPicture().getSpPr().getXfrm().getExt().getCx();
    long y = pic.getCTPicture().getSpPr().getXfrm().getExt().getCy();

    return x == 2066925 && y == 590550;
}
于 2014-08-07T16:29:48.853 回答