使用Apache POI从所有Excel工作表中读取图像

时间:2017-08-02 23:54:16

标签: excel image apache-poi

我正在尝试将所有工作表中的所有图像从现有的Excel文件复制到新的Excel文件中。为此,我从现有的excel文件中读取所有工作表,并将图像复制到新的excel文件中。以下代码访问所有工作表并尝试将所有图像复制到新工作表。

    public static void modifyExcelFile(XSSFWorkbook xssfWorkbook) throws InvalidFormatException, IOException, XmlException{
    String newFileName = "outputexcelfile.xlsx";
    XSSFWorkbook dest = new XSSFWorkbook("test.xlsx");

    int numSheets = xssfWorkbook.getNumberOfSheets();

    // clone the template sheet additional number of times required
    for(int i=1; i<numSheets; i++){
        dest.cloneSheet(0);
    }

    for(int i=0; i<numSheets; i++) {
        XSSFSheet destSheet = dest.getSheetAt(i);
        dest.setSheetName(i, xssfWorkbook.getSheetName(i));

        XSSFSheet sheet = xssfWorkbook.getSheetAt(i);
        // copy images
        System.out.println("Copying images ...");
        copyImages(sheet, destSheet);

    }

    writeFile(dest, newFileName);

}

test.xlsx是只有一张工作表的模板文件。以下copyImages函数尝试将所有图像从一个工作表复制到另一个工作表。

    public static void copyImages(XSSFSheet from, XSSFSheet to) throws IOException, XmlException, InvalidFormatException{
    Drawing drawingPatriarch = to.createDrawingPatriarch();
    XSSFWorkbook destWorkbook = to.getWorkbook();

    // Add image
    for (POIXMLDocumentPart pdp : from.getRelations()) {
        if (!XSSFRelation.DRAWINGS.getRelation().equals(pdp.getPackageRelationship().getRelationshipType())) continue;

        PackagePart drawPP = pdp.getPackagePart();
        WsDrDocument draw = WsDrDocument.Factory.parse(drawPP.getInputStream());


        for (CTTwoCellAnchor twoAnc : draw.getWsDr().getTwoCellAnchorList()) {
            String picId = twoAnc.getPic().getBlipFill().getBlip().getEmbed();
            PackageRelationship pr = drawPP.getRelationship(picId);
            PackagePart imgPP = drawPP.getRelatedPart(pr);

            System.out.println(imgPP.getPartName() + ": contentType: " + imgPP.getContentType() + " size: " + imgPP.getSize()
                    + ": picId: " + picId
                    +" - Col1: "+twoAnc.getFrom().getCol()
                    +" - Row1: "+twoAnc.getFrom().getRow()
                    +" - Col2: "+twoAnc.getTo().getCol()
                    +" - Row2: "+twoAnc.getTo().getRow()
            );

            // skip the logo
            if(twoAnc.getFrom().getCol()==0 && twoAnc.getFrom().getRow()==0)
                continue;

            try {
                InputStream is = imgPP.getInputStream();
                byte[] bytes = IOUtils.toByteArray(is);
                int pictureIdx = destWorkbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
                is.close();

                CreationHelper helper = destWorkbook.getCreationHelper();

                //add a picture shape
                ClientAnchor anchor = helper.createClientAnchor();
                //set top-left corner of the picture,

                anchor.setCol1(twoAnc.getFrom().getCol());
                anchor.setRow1(twoAnc.getFrom().getRow());
                anchor.setRow2(twoAnc.getTo().getRow());
                anchor.setCol2(twoAnc.getTo().getCol());
                Picture pict = drawingPatriarch.createPicture(anchor, pictureIdx);

            }catch(IOException ioEx){
                System.out.println("Failed to add icons. Details: " + ioEx.getMessage());
            }

        }
    }
}

但如果我运行代码,它只能成功复制第一张图片中的图像。对于所有其他工作表,图像不存在。代码运行成功,没有任何错误。任何帮助是极大的赞赏。谢谢!

1 个答案:

答案 0 :(得分:0)

只需添加pict.resize(); Picture pict = ...后的函数调用修复了问题。因此修改后的代码如下所示:

   Picture pict = drawingPatriarch.createPicture(anchor, pictureIdx);
   pict.resize();

如果没有resize()调用,不确定为什么它不起作用。