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

news2025/1/11 7:12:51

前言

昨天遇到个有点复杂的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 行结束。



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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/999387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

过等保三级的好处是什么?谁能简单说说?

虽然国家已经严格落地执行了等保2.0政策&#xff0c;但还有少数小伙伴对于等保政策不是很了解&#xff0c;有小伙伴问过等保三级的好处是什么&#xff1f;谁能简单说说&#xff1f;这里就来一起聊聊。 过等保三级的好处是什么&#xff1f; 好处1、遵循国家法律法规要求&…

气象观测站:观测原理及优势,助力气象精准预报

随着全球气候变化日益严重&#xff0c;气象观测站在现代社会中的地位愈发凸显。 一、气象观测站的观测原理 气象观测站主要通过各种传感器来测量大气的温度、湿度、风速、风向、气压、太阳辐射等基本气象要素。这些传感器需要具备高精度和高稳定性&#xff0c;以确保观测数据…

DAY02_瑞吉外卖——完善登录功能新增员工员工分页查询启用/禁用员工账号编辑员工信息

目录 1. 完善登录功能1.1 问题分析1.2 思路分析1.3 代码实现1.4 功能测试 2. 新增员工2.1 需求分析2.2 数据模型2.3 程序执行流程2.4 代码实现2.5 功能测试2.6 全局异常处理2.6.1 思路分析2.6.2 全局异常处理器2.6.3 测试 3. 员工分页查询3.1 需求分析3.2 程序执行流程3.2.1 页…

实现在外网SSH远程访问内网树莓派的详细教程

文章目录 如何在局域网外SSH远程访问连接到家里的树莓派&#xff1f;如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpol…

PyTorch深度学习实战(15)——迁移学习

PyTorch深度学习实战&#xff08;15&#xff09;——迁移学习 0. 前言1. 迁移学习1.1 迁移学习基本概念1.2 迁移学习的重要性1.3 ImageNet1.4 迁移学习流程 2. VGG16 架构3. 使用预训练 VGG16 模型实现猫狗分类小结系列链接 0. 前言 迁移学习( Transfer Learning )是一种利用从…

利用evo将kitti数据集真值轨迹由kitti格式转为tum格式

&#xff08;1&#xff09;首先是序列对应问题&#xff1a; 00: 2011_10_03_drive_0027 01: 2011_10_03_drive_0042 02: 2011_10_03_drive_0034 03: 2011_09_26_drive_0067 04: 2011_09_30_drive_0016 05: 2011_09_30_drive_0018 06: 2011_09_30_drive_0020 07: 2011_09_30_dr…

精品基于NET实现的期刊订购管理系统

《[含文档PPT源码等]精品基于NET实现的期刊订购管理系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发软件&#xff1a;VS 2017 &#xff08;版本2017以上即可&#xff0c;不能低于2017&#xff09; 数…

12.示例程序(定时器定时中断定时器外部时钟)

目录 定时中断和时钟源选择相关库函数使用 1.定时器初始化配置 2.参数&#xff08;PSC、ARR等&#xff09;更改函数&#xff08;在程序运行过程中修改&#xff09; 3.使用定时器库函数的一些细节 定时器定时中断实例 定时器外部时钟选择 知识点get&#xff1a; 滤波器工作…

印尼市场TikTok攻略:如何利用海外网红引领品牌营销?

随着社交媒体的迅速崛起&#xff0c;营销策略也在不断演变&#xff0c;其中TikTok作为一个全球热门的短视频平台&#xff0c;为企业在国际市场上推广产品和服务提供了新的机会。印尼作为东南亚最大的国家之一&#xff0c;拥有庞大的互联网用户群体&#xff0c;为品牌在TikTok上…

如何写出一篇爆款产品文案,从目标受众到市场分析!

