EasyExcel 导出动态表格

EasyExcel 导出动态表格

一般推荐使用方法二,但方法一也一定要看,会有很多收获。

需求

:前端选择对应列,导出对应列的数据,比如前端选择了 姓名、名称、学号列
那么就需要导出如下表格:

在这里插在这里插入图片描述
入图片描述

ok,需求明确。

方法一 (推荐待选字段过多不用写VO的情况)

① 通过反射拿到实体对应的字段、属性等信息,返给前端供前端选择。
这里利用了@TableField 、@ApiModelProperty注解拿到对应的
注释(name)、字段名(filedName)、数据库字段名(key)

    public List<Map<String, String>> getFields() {Field[] declaredFields = HbProjectInfo.class.getDeclaredFields();List<Map<String, String>> resultList = new ArrayList<>();for (Field field : declaredFields) {if (field.isAnnotationPresent(TableField.class) && field.getAnnotation(TableField.class).exist()) {Map<String, String> map = new HashMap<>();String key = field.getAnnotation(TableField.class).value();String name = null;if (field.isAnnotationPresent(ApiModelProperty.class)) {name = field.getAnnotation(ApiModelProperty.class).value();}map.put("key", key);map.put("name", name);map.put("filedName", field.getName());resultList.add(map);}}return resultList;}

结果JSON

[{"filedName": "name","name": "名字","key": "NAME"},{"filedName": "age","name": "年龄","key": "AGE"},{"filedName": "studentId","name": "学号","key": "STUDENT_ID"}
]

② 前端选择后,传给后端

后端传入的 JSON ,比如他选了 年龄、年龄两个字段

[{"filedName": "name","name": "名字","key": "NAME"},{"filedName": "age","name": "年龄","key": "AGE"}
]

③ 后端接口:
studentService 是自己的实现类,自己 @AutoWired 出来即可

    @PostMapping("/export")@ApiOperation(value = "学员信息导出", notes = "")public AjaxResult export(HttpServletResponse response, @RequestBody List<Map<String,String>> headList) throws Exception {studentService.export(response,headList);return AjaxResult.success("导出成功!");}

④ 实现我们的 export 方法 下面是正文,请好好看

