Java语言在导出excel功能中添加图片导出
使用到的工具类
java
package com.test.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.longconverter.LongStringConverter;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.ybbsy.travel.framework.common.util.http.HttpUtils;
import com.ybbsy.travel.framework.excel.core.handler.SelectSheetWriteHandler;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* Excel 工具类
*
* @author 骑猪撞地球QAQ
*/
public class ExcelUtils {
/**
* 将列表以 Excel 响应给前端
*
* @param response 响应
* @param filename 文件名
* @param sheetName Excel sheet 名
* @param head Excel head 头
* @param data 数据列表哦
* @param <T> 泛型,保证 head 和 data 类型的一致性
* @throws IOException 写入失败的情况
*/
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
Class<T> head, List<T> data) throws IOException {
// 输出 Excel
EasyExcel.write(response.getOutputStream(), head)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename));
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
return EasyExcel.read(file.getInputStream(), head, null)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.doReadAllSync();
}
}
java
// 导出 Excel
ExcelUtils.write(response, "记录.xls", "数据", VO.class, list);
vo的图片类上面添加如下注解:
@ExcelProperty(value = "照片", converter = ImageConverter.class)
使用的是com.alibaba.excel.annotation.ExcelProperty;
java
package com.test.convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: 骑猪撞地球QAQ
* @CreateTime: 2026-02-13
* @Description: 图片转换器,将图片url转换为excel中的图片
* @Version: 1.0
*/
public class ImageConverter implements Converter<String> {
@Override
public Class<String> supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.EMPTY;
}
@Override
public WriteCellData<?> convertToExcelData(String urlStr, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws Exception {
List<ImageData> imageDataList = new ArrayList<>();
if (StrUtil.isEmpty(urlStr)) {
return new WriteCellData<>(CellDataTypeEnum.STRING);
}
// url是用','分割的,进行切分;todo 此处可根据自己实际情况具体处理
String[] urls = urlStr.split(",");
for (String url : urls) {
try (InputStream inputStream = new URL(url).openStream()) {
// 原始图片读取
BufferedImage srcImage = ImageIO.read(inputStream);
// 预生成缩略图(提升性能)
BufferedImage thumbnail = new BufferedImage(273, 89, BufferedImage.TYPE_INT_RGB);
thumbnail.getGraphics().drawImage(
srcImage.getScaledInstance(273, 89, Image.SCALE_SMOOTH),
0, 0, null
);
// 转换为字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(thumbnail, "JPEG", baos);
ImageData imageData = new ImageData();
imageData.setImage(baos.toByteArray());
imageDataList.add(imageData);
}
}
WriteCellData<?> cellData = new WriteCellData<>();
if (!imageDataList.isEmpty()) {
cellData.setImageDataList(imageDataList);
cellData.setType(CellDataTypeEnum.EMPTY);
} else {
cellData.setStringValue("无图片");
cellData.setType(CellDataTypeEnum.STRING);
}
return cellData;
}
}