我需要使用Apache POI将word占位符替换为word文档中的image。我可以使用Apache poi在word文档中插入图片。但我不知道如何用图像替换占位符。有人可以帮忙吗?
我知道如果我们通过docx4j或其他API进行操作会很容易,我只能使用Apache poi。
答案 0 :(得分:1)
可以这样做,但我相信你必须插入原始XML才能完成它。这个相关问题" Insert picture in word document"有基本的想法。您只能使用POI所需的库,而不是dom4j。如果您查看XWPFRun上添加图片的方法的源代码,它也会尝试添加原始XML。但是,如果使用该方法,则在写回磁盘时会使您的doc无法读取。因此,您必须使用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;
}