SpringBoot+若依+图片导出

前言

本文基于若依框架,实现excel中图片导出功能。

自定义导出Excel数据注解

java 复制代码
public enum ColumnType{
        NUMERIC(0), STRING(1), IMAGE(2);
        private final int value;

        ColumnType(int value){
            this.value = value;
        }

        public int value(){
            return this.value;
        }
    }

工具类中设置

java 复制代码
/**
 * 设置单元格信息
 * 
 * @param value 单元格值
 * @param attr 注解相关
 * @param cell 单元格信息
 */
 public void setCellVo(Object value, Excel attr, Cell cell){
        if (Excel.ColumnType.STRING == attr.cellType()){
            String cellValue = Convert.toStr(value);
            // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
            if (StringUtils.startsWithAny(cellValue, FORMULA_STR)){
                cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
            }
            if (value instanceof Collection && StringUtils.equals("[]", cellValue)){
                cellValue = StringUtils.EMPTY;
            }
            cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
        }
        else if (Excel.ColumnType.NUMERIC == attr.cellType()){
            if (StringUtils.isNotNull(value)){
                cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
            }
        }
        else if (Excel.ColumnType.IMAGE == attr.cellType()){
            ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
            String imagePath = Convert.toStr(value);
            if (StringUtils.isNotEmpty(imagePath)){
                byte[] data = ImageUtils.getImage(imagePath);
                getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
                        cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
            }
        }
    }

    /**
     * 获取画布
     */
    public static Drawing<?> getDrawingPatriarch(Sheet sheet){
        if (sheet.getDrawingPatriarch() == null){
            sheet.createDrawingPatriarch();
        }
        return sheet.getDrawingPatriarch();
    }

    /**
     * 获取图片类型,设置图片插入类型
     */
    public int getImageType(byte[] value){
        String type = FileTypeUtils.getFileExtendName(value);
        if ("JPG".equalsIgnoreCase(type)){
            return Workbook.PICTURE_TYPE_JPEG;
        }
        else if ("PNG".equalsIgnoreCase(type)){
            return Workbook.PICTURE_TYPE_PNG;
        }
        return Workbook.PICTURE_TYPE_JPEG;
    }

图片处理工具类

使用字节流,对图片文件进行处理

java 复制代码
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;

/**
 * 图片处理工具类
 *
 * 
 */
public class ImageUtils {
    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);

    public static byte[] getImage(String imagePath) {
        InputStream is = getFile(imagePath);
        try {
            return IOUtils.toByteArray(is);
        } catch (Exception e) {
            log.error("图片加载异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    public static InputStream getFile(String imagePath) {
        try {
            byte[] result = readFile(imagePath);
            result = Arrays.copyOf(result, result.length);
            return new ByteArrayInputStream(result);
        } catch (Exception e) {
            log.error("获取图片异常 {}", e);
        }
        return null;
    }

    /**
     * 读取文件为字节数据
     *
     * @param url 地址
     * @return 字节数据
     */
    public static byte[] readFile(String url) {
        InputStream in = null;
        try {
            // 网络地址
            URL urlObj = new URL(url);
            URLConnection urlConnection = urlObj.openConnection();
            urlConnection.setConnectTimeout(30 * 1000);
            urlConnection.setReadTimeout(60 * 1000);
            urlConnection.setDoInput(true);
            in = urlConnection.getInputStream();
            return IOUtils.toByteArray(in);
        } catch (Exception e) {
            log.error("访问文件异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
}

使用

java 复制代码
@Excel(name = "图片", cellType = Excel.ColumnType.IMAGE)
private String pictureUrls;

结果

相关推荐
Java编程爱好者16 小时前
Condition底层机制剖析:多线程等待与通知机制
后端
Java编程爱好者17 小时前
面试官:你知道 MCP、Skill、Function Call 这三个的区别吗?
后端
狂炫冰美式17 小时前
把手从键盘上抬起来:AI 编程的 3 个不可逆阶段
前端·后端·ai编程
王中阳Go17 小时前
Go 协程池满了怎么办?面试官问我“兜底策略”,我差点挂了……
后端
蝎子莱莱爱打怪18 小时前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes
茶杯梦轩19 小时前
CompletableFuture 在 项目实战 中 创建异步任务 的核心优势及使用场景
服务器·后端·面试
埃博拉酱19 小时前
SMB服务器无法访问?一次PowerShell故障排查演练
后端
大道至简Edward19 小时前
Spring Boot 2.7 + JDK 8 升级到 Spring Boot 3.x + JDK 17 完整指南
spring boot·后端
透明人_x19 小时前
OpenClaw安装
人工智能·后端
程序员清风19 小时前
用了三年AI,我总结出高效使用AI的3个习惯!
java·后端·面试