首页 文章

Java Apache-POI XWPF如何复制或输出位图?

提问于
浏览
1

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

我正在阅读一个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给人留下了非常深刻的印象 .

1 回答

  • 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直接插入到新创建的运行中 . 但是,我没有't manage to make it work (images simply didn'出现) . 但是使用两步法,它最终给出了结果 .

    希望能帮助到你!

    附:现在的问题是使用哪个SIZE图像?有一会儿,我只看到了 addPicture 函数,它要求你传递宽度和高度,而且还可以重新缩放你的图像 . 因此,我们需要一些技巧来提取每个图像在原始文档中所采用的大小(以像素为单位)(不是原始图像大小的nececcarily,因为它可以由用户重新调整) .

    灵感来自here .

相关问题