EasyExcel根据自定义模板导出Excel(包含图片、表格)

使用EasyExcel根据模板导出excel,包含图片、表格

提示:其实使用EasyExcel根据模板导出一个excel并不难,难点在于指定图片的位置


文章目录

  • 使用EasyExcel根据模板导出excel,包含图片、表格
  • 前言
  • 一、Controller
  • 二、ServiceImpl
  • 三、TemplateExcelUtils
  • 四、xlsx模板路径
  • 五、模板内容制作
  • 六、导出内容展示
  • 总结


前言

提示:EasyExcel请使用 3.0 以上版本,我这里使用的是 3.0.2 版本:

<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>easyexcel</artifactId>
     <version>3.0.2</version>
 </dependency>

提示:我的需求是,前端页面有个 echarts 图,需要导出到excel,当然前端也可以直接导出图片;但是我是需要将图片插入到模板指定位置,模板中还有其他内容,所以需要前端先将图片传给我,后台再写入到模板中

一、Controller

@ApiOperation(value = "导出excel")
@PostMapping("/export")
public void exportExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response, @Valid FwFloodForecastResultExportDto dto) {
    service.export(file, response, dto);
}

二、ServiceImpl

ResourceUtil工具类使用的是开源的java工具包cn.hutool,具体的pom中的maven依赖坐标,自行百度

Map<String, Object> map = new HashMap<>();
map.put("startW", 33);
map.put("avgRain", 35);
map.put("pa", 36);
map.put("forecastTime", "12月10日12时03分");
map.put("maxFlow", 37);
map.put("maxFlowTime", "11月27日20时");
map.put("maxOtq", 38);
map.put("maxOtqTime", "11月29日2时");
map.put("maxW", 39);
map.put("maxWTime", "11月27日20时");

List<Map<String, Object>> list = new ArrayList<>();
Map<String, Object> m1 = new HashMap<>();
m1.put("month", "11");
m1.put("day", "3");
m1.put("hour", "10");
m1.put("rain", 40);
m1.put("inq", 41);
m1.put("otq", 42);
Map<String, Object> m2 = new HashMap<>();
m2.put("month", "12");
m2.put("day", "3");
m2.put("hour", "10");
m2.put("rain", 40);
m2.put("inq", 41);
m2.put("otq", 42);
Map<String, Object> m3 = new HashMap<>();
m3.put("month", "1");
m3.put("day", "3");
m3.put("hour", "10");
m3.put("rain", 40);
m3.put("inq", 41);
m3.put("otq", 42);
Map<String, Object> m4 = new HashMap<>();
m4.put("month", "2");
m4.put("day", "3");
m4.put("hour", "10");
m4.put("rain", 40);
m4.put("inq", 41);
m4.put("otq", 42);
Map<String, Object> m5 = new HashMap<>();
m5.put("month", "3");
m5.put("day", "3");
m5.put("hour", "10");
m5.put("rain", 40);
m5.put("inq", 41);
m5.put("otq", 42);
list.add(m1);
list.add(m2);
list.add(m3);
list.add(m4);
list.add(m5);
InputStream is = null;
// 取出模板
try {
    is = ResourceUtil.getStream("classpath:templates/forecastTemp.xlsx");
    // 这里定义最终导出的文件名称
    String fileName = "xxxx.xlsx";
    // 这里的 file 就是 Controller 中传过来的 MultipartFile 文件对象;TemplateExcelUtils.imageCells()里面有图片的一些参数,可以根据自己需要调整图片的起始位置,边框等
    WriteCellData<Void> voidWriteCellData = TemplateExcelUtils.imageCells(file.getBytes());
    // 这个 img 就是你在模板中文件图片所在位置的占位符  ,需要提前在模板中定义好 => {img}
    map.put("img", voidWriteCellData);
    ExcelWriter excelWriter = EasyExcel.write(TemplateExcelUtils.getOutputStream(fileName, response)).withTemplate(is).excelType(ExcelTypeEnum.XLSX).build();
    WriteSheet writeSheet = EasyExcel.writerSheet().build();
    // 这个传进去的 map 就是非表格数据,详见我定义的模板中图片位置上方那部分
    excelWriter.fill(map, writeSheet);
    // 这个 data 是官方约定就这么写, 传进去的 list 就是要遍历的表格数据,详见我定义的模板中图片位置右侧那部分
    excelWriter.fill(new FillWrapper("data", list), writeSheet);
    excelWriter.finish();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、TemplateExcelUtils

代码如下(示例):

package com.jxstjh.xjwpsm.forecastWarning.app.utils;

import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.FileUtils;


import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0
 * @date 2022-12-11 18:00
 */
public class TemplateExcelUtils {

    /**
     * Excel所有图片设置
     *
     * @param bytes
     * @return
     * @throws IOException
     */
    public static WriteCellData<Void> imageCells(byte[] bytes) throws IOException {


        WriteCellData<Void> writeCellData = new WriteCellData<>();
        // 这里可以设置为 EMPTY 则代表不需要其他数据了
        //writeCellData.setType(CellDataTypeEnum.EMPTY);

        // 可以放入多个图片
        List<ImageData> imageDataList = new ArrayList<>();
        writeCellData.setImageDataList(imageDataList);


        ImageData imageData = new ImageData();
        imageDataList.add(imageData);
        // 设置图片
        imageData.setImage(bytes);
        // 图片类型
        //imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
        // 上 右 下 左 需要留空,这个类似于 css 的 margin;这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
        imageData.setTop(10);
        imageData.setRight(10);
        imageData.setBottom(10);
        imageData.setLeft(10);

        // * 设置图片的位置。Relative表示相对于当前的单元格index。first是左上点,last是对角线的右下点,这样确定一个图片的位置和大小。
        // 目前填充模板的图片变量是images,index:row=7,column=0。所有图片都基于此位置来设置相对位置
        // 第1张图片相对位置
        imageData.setRelativeFirstRowIndex(0);
        imageData.setRelativeFirstColumnIndex(0);
        imageData.setRelativeLastRowIndex(20);
        imageData.setRelativeLastColumnIndex(5);


        return writeCellData;
    }


    /**
     * 导出文件时为Writer生成OutputStream.
     *
     * @param fileName 文件名
     * @param response response
     * @return ""
     */
    public static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            throw new Exception("导出excel表格失败!", e);
        }
    }

}

四、xlsx模板路径

EasyExcel根据自定义模板导出Excel(包含图片、表格)_第1张图片

五、模板内容制作

EasyExcel根据自定义模板导出Excel(包含图片、表格)_第2张图片

六、导出内容展示

EasyExcel根据自定义模板导出Excel(包含图片、表格)_第3张图片


总结

提示:对图片操作最重要的类就是 WriteCellData 如果你的easyexcel没有这个类,说明你的版本太低,请升级到3.0以上:

如果有多张图片需要指定位置的请参考这里:请点击这里

你可能感兴趣的:(java,excel,java)