对此进行了一些研究,似乎过去存在与此相关的错误,我不确定它们是否在最新版本中得到了解决。
我正在阅读docx模板,做一些mod并输出它。我正在复制文档的所有元素,除了位图,位图应该包含文本的标记,“此图像当前无法显示”。我做了一些事情。
将位图从一个文档复制到另一个文档的推荐方法是什么?
我可以获得如下图像:
列出piclist = template.getAllPictures();
XWPFPictureData picture =(XWPFPictureData)piclist.get(i);
但我不确定如何将其复制到我的新文档中。
我尝试过从文件中添加单个位图的测试,此代码会创建一个Word文档,该文档会出错并无法加载到Word中:
InputStream pic = new FileInputStream(“filename.gif”);
outputDoc.addPictureData(pic,outputDoc.PICTURE_TYPE_GIF);
任何帮助非常感谢。 Apache-POI给我留下了非常深刻的印象。
答案 0 :(得分:2)
很晚才回答,但谁知道.. 如果要将一个文档的图片复制到另一个文档,请尝试以下操作:
public void copyAllImages( XWPFDocument sourceDocument, XWPFDocument targetDocument ) {
Map<String, Integer> extractedImages = new HashMap<String, Integer>();
XWPFPictureData pictureData = null;
// 1. Writing all found images to the disk (to the same folder as your source document)
for ( XWPFParagraph par : sourceDocument.getParagraphs() ) {
for ( XWPFRun run : par.getRuns() ) {
for ( XWPFPicture picture : run.getEmbeddedPictures() ) {
pictureData = picture.getPictureData();
byte[] img = pictureData.getData();
String fileName = pictureData.getFileName();
int imageFormat = pictureData.getPictureType();
writeByteArrayToFile( img, fileName );
extractedImages.put( fileName, imageFormat );
}
}
}
// 2. Writing images from the disk to the final document,
// creating 1 new paragraph with 1 run for each image.
for ( String imageFileName : extractedImages.keySet() ) {
XWPFParagraph newParagraph = targetDocument.createParagraph();
XWPFRun newRun = newParagraph.createRun();
copyImageToRun( imageFileName, newRun, extractedImages.get( imageFileName ) );
}
}
private static void writeByteArrayToFile( byte[] byteArray, String fileName ) {
FileOutputStream out = null;
try {
out = new FileOutputStream( new File( fileName ) );
out.write( byteArray );
} catch ( Exception e ) {
e.printStackTrace();
} finally {
try {
out.close();
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
private void copyImageToRun( String imageFileName, XWPFRun run, int format ) {
run.setText( imageFileName );
run.addBreak();
try {
run.addPicture( new FileInputStream( imageFileName ), format, imageFileName,
Units.toEMU( 200 ), Units.toEMU( 200 ) ); // 200x200 pixels
} catch ( Exception e ) {
e.printStackTrace();
}
run.addBreak( BreakType.PAGE );
}
因此,您只需要两个XWPFDocument对象,将它们传递给第一个函数(copyAllImages),然后像往常一样使用document.write(out)
保存这些文档。
根据您的需要,您还可以添加到第1步代码,该代码将复制段落的所有内容(而不仅仅是图像)。可能会跳过将图像写入磁盘,将pictureData直接插入到新创建的运行中。但是,我没有设法让它工作(图像根本没有出现)。但是使用两步法,它最终给出了结果。
希望它有所帮助!
P.S。现在的问题是使用哪个SIZE图像?有一会儿我只看到了addPicture
函数,它要求你传递宽度和高度,而且还可以重新缩放你的图像。因此,我们需要一些技巧来提取每个图像在原始文档中所采用的大小(以像素为单位)(并非原始图像大小,因为它可以由用户重新调整)。
灵感来自here。