You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java的Apache POI实现Excel图片适配单元格大小

解决Excel图片无法适配单元格的问题

你遇到的picture.resize无效,本质是锚点类型设置错误,且未正确计算单元格与图片的尺寸匹配关系。要让图片自动适配单元格,需要调整锚点类型并计算缩放比例,以下是修正方案:

问题分析

原代码中设置了ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE,这个类型会让图片固定位置和大小,完全不受单元格尺寸变化影响,自然无法适配单元格。另外,直接调用resize但未基于单元格实际尺寸计算缩放比例,也会导致调整无效。

修正步骤

  1. 修改锚点类型:使用MOVE_AND_RESIZE,让图片随单元格移动并可调整大小。
  2. 计算单元格像素尺寸:POI中列宽和行高的单位不是直接像素,需要转换。
  3. 计算图片缩放比例:根据图片原始宽高和单元格可用区域,计算等比例缩放的比例,避免拉伸变形。
  4. 应用缩放:通过Picture.resize或调整锚点的偏移量来设置图片大小。

修正后的代码

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public static void main(String[] args) throws IOException {
    Workbook workbook = new HSSFWorkbook();
    Sheet sheet = workbook.createSheet("My Sheet2");
    
    // 创建单元格并设置内容
    Cell cell1 = sheet.createRow(0).createCell(0);
    Cell cell2 = sheet.createRow(1).createCell(0);
    cell1.setCellValue("this is Image1");
    cell2.setCellValue("this is Image2");
    
    // 读取图片
    InputStream inputStream1 = new FileInputStream("src/main/resources/Image1.png");
    InputStream inputStream2 = new FileInputStream("src/main/resources/Image2.png");
    byte[] inputImage1 = IOUtils.toByteArray(inputStream1);
    byte[] inputImage2 = IOUtils.toByteArray(inputStream2);
    int inputImagePicture1 = workbook.addPicture(inputImage1, Workbook.PICTURE_TYPE_PNG);
    int inputImagePicture2 = workbook.addPicture(inputImage2, Workbook.PICTURE_TYPE_PNG);
    inputStream1.close();
    inputStream2.close();
    
    CreationHelper helper = workbook.getCreationHelper();
    Drawing<?> drawing = sheet.createDrawingPatriarch();
    
    // 设置单元格尺寸(单位转换:列宽1单位=1/256字符宽度,行高1单位=1/20点)
    int columnWidthInChars = 25;
    sheet.setColumnWidth(1, columnWidthInChars * 256);
    short rowHeightInPoints = 60;
    cell1.getRow().setHeight((short)(rowHeightInPoints * 20));
    cell2.getRow().setHeight((short)(rowHeightInPoints * 20));
    
    // 处理第一张图片
    ClientAnchor anchor1 = helper.createClientAnchor();
    // 设置锚点类型为随单元格移动并调整大小
    anchor1.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
    // 图片定位在第1列到第2列,第0行到第1行
    anchor1.setCol1(1);
    anchor1.setCol2(2);
    anchor1.setRow1(0);
    anchor1.setRow2(1);
    // 图片边缘与单元格边缘留少量空白(可选)
    anchor1.setDx1(10);
    anchor1.setDy1(10);
    anchor1.setDx2(-10);
    anchor1.setDy2(-10);
    
    Picture picture1 = drawing.createPicture(anchor1, inputImagePicture1);
    // 获取图片原始尺寸
    int imgWidth = picture1.getImageDimension().width;
    int imgHeight = picture1.getImageDimension().height;
    
    // 计算单元格的实际像素尺寸(列宽转换:1字符宽度≈8像素,可根据字体调整;行高转换:1点≈1.333像素)
    int cellWidth = columnWidthInChars * 8;
    int cellHeight = rowHeightInPoints * 3 / 2;
    
    // 计算等比例缩放比例
    double scale = Math.min((double)cellWidth / imgWidth, (double)cellHeight / imgHeight);
    // 应用缩放
    picture1.resize(scale);
    
    // 处理第二张图片,逻辑同上
    ClientAnchor anchor2 = helper.createClientAnchor();
    anchor2.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
    anchor2.setCol1(1);
    anchor2.setCol2(2);
    anchor2.setRow1(1);
    anchor2.setRow2(2);
    anchor2.setDx1(10);
    anchor2.setDy1(10);
    anchor2.setDx2(-10);
    anchor2.setDy2(-10);
    
    Picture picture2 = drawing.createPicture(anchor2, inputImagePicture2);
    imgWidth = picture2.getImageDimension().width;
    imgHeight = picture2.getImageDimension().height;
    scale = Math.min((double)cellWidth / imgWidth, (double)cellHeight / imgHeight);
    picture2.resize(scale);
    
    // 自动调整第一列的宽度以适配文本
    sheet.autoSizeColumn(0);
    
    try(FileOutputStream saveExcel = new FileOutputStream("target/newWorkbook.xls")) {
        workbook.write(saveExcel);
    }
}

关键说明

  • 锚点类型:MOVE_AND_RESIZE是核心,确保图片与单元格绑定,单元格大小变化时图片也会跟着调整。
  • 尺寸转换:POI的列宽和行高单位需要转换成像素才能和图片尺寸匹配,这里的转换值是通用近似值,若使用特殊字体可根据实际情况调整。
  • 等比例缩放:通过Math.min取宽高比例的最小值,保证图片完整显示且不变形。

内容的提问来源于stack exchange,提问作者Prabhanshu gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:16:06