一篇爆款产品文案意味着什么?意味着更强的种草能力&#xff0c;更高的销售转化和更强的品牌传播力。今天来分享下如何写出一篇爆款产品文案&#xff0c;从目标受众到市场分析&#xff01; 一、产品文案策略 一篇爆款产品文案&#xff0c;并不是一时兴起造就的。在撰写之前&…

Date日期工具类(数据库日期区间问题)

文章目录 前言DateUtils日期工具类总结 前言 在我们日常开发过程中&#xff0c;当涉及到处理日期和时间的操作时&#xff0c;字符串与Date日期类往往要经过相互转换&#xff0c;且在SQL语句的动态查询中&#xff0c;往往月份的格式不正确&#xff0c;SQL语句执行的效果是不同的…

提升测试效果:深入解析《Effective软件测试》的关键方法与实践

目录 1、写在前面2、独特的观点3、内容介绍4、作者介绍5、赠书 or 购买 1、写在前面 近年来出现了一 些新的出版方式&#xff0c;MEAP(Manning Early Access Program)就是其中的一种&#xff0c;把开源运动扩展到出版行业。在MEAP中&#xff0c;读者可在图书出版前逐章阅读早期…

2023开学值得买电容笔有哪些?ipad第三方电容笔推荐

很多学生都已经在为新学期的到来做准备了&#xff0c;而电容笔&#xff0c;也是他们最喜欢的一种。苹果的Pencil&#xff0c;虽然功能很强&#xff0c;但也很贵&#xff0c;不是每个人都能买得起的。目前市场上有很多价格低廉&#xff0c;使用方便的平替电容笔&#xff0c;因此…

Numpy和Pandas简介

推荐&#xff1a;使用NSDT场景编辑器快速搭建3D应用场景 如果您正在从事数据科学项目&#xff0c;Python 包将简化您的生活&#xff0c;因为您只需要几行代码即可执行复杂的操作&#xff0c;例如操作数据和应用机器学习/深度学习模型。 在开始你的数据科学之旅时&#xff0c;…

[Linux]进程间通信--共享内存

[Linux]system V共享内存 文章目录 [Linux]system V共享内存共享内存通信的原理系统接口创建共享内存接口关联共享内存接口去关联共享内存接口删除共享内存接口 使用指令操作共享内存查看共享内存删除共享内存 共享内存的特性编码测试共享内存 共享内存是Linux系统下的一种进程…

spring boot项目运行及打包

目录 一、项目示例 二、项目运行 三、项目打包 3.1 配置打包项 3.2 运用maven工具打包 3.3 运行打包好的jar文件 一、项目示例 创建项目逻辑实现文件&#xff08;控制URL路径访问及内容逻辑实现&#xff09; 如上图点击创建新的java class文件&#xff0c;编辑文件内容&…

开发工程师VS测试工程师VS测试开发工程师

每年正式上班之后就会非常忙&#xff0c;今年也不例外。我们公司现在也忙了起来&#xff0c;都没有时间写我的自动化测试教程了。不过大家放心&#xff0c;我会继续写下去的&#xff0c;不过可能更新的不那么快了。最近被同事问到了一个问题&#xff0c;开发&#xff0c;测试和…

nvidia-smi指令报错:Failed to initialize NVML: Driver 解决

文章目录 如何解决题外话&#xff0c;ubuntu22如何安装NVIDIA驱动 我的系统是ubuntu22。 如何解决 我是之前有能用的驱动&#xff0c;但突然服务器nvidia-smi命令不能用了。 看网上说重启就好了&#xff0c;我重启后还是没用&#xff0c;我建议是重启后运行下面2个指令。 运…

python开发之个人微信机器人的开发

简要描述&#xff1a; 发送链接 请求URL&#xff1a; http://域名地址/sendUrl 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是st…

运维学习之采集器Node-Exporter 1.3.1安装并使用

参考《监控系统部署prometheus基本功能》先完成prometheus部署。 wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz下载压缩包。 tar -zxf node_exporter-1.3.1.linux-amd64.tar.gz进行解压。 cp node_e…