public void export(HttpServletResponse response,List<Map<String,String>> headList) throws Exception {if(CollectionUtils.isEmpty(headList)){headList = hbProjectInfoService.getFields();}List<String> names = headList.stream().map(m -> m.get("name")).collect(Collectors.toList());List<String> keys = headList.stream().map(m -> m.get("key")).collect(Collectors.toList());List<String> filedNames = headList.stream().map(m -> m.get("filedName")).collect(Collectors.toList());//表头List<List<String>> heads = new ArrayList<>();String title = "数据导出";for (String name : names) {List<String> head0 = new ArrayList<>();head0.add(title);head0.add(name);heads.add(head0);}//填充数据List<List<Object>> dataList = new LinkedList<>();String join = String.join(",", keys);List<Student>  list = studentService.getColumnsData(join);for (Student student: list) {List<Object> objectList = new LinkedList<>();Class<? extends Student> ac = Student.getClass();for (String name : filedNames) {Field field = ac.getDeclaredField(name);field.setAccessible(true);Object o = field.get(hbProjectInfo);objectList.add(o);}dataList.add(objectList);}// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 背景设置为白色headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)16);headWriteCellStyle.setWriteFont(headWriteFont);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);//设置边框contentWriteCellStyle.setBorderTop(BorderStyle.THIN);contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);contentWriteCellStyle.setBorderRight(BorderStyle.THIN);contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);//居中contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 背景白色contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小contentWriteFont.setFontHeightInPoints((short)12);contentWriteCellStyle.setWriteFont(contentWriteFont);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);// 设置响应头// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postmanresponse.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和 easyexcel 没有关系String fileName = URLEncoder.encode("学员信息表", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");// 先仅仅写入头,再以不写入头的方式写入数据EasyExcel.write(response.getOutputStream()).head(heads).registerWriteHandler(horizontalCellStyleStrategy)//列宽自适应.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())//设置头部和内容的行高.registerWriteHandler(new SimpleRowHeightStyleStrategy((short)50,(short)30)).sheet("学员信息表").doWrite(dataList);}

结果就是:
在这里插入图片描述

你也可以了解各种策略,来实现你的目的,但是我是真的没再官网知道 EasyExcel 的所有 策略,网上也找不到适合我的,就只能从官网上拼拼凑凑这么个东西。

方法二 (一般情况下推荐)

使用 includeColumnFieldNames

includeSet 为动态表头的 code 是个 Set<String>dataList 为数据,这里需要一个 List <Student >
让实体的字段名称与 includeSet 的 code 对应上即可。

@Data
public class Student {@ExcelProperty(value = {"学员基本信息","姓名"},order = 0)private String name;@ExcelProperty(value = {"学员基本信息","年龄"},order = 1)private String age;@ExcelProperty(value = {"学员基本信息","学号"},order = 2)private String studentID;
}

具体实现代码:

    public void getStudent(HttpServletResponse response) throws Exception {//这里我是写死的,你可以让前端传Set<String> headList = new HashSet<>();headList.add("name");headList.add("age");//数据List<Student> dataList = new LinkedList<>();Student student = new Student();student.setName("张三");student.setAge("12");student.setStudentID("12123213");dataList.add(student);Student student1 = new Student();student1.setName("李四");student1.setAge("13");student1.setStudentID("32432432");dataList.add(student1);response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("学员基本信息", "UTF-8").replaceAll("\\+", "%20");// 设置Content-Disposition属性值response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), Student.class).includeColumnFieldNames(headList).registerWriteHandler(new ExcelWidthStyleStrategy()).registerWriteHandler(new ExcelHeightStyleStrategy()).registerWriteHandler(new HbTableStyle()).sheet("学员基本信息").doWrite(dataList);}

HbTableStyle 类:方法一的头部策略、内容策略一致,直接使用改类即可,他们都共同继承了 AbstractVerticalCellStyleStrategy

public class HbTableStyle extends AbstractVerticalCellStyleStrategy {public HbTableStyle() {}@Overrideprotected WriteCellStyle headCellStyle(Head head) {// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 背景设置为白色headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)16);headWriteCellStyle.setWriteFont(headWriteFont);return headWriteCellStyle;}@Overrideprotected WriteCellStyle contentCellStyle(Head head) {// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);//设置边框this.setBorderStyle(contentWriteCellStyle);//居中contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 背景白色contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小contentWriteFont.setFontHeightInPoints((short)12);contentWriteCellStyle.setWriteFont(contentWriteFont);return contentWriteCellStyle;}private static void setBorderStyle(WriteCellStyle contentWriteCellStyle){//设置边框样式contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);contentWriteCellStyle.setBorderTop(BorderStyle.THIN);contentWriteCellStyle.setBorderRight(BorderStyle.THIN);contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);}
}

总结:

区别:方法一灵活,想怎么玩怎么玩,不用定义实体,有点复杂
方法二,简单方便,实用于大部分业务,比起方法一可能没那么灵活,但也够用了。

更多的API使用请查询官网:EasyExcel官网
我就是没仔细看官网API下面有很多的参数配置,只看了基础文档,才写出的方法一。希望大家以后看文档,仔细认真。

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

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

相关文章

面试题 之 react

1.说说对react的理解 1️⃣是什么 React是用于构建用户界面的 JavaScript 库,遵循组件设计模式、声明式编程范式和函数式编程概念&#xff0c;更高效使用虚拟 DOM 来有效地操作 DOM &#xff0c;遵循从高阶组件到低阶组件的单向数据流。 react 类组件使用一个名为 render() 的方…

爬虫高阶(一):解决验证码及爬取知网论文数据

爬取知网论文数据 解决验证码实现过程代码解决验证码 首先我们必须要识别出验证码,才能让进行下一步。 分享一个好用的网站 云码 接着按照流程操作来得到积分,点击个人中心查看自己的token即可(会用到,一次大约10积分,初始有300免费积分,1元能有1000积分) 实现过程…

[AIGC] MySQL与PostgreSQL事务完整性的对比

事务完整性是数据库管理系统最为重要的特性之一。在简单的术语中&#xff0c;一个事务可以被定义为一个逻辑单元的工作&#xff0c;它一旦被提交&#xff0c;要么全部成功&#xff0c;要么全部失败。这种“全部或无”的特性体现了一个数据库事务的原子性&#xff0c;是保证数据…

Css提高——Css3盒子模型border-box

1、盒子模型的种类与区别 CSS3 中可以通过 box-sizing 来指定盒模型&#xff0c;有2个值&#xff1a;即可指定为 content-box、border-box&#xff0c;这样我们 计算盒子大小的方式就发生了改变。 CSS3 盒子模型 可以分成两种情况&#xff1a; 1. box-sizing: content-box 盒…

ArcGIS Pro与R:携手优化生态系统服务评估流程

生态系统服务是指生态系统所形成的用于维持人类赖以生存和发展的自然环境条件与效用&#xff0c;是人类直接或间接从生态系统中得到的各种惠益。联合国千年生态系统评估&#xff08;Millennium ecosystem assessment&#xff0c;MA&#xff09;提出生态系统服务包括供给、调节、…

easyExcel 读取excel(按条读取)

MAVEN <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency>代码 import com.al…

Python 解析CSV文件 使用Matplotlib绘图

数据存储在CSV文件中&#xff0c;使用Matplotlib实现数据可视化。 CSV文件&#xff1a;comma-separated values&#xff0c;是在文件中存储一系列以‘&#xff0c;’分隔的值。 例如&#xff1a;"0.0","2016-01-03","1","3","20…

电子电工基础-二极管

二极管&#xff1a;单向导电性 工作区域&#xff1a;截止区、放大区、饱和区、反向击穿区 相关计算题 注意点&#xff1a;正向压降为0.7V&#xff0c;但是电流小&#xff0c;可以设为0.6V 在对其进行静态分析 可以得出静态直流的电流大小Id 根据二极管电流为26ma的特性&…

力扣刷题Days23-35.搜索插入的位置(js)

1&#xff0c;题目 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。 2&#xff0c;代码 /*** param {number[]} nums*…

Vue+SpringBoot打造智慧家政系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…

鸿蒙 Launcher与android Launcher的开发区别

鸿蒙&#xff08;HarmonyOS&#xff09;Launcher与Android Launcher在某些方面相似&#xff0c;但也存在一些明显的区别。尽管鸿蒙Launcher和Android Launcher都是用于用户与设备交互的界面&#xff0c;但由于底层架构、生态系统、开发语言和工具等方面的差异&#xff0c;它们在…

2024年亚洲图像处理趋势会议(ATIP 2024)即将召开!

2024年亚洲图像处理趋势会议&#xff08;简称&#xff1a;ATIP 2024&#xff09;将于2024年6月21日至23日在英国伦敦举行。在会议上我们将与相关领域的研究人员和知名专业人士共同讨论关于图像处理学科的最新研究方向及进展&#xff0c;评估当前最先进的技术和未来研究的关键领…

使用el-cascader组件写下拉级联多选并且具有全选功能

样式 说明&#xff1a; 级联选择器中加上全选的按钮&#xff0c; 并且保证数据响应式。 思路 因为是有全选的功能&#xff0c;所以不能直接使用el-cascader组件&#xff0c; 而是选择使用el-select组件&#xff0c; 在此组件内部使用el-cascader-panel级联面板全选按钮也是…

Win11配置WSL(Ubuntu)环境

一&#xff0c;什么是WSL WSL:Windows Subsystem for Linux&#xff0c;是用于Windows系统之上的Linux子系统。作用很简单&#xff0c;可以在Windows系统中获得Linux系统环境&#xff0c;并完全直连计算机硬件&#xff0c;无需通过虚拟机虚拟硬件 简而言之: Windows10的WSL功能…

【Android】图解View事件分发机制

文章目录 View事件分发机制dispartchTouchEvent()dispatchTouchEvent() 方法主要负责什么&#xff1f; onTouchEvent(event) 点击事件分发的传递规则自上而下自下而上 View事件分发机制 View的事件分发机制是Android中非常核心的一个概念&#xff0c;它负责处理触摸事件&#…

【黄金手指】windows操作系统环境下使用jar命令行解压和打包Springboot项目jar包

一、背景 项目中利用maven将Springboot项目打包成生产环境jar包。名为 prod_2024_1.jar。 需求是 修改配置文件中的某些参数值&#xff0c;并重新发布。 二、解压 jar -xvf .\prod_2024_1.jar释义&#xff1a; 这段命令是用于解压缩名为"prod_2024_1.jar"的Java归…

OpenGL学习笔记【2】——开发环境配置(GLFW,VS,Cmake),创建第一个项目

学OpenGL的都会知道&#xff0c;OpenGL只提供了绘图功能&#xff0c;创建窗口是需要自己完成的。这就需要学习相应操作系统的创建窗口方法&#xff0c;为简化创建窗口的过程&#xff0c;可以使用专门的窗口库&#xff0c;例如GLFW。使用GLFW之前需要先进行配置&#xff0c;那怎…

css实现的3D立体视觉效果鸡蛋动画特效

这是一个基于纯css实现的3D立体视觉效果鸡蛋动画特效&#xff0c;喜欢的朋友可以拿来使用演示动态效果 css实现的3D立体视觉效果鸡蛋动画特效

spark RDD 创建及相关算子

RDD编程入口 RDD编程入口对象是SparkContext对象&#xff0c;想要调用相关的计算api都需要通过构造出的sparkcontext对象调用 RDD的创建 通过并行化集合创建RDD&#xff08;本地集合转为分布式&#xff09;&#xff0c;api如下 rdd sc.parrallize(param1, param2)参数1是本…

Linux:点命令source

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 source命令用于读取一个文件的内容并在当前Shell环境&#xff08;包括交互式Shell或是非交互式Shell&#xff09;执行里面的命令。它被称为点命令是因为命令名source也可…