21xrx.com
2025-04-20 09:59:21 Sunday
文章检索 我的文章 写文章
Java 实现 Excel 导出图片并进行压缩
2023-06-15 20:09:01 深夜i     25     0
Java Excel 图片导出 压缩

在 Java 开发中,经常需要对 Excel 文档进行操作,其中一个常见需求就是将 Excel 中的图片导出。本文将介绍如何使用 Java 代码实现 Excel 导出图片,并对图片进行压缩。

本文所用的开发环境为 Eclipse,导入的 jar 包为以下两个:

- poi-ooxml-3.17.jar

- poi-ooxml-schemas-3.17.jar

首先,我们需要在 Excel 中插入一张图片。插入图片的方式为:在 Excel 中选择一个单元格,然后点击“插入”->“图片”,选择一张本地图片即可。

接下来,我们使用以下代码实现图片的导出:

FileOutputStream out = null;
try {
  out = new FileOutputStream("D:/test.png");
  Drawing drawing = sheet.getDrawingPatriarch();
  if (drawing != null) {
    List
  list = drawing.getShapes();
 
    for (XSSFShape shape : list) {
      if (shape instanceof XSSFPicture) {
        XSSFPicture pic = (XSSFPicture) shape;
        XSSFClientAnchor anchor = pic.getClientAnchor();
        if (anchor.getRow1() >= firstRow && anchor.getRow2() <= lastRow) { // firstRow 和 lastRow 分别为需要导出的图片所在的第一行和最后一行
          byte[] data = pic.getPictureData().getData();
          out.write(data);
        }
      }
    }
  }
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} finally {
  try {
    if (out != null) {
      out.close();
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

代码中,首先创建了一个 FileOutputStream 对象,用于将图片数据写入本地文件,然后获取 Excel 中的 Drawing 对象,通过遍历 Drawing 中的所有 Shape,找到其中类型为 XSSFPicture 的 Shape,再通过该 Shape 的 getClientAnchor() 方法获取图片所占用的单元格位置,并根据需求进行过滤,最后调用 XSSFPicture 的 getPictureData() 方法获取图片的二进制数据,并写入本地文件。

接下来,我们需要对导出的图片进行压缩。使用 Java 自带的 ImageIO 类对图片进行压缩,如下:

Image src = ImageIO.read(new File("D:/test.png"));
// 压缩后的宽度和高度
int width = 800;
int height = 600;
// 获取原始图片宽度和高度
int originWidth = src.getWidth(null);
int originHeight = src.getHeight(null);
// 计算压缩比例
double ratio = 1;
if (originWidth > width || originHeight > height) {
  double ratio1 = (double) width / (double) originWidth;
  double ratio2 = (double) height / (double) originHeight;
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
}
// 生成压缩后的图片
BufferedImage img = new BufferedImage((int) (originWidth * ratio), (int) (originHeight * ratio), BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(src, 0, 0, (int) (originWidth * ratio), (int) (originHeight * ratio), null);
g.dispose();
ImageIO.write(img, "jpg", new File("D:/test_compress.jpg")); // 压缩后的图片格式为 jpg

代码中,首先使用 ImageIO 类读取之前导出的图片,然后计算出图片压缩比例,并生成相应大小的 BufferedImage 对象,再将原始图片绘制到该 BufferedImage 对象中,最后使用 ImageIO 类将该 BufferedImage 对象写入另一个本地文件中,即为压缩后的图片。

  
  

评论区

请求出错了