【问题标题】:Java Apache-POI XWPF how to copy or output bitmaps?Java Apache-POI XWPF 如何复制或输出位图?
【发布时间】:2023-04-04 17:45:01
【问题描述】:

对此进行了一些研究,过去似乎存在与此相关的错误,我不确定它们是否在最新版本中得到解决。

我正在阅读一个 docx 模板,做一些修改并输出它。我正在复制文档的所有元素,除了位图,位图应该包含文本的位置出现一个标记,“当前无法显示此图像”。我已经尝试了几次。

将位图从一个文档复制到另一个文档的推荐方法是什么?

我可以得到如下图片:

List piclist = template.getAllPictures();

XWPFPitureData 图片 = (XWPFPitureData)piclist.get(i);

但我不确定如何将其复制到我的新文档中。

我尝试了从文件中添加单个位图的测试,此代码创建了一个 Word 文档,该文档出现错误并且无法加载到 Word:

InputStream pic = new FileInputStream("filename.gif");

outputDoc.addPictureData(pic, outputDoc.PICTURE_TYPE_GIF);

非常感谢任何帮助。对 Apache-POI 印象深刻。

【问题讨论】:

  • 这看起来不太正确,因为它没有将图片与文档中的任何位置相关联。如果您尝试TestXWPFRun.testAddPicture() 中显示的方法会发生什么?

标签: java apache-poi xwpf


【解决方案1】:

一个很晚的答案,但谁知道.. 如果您想将一个文档的图片复制到另一个文档,请尝试以下操作:

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 步的代码,该代码将复制段落的所有内容(不仅仅是图像)。可能人们可以跳过将图像写入磁盘,将图片数据直接插入到新创建的运行中。但是,我没有设法让它工作(图像根本没有出现)。但是使用两步法,它终于给出了一个结果。

希望对你有帮助!

附:现在的问题是使用哪种尺寸的图像?有一段时间我只看到了addPicture 函数,它要求你传递宽度和高度,而且它可以重新缩放你的图像。所以我们需要一些技巧来提取每个图像在原始文档中的大小(以像素为单位)(不一定是原始图像大小,因为它可以由用户重新缩放)。

灵感来自here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多