easypoi模板导出、一张sheet有多个不同表格、带一张或多张echars图表

前言

昨天遇到个有点复杂的excel需要导出,一张sheet里面有两个不同的表格,然后还有几张echars图表要加进去。总共分为上下两个部分,上面是表格一;下面又分为左右两个部分,左边是表格二,右边是几张echars图。结构大概如下图:

在这里插入图片描述
一张sheet里面放两个不同表格这种导出,我印象里好像还真没写过这种导出,这种表格一般用模板进行导出会方便一点吧?

然后echars图表的话,以前写过一个导出单个图表的:easypoi导出表格带echars图表 。然后这次我们需要导多张图表。

实现

效果

我们先来看看实现效果:

在这里插入图片描述

在这里插入图片描述

这里我选择用模板导出(这次的表格填充数据也方便),我们在 resources 文件夹下,创建一个 template 文件夹,然后里面放excel模板。

1、先设置好要导出的模板

在这里插入图片描述

设置好后,把模板放到 template 文件夹里面。

2、导出

<!-- excel -->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>4.4.0</version>
</dependency>
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.excel.imports.ExcelImportService;
import cn.hutool.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;

/**
 * easypoi操作工具类
 */
public class EasyExcelUtil {

	// ......省略其他代码
	
    /**
     * 导出Excel,并在最后追加多张图片
     * @param workbook   HSSFWorkbook对象
     * @param imgBase64  图片base64
     * @param anchors  图片偏移量
     */
    public static Workbook getHSSFWorkbook(Workbook workbook, JSONArray imgBase64, int[] anchors) throws IOException {
        if (workbook == null) {
            workbook = new HSSFWorkbook();
        }
        List<File> tempList = new ArrayList<>(); // 存放临时图片文件
        Sheet sheet = workbook.getSheetAt(0);
        String picPath = System.getProperty("user.dir")+"\\upload\\excel\\"; // 图片临时路径
        int size = imgBase64.size();
        int offset = anchors[5]; // Y轴偏移量
        for (int i = 0; i < size; i++) {
            String[] imgUrlArr = imgBase64.get(i).toString().split("base64,");  //拆分base64编码后部分
            byte[] buffer = new BASE64Decoder().decodeBuffer(imgUrlArr[1]);
            String temp = picPath + i + ".png"; // 临时图片
            File file = new File(temp); //图片文件
            try {
                //生成图片
                OutputStream out = new FileOutputStream(file);//图片输出流
                out.write(buffer);
                out.flush();//清空流
                out.close();//关闭流
                ByteArrayOutputStream outStream = new ByteArrayOutputStream(); // 将图片写入流中
                BufferedImage bufferImg = ImageIO.read(new File(temp));
                ImageIO.write(bufferImg, "PNG", outStream);
                Drawing<?> patri = sheet.createDrawingPatriarch(); // 利用HSSFPatriarch将图片写入EXCEL
                /**
                 * dx1:图片左上角相对于单元格左上角的X轴偏移量,单位是英寸的1/1024部分。通常情况下,你可以将其设置为0,表示与单元格左上角对齐。
                 * dy1:图片左上角相对于单元格左上角的Y轴偏移量,单位是英寸的1/1024部分。通常情况下,你可以将其设置为0,表示与单元格左上角对齐。
                 * dx2:图片右下角相对于单元格左上角的X轴偏移量,单位是英寸的1/1024部分。这个值通常设置为0,表示不进行X轴方向的偏移。
                 * dy2:图片右下角相对于单元格左上角的Y轴偏移量,单位是英寸的1/1024部分。这个值通常设置为0,表示不进行Y轴方向的偏移。
                 * col1:图片左上角所在的列号(从0开始)。通常情况下,你可以将其设置为插入图片的单元格列号。3(第4列开始)
                 * row1:图片左上角所在的行号(从0开始)。通常情况下,你可以将其设置为插入图片的单元格行号。27(第28行开始)
                 * col2:图片右下角所在的列号(从1开始)。8(到第8列为止)
                 * row2:图片右下角所在的行号(从1开始)。9(总共占了9行)
                 */
                ClientAnchor anchor = patri.createAnchor(anchors[0], anchors[1], anchors[2], anchors[3], anchors[4], offset, anchors[6], offset+9);
                patri.createPicture(anchor, workbook.addPicture(outStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
                offset += 10; // 增加Y轴偏移量,确保下一张图片在上一张图片的下面(空1行)
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            tempList.add(file);
        }
        // 删除临时图片
        for (File file : tempList) {
            if (file.exists()) file.delete();
        }
        return workbook;
    }
    
    // ......省略其他代码
    
}

在这里插入图片描述

/**
 * 导出
 */
@PostMapping("/export")
public void export(@RequestBody Map<String,Object> params,HttpServletResponse response) throws IOException {
    // 获取导出的模板
    TemplateExportParams template = new TemplateExportParams("template/1.xlsx");
    // 创建Excel数据模型
    Map<String, Object> model = new HashMap<>();
    model.put("list", getList()); // 按需求查询列表
    model.put("tjList", getTjList()); // 按需求查询列表
    model.put("yhbh", ""); // 按需求查询用户编号
    model.put("yhmc", ""); // 按需求查询用户名称

    // 创建Excel工作簿
    Workbook workbook = ExcelExportUtil.exportExcel(template, model);
    // 插入图片,设置图片偏移量(这里我只设置了7个参数,第八个参数是根据第六个参树来计算的)
    int[] imgAnchors = {0, 0, 0, 0, 3, 27, 8};
    EasyExcelUtil.getHSSFWorkbook(workbook,array,imgAnchors);
    EasyExcelUtil.downLoadExcel("导出",response,workbook);
}

3、关于图片的偏移量

也就是 int[] imgAnchors = {0, 0, 0, 0, 3, 27, 8}; 这一句设置的偏移量。

总共有八个参数,前面四个是固定写0的,主要是后面四个参数。

  • col1:图片左上角所在的列号(从0开始)。通常情况下,可以将其设置为插入图片的单元格列号。
  • row1:图片左上角所在的行号(从0开始)。通常情况下,可以将其设置为插入图片的单元格行号。
  • col2:图片右下角所在的列号(从1开始)。
  • row2:图片右下角所在的行号(从1开始)。

col1 计算

一般情况下数据list的列数我们都是可以确定有多少列的,所以 col1 的值我们也能够直接确定,直接根据数据的列数设置就行,或者没有特殊要求直接设置为0就行。因为我的图表左边还有个表格,所以设置的不是0。

col2 计算

col2 也很好确定,就是你想让图表占多少列,也就是到第几列结束,就设置为几,col2 = col1 + 占几列 。比如我上面的示例是占了 5 列,那么 col2 = 3+5

row1 计算

然后是行数,因为图片是追加到数据list下面的,绝大多数情况下我们都是不确定的总共有多少条数据的,所以 row1 不能写死(上面的示例我写死了是因为我确定数据只有24条),那 row1 应该要怎么计算呢?这时我们就需要根数据list的size来进行计算了。公式:row1 = title的行数 + header的行数 + list.size() + 空几行 。比如我的sheet没有标题,那么 title就是0(有标题的话,title有几行就加几),表头有1行,list有24条数据,然后我在数据下面空2行显示图片,结果就是:row1 = 0 + 1 + 24 + 2 = 27

row2 计算

最后就是 row2 ,这个和 col2 一样,确定了 row1 就很好确定 row2 了。col2 是占几列,那么 row2 就是占几行,想让图表占多少行,也就是到第几行结束,就设置为几,row2 = row1 + 占几行 。比如我上面的示例是占了 9 行,那么 row2 = 27+9 ,到第 36 行结束。



好啦,以上就是本篇文章的全部内容了,如果你觉得对你有帮助的话,不妨给博主点个赞~ (没帮助也给偶点个赞赞吧~🥺🥺)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

符华-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值