【问题标题】:Get the image size (height and width) in excel files instead of the original size when using Apache POI (for both xls and xlsx files)使用 Apache POI 时获取 excel 文件中的图像大小(高度和宽度)而不是原始大小(对于 xls 和 xlsx 文件)
【发布时间】:2021-09-11 06:10:54
【问题描述】:

目前我们正在开发一个将 xls 和 xlsx 文件转换为 html 的 api,我们希望保留图像(在 excel 文件中的大小和位置)我们希望获得与我们在excel文件(调整大小后)。我们尝试了这种方法:

    for (HSSFPictureData pic : workbook.getAllPictures()) {
    InputStream in = new ByteArrayInputStream(pic.getData());
    BufferedImage image = ImageIO.read(in);
    System.out.println(image.getWidth() + ":" + image.getHeight());
}

但它返回的是原始大小,而不是我们在 excel 文件中调整大小的那个。有什么方法可以实现吗?

【问题讨论】:

  • 我按照您的建议将 poi 版本从 4.1.2 更改为 5.0.0,并且成功了!谢谢!

标签: java html excel image apache-poi


【解决方案1】:

Workbook.getAllPictures() 获取嵌入在Excel 文件中的所有图片文件。这些图片文件包含纯图片数据。所以没有任何方法可以得到缩放后的图片大小。

缩放后的图片包含在图纸中,并固定在图纸的单元格中。因此,要获得缩放的图片,需要遍历图纸以从中获取Pictures。从Picture 可以得到工作表中的锚定位置、锚点的尺寸(也称为缩放大小)以及PictureData

完整示例(使用当前的apache poi 5.0.0 测试和工作,同时适用于HSSFXSSF)。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.ss.util.ImageUtils;
import org.apache.poi.util.Units;

import java.awt.Dimension;

import java.io.FileInputStream;

import java.util.List;

class ExcelGetPicturesWithPositionAndSize {

 public static void main(String[] args) throws Exception {

  //Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelWithImages.xlsx"));
  Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelWithImages.xls"));

  for (Sheet sheet : workbook) {
   String sheetname = sheet.getSheetName();

   Drawing drawing = sheet.getDrawingPatriarch();
   
   List<?> shapes = null;
   if (drawing instanceof XSSFDrawing) {
    shapes = ((XSSFDrawing)drawing).getShapes();
   } else if (drawing instanceof HSSFPatriarch) {
    shapes = ((HSSFPatriarch)drawing).getChildren();
   }
   
   for (Object shape : shapes) {
    if (shape instanceof Picture) {
     Picture picture = (Picture)shape;
     
     String shapename = picture.getShapeName();
     int row = picture.getClientAnchor().getRow1();
     int col = picture.getClientAnchor().getCol1();
System.out.println(
 "Picture with Shapename: " + shapename + 
 " is located sheet: " + sheetname + 
 ", row: " + row + 
 ", col: " + col
 );

     Dimension dimension = ImageUtils.getDimensionFromAnchor(picture);
System.out.println(
 "Picture's size in EMU: width=" + dimension.getWidth() + ", height=" + dimension.getHeight() +
 ", in pixel: width=" + dimension.getWidth()/Units.EMU_PER_PIXEL + ", height=" + dimension.getHeight()/Units.EMU_PER_PIXEL
 ); 
 
     PictureData pictureData =  picture.getPictureData();
System.out.println(
 "Picture's data: bytes=" + pictureData.getData().length +
 ", mime type=" + pictureData.getMimeType() +
 ", suggested file extension=" + pictureData.suggestFileExtension()
 ); 

    }
   } 
  }

  workbook.close();
 }
}

【讨论】:

  • 似乎它会根据单元格的大小。我可以看到我是否将图像(宽度:100 像素,高度:500 像素)放置到包含大量文本的单元格中,宽度 = 1000 像素,当我遵循这种方法时,宽度将为 1000 像素而不是 100 像素跨度>
  • @thang dang:抱歉,无法重现该问题。它适用于我,不受不同单元格大小的影响。
  • 我按照您的建议将 poi 版本从 4.1.2 更改为 5.0.0,并且成功了!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
相关资源
最近更新 更多