Java在导出excel时中添加图片导出

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;
    }
}
相关推荐
csdn2015_1 小时前
MybatisPlus LambdaQueryChainWrapper 联合查询
开发语言·windows·python
好家伙VCC1 小时前
# 发散创新:基于 Go 语言打造高性能服务网格的实践与突破在微服务架构
java·python·微服务·架构·golang
悦悦子a啊1 小时前
CSS 知识点
开发语言·前端·css
匀泪1 小时前
云原生(nginx环境设定)
java·nginx·云原生
Anastasiozzzz2 小时前
ZGC随手记
java
好家伙VCC2 小时前
# BERT在中文文本分类中的实战优化:从模型微调到部署全流程在自然语言处理(NL
java·python·自然语言处理·分类·bert
只会写bug的小李子2 小时前
AI Agent动态规划失效处理:多步执行卡壳时,局部修正远比从头重来更高效
java·开发语言
NGC_66112 小时前
idea中使用git
java·git·intellij-idea
unirst19850072 小时前
搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
开发语言·后端·golang