easypoi动态表头导出数据

需求:动态导出某年某月用户和用户评分数据信息,表头(序号、姓名、用户姓名),数据(所有用户对应的评分以及平均分);

分析:1、表头除过序号、姓名,用户姓名要动态生成;

            2、用户评分信息要和表头中的用户一一对应;

1、maven依赖

<!-- easypoi -->
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.4.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>4.4.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.4.0</version>
</dependency>

2、数据表结构

2.1用户表

2.2 评分表

2.3 sql

select 
tu.id as userId,//用户id(被评分人id)
tu.real_name as realName, //用户姓名(被评分人)
GROUP_CONCAT(ts.scorer_id  SEPARATOR ',') as scorerId,//该用户对应的所有评分人id,用逗号隔开
GROUP_CONCAT(ts.score SEPARATOR ',') as scoreStr,//该用户的所有评分分数,用逗号隔开
ROUND(avg(ts.score),3) as avgScore//该用户评分平均数
from t_user tu left join t_score ts 
on tu.id  = ts.user_id 
where ts.`year` = '2024' and ts.`month` = '5'
GROUP by userId ,realName
order by  avgScore;

3、代码

1、查询表头所有用户,即可知道表头总列数

2、对应上面sql,查询用户评分数据

3、被评分人分数按照评分人userDOS顺序设置

4、评分人是固定的,但是所有评分人不一定都给(用户)被评分人评分,如果评分人还未评分,分数则为0

5、scoreList 中的数据即是按照表头评分人评的分数有序排列(如果评分人还未评分,分数则为0)

6、excel  title

7、excel data

8、规则设置高度

9、表头设置样式

3.1 controller

/*** Excel导出*/@GetMapping("/excel")public Result excelDownload( HttpServletResponse response, HttpServletRequest request,@RequestParam(name = "year",required = false) String year,@RequestParam(name = "month",required = false) String month) throws Exception{scoreService.excelDownload(response,request,year,month);return ResultGenerator.genOkResult();}

3.2实现类

@Overridepublic void excelDownload(HttpServletResponse response, HttpServletRequest request,String year, String month) throws IOException {LocalDate currentDate = LocalDate.now();String currentYear = String.valueOf(currentDate.getYear());String currentMonth = String.valueOf(currentDate.getMonthValue());year = StrUtil.isNotEmpty(year) ? year : currentYear;month = StrUtil.isNotEmpty(month) ? month : currentMonth;//1、查询表头所有用户,即可知道表头总列数QueryWrapper<UserDO> queryWrapper =  new QueryWrapper<UserDO>();queryWrapper.isNotNull("real_name");final List<UserDO> userDOS = userMapper.selectList(queryWrapper);//2、对应上面sql,查询用户评分数据final List<UserIdAndScoreDTO> userIdAndScoreDTOS = userMapper.selectUserScores(year, month);//3、被评分人分数按照评分人userDOS顺序设置for(UserIdAndScoreDTO userIdAndScoreDTO : userIdAndScoreDTOS){List<Double> scoreList = new ArrayList<>();final String[] split = userIdAndScoreDTO.getScorerId().split(",");final String[] split1 = userIdAndScoreDTO.getScoreStr().split(",");for(UserDO userDO : userDOS){//判断某个字符串在数组中如果存在,找到对应下标,如果不存在则为-1int index = findStringIndex(split, userDO.getId());//4、评分人是固定的,但是所有评分人不一定都给(用户)被评分人评分,如果评分人还未评分,分数则为0String a = (index!= -1) ? split1[index] : "0";scoreList.add(Double.valueOf(a));}//5、scoreList 中的数据即是按照表头评分人评的分数有序排列(如果评分人还未评分,分数则为0)userIdAndScoreDTO.setScoreList(scoreList);}//6、excel  titlefinal List<DynamicTablePo> tablePoList = getTalePoList(userDOS);//7、excel datafinal List<Map<String, Object>> excelScoreVOS = dataList(userIdAndScoreDTOS, userDOS);List<ExcelExportEntity> beanList = new ArrayList<ExcelExportEntity>(tablePoList.size());for (DynamicTablePo tablePo : tablePoList){ExcelExportEntity entity = new ExcelExportEntity();entity.setName(tablePo.getFiledShowName());entity.setKey(tablePo.getFiledCode());entity.setOrderNum(tablePo.getOrderNum());beanList.add(entity);}String excelName = "营销部"+ month +"月份各专责互评的得分表";String secondTitle = "规则:从日常工作协同等工作进行考评,从1-5分为9个分值进行打分," +"如:1-1.5-2-2.5-3-3.5-4-4.5-5,每个人总分除以9作为最终得分。" +"注意:分值出现一样作为废票,该人员打分全部人员均按照委分统计。";ExportParams exportParams = new ExportParams(excelName,secondTitle, "sheet1");//8、规则设置高度exportParams.setSecondTitleHeight((short) 10);//9、表头设置样式exportParams.setStyle(ExcelExportTitleStyle.class);Workbook workbook = ExcelExportUtil.exportExcel(exportParams, beanList , excelScoreVOS);response.setHeader("content-Type","application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(excelName + "导出表", "UTF-8") + ".xls");response.setCharacterEncoding("UTF-8");workbook.write(response.getOutputStream());workbook.close();}/*** 组装数据* @return*/private List<Map<String,Object>> dataList(List<UserIdAndScoreDTO> userIdAndScoreDTOS,List<UserDO> userDOS){List<Map<String,Object>> exportList = new ArrayList<>();int j = 1;for(UserIdAndScoreDTO userIdAndScoreDTO : userIdAndScoreDTOS){Map<String,Object> map = new HashMap<>();map.put("num",j);map.put("realName",userIdAndScoreDTO.getRealName());map.put("avgScore",userIdAndScoreDTO.getAvgScore());final List<Double> scoreList = userIdAndScoreDTO.getScoreList();int i =0;for (UserDO userDO : userDOS) {map.put(userDO.getId(),scoreList.get(i));i++;}exportList.add(map);j++;}return exportList;}/*** 设置动态表头* @return*/private List<DynamicTablePo> getTalePoList(List<UserDO> userDOS) {int i = 3;List<DynamicTablePo> resultList = new ArrayList<>();DynamicTablePo tablePo = new DynamicTablePo();tablePo.setFiledShowName("序号");tablePo.setFiledCode("num");tablePo.setOrderNum(1);tablePo.setDataType(0);DynamicTablePo tablePo1 = new DynamicTablePo();tablePo1.setFiledShowName("姓名");tablePo1.setFiledCode("realName");tablePo1.setOrderNum(2);tablePo1.setDataType(0);resultList.add(tablePo);resultList.add(tablePo1);for (UserDO userDO : userDOS) {DynamicTablePo tablePo2 = new DynamicTablePo();tablePo2.setFiledShowName(userDO.getRealName());tablePo2.setFiledCode(userDO.getId());tablePo2.setOrderNum(i);tablePo2.setDataType(0);resultList.add(tablePo2);i++;}DynamicTablePo tablePo3 = new DynamicTablePo();tablePo3.setFiledShowName("平均分");tablePo3.setFiledCode("avgScore");tablePo3.setOrderNum(i);tablePo3.setDataType(0);resultList.add(tablePo3);return resultList;}/*** 判断某个字符串在数组中如果存在,找到对应下标,如果不存在则为-1* @param array* @param target* @return*/public static int findStringIndex(String[] array, String target) {for (int i = 0; i < array.length; i++) {if (array[i].equals(target)) {return i;}}return -1;}

3.3 实体  filedCode(表头key值和查询出来的数据的实体/map相对应,否则无法填充数据)

package com.langzhifangling.wx.scoringapplet.model.VO;import lombok.Data;import java.io.Serializable;@Data
public class DynamicTablePo implements Serializable {private static final long serialVersionUID = 8991244829305414889L;//表头名字private String filedShowName;//表头key值和查询出来的数据的实体相对应private String filedCode;//表头顺序private Integer orderNum;//字段数据类型private Integer dataType;
}

3.4 表头样式 

package com.langzhifangling.wx.scoringapplet.config;import cn.afterturn.easypoi.excel.export.styler.AbstractExcelExportStyler;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import org.apache.poi.ss.usermodel.*;/*** 导出自定义title的工具类** @author changjiang.liu* @date 2022/5/23 16:44*/
public class ExcelExportTitleStyle extends AbstractExcelExportStylerimplements IExcelExportStyler {public ExcelExportTitleStyle(Workbook workbook) {super.createStyles(workbook);}@Overridepublic CellStyle getTitleStyle(short color) {CellStyle titleStyle = workbook.createCellStyle();// 自定义字体Font font = workbook.createFont();font.setColor(IndexedColors.WHITE1.getIndex());font.setBold(true);font.setFontName("宋体");titleStyle.setFont(font);// 自定义背景色titleStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);titleStyle.setBorderBottom(BorderStyle.THIN);titleStyle.setBorderTop(BorderStyle.THIN);titleStyle.setBorderLeft(BorderStyle.THIN);titleStyle.setBorderRight(BorderStyle.THIN);titleStyle.setAlignment(HorizontalAlignment.CENTER);titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);titleStyle.setWrapText(true);return titleStyle;}@Overridepublic CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {CellStyle style = workbook.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setDataFormat(STRING_FORMAT);if (isWarp) {style.setWrapText(true);}return style;}@Overridepublic CellStyle getHeaderStyle(short color) {CellStyle titleStyle = workbook.createCellStyle();Font font = workbook.createFont();font.setFontHeightInPoints((short) 12);titleStyle.setFont(font);titleStyle.setAlignment(HorizontalAlignment.CENTER);titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);return titleStyle;}@Overridepublic CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {CellStyle style = workbook.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setDataFormat(STRING_FORMAT);if (isWarp) {style.setWrapText(true);}return style;}}

4、结果

注:

数据可以封装一个实体,由于被评分人的所有评分是一个集合,没搞出来;

故我是采用List<map>封装数据进行导出; 

所有是非集合,可以采用封装实体进行导出更简单点;

参考:

easypoi导出数据的两种方式(动态表头导出和静态表头导出)_easypoi 导出列的顺序-CSDN博客

补充:使用excel模板进行导出  #是横向获取集合数据   $是纵向获取集合数据  

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

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

相关文章

【赠书活动第4期】《Rust编程与项目实战》

赠书活动 《Rust编程与项目实战》免费赠书 3 本&#xff0c; 收到赠书之后&#xff0c;写一篇 本书某一节内容 的学习博客文章。 可在本帖评论中表示参加&#xff0c;即可获得赠书&#xff0c;先到先得。学习心得博客链接&#xff0c;后面有空发上来。 赠书截止日期为送出3…

无人播剧直播收益在哪里!快手无人播剧新秘籍:版权无忧,日入四位数攻略

无人播剧顾名思义就是通过短视频平台直播不需要真人出镜受众群体通过网络短视频平台看到的经典影视剧集可以实现24小时不停断的播放利用多种途径变现的一种直播形式 1、操作简单、不露脸、不出镜2、手机、电脑都可以操作3、可以矩阵操作4、0粉丝、0作品、0保证金就可以开播5、…

2010-2030年GHS-POP数据集下载

扫描文末二维码&#xff0c;关注微信公众号&#xff1a;ThsPool 后台回复 g008&#xff0c;领取 2010-2030年100m分辨率GHS-POP 数据集 &#x1f4ca; GHS Population Grid (R2023)&#xff1a;全球人口分布的精准视图与深度应用 &#x1f310; 在全球化和快速城市化的今天&am…

[嵌入式系统-73]:RT-Thread-快速上手:如何选择RT Thread的版本?

目录 如何选择合适的 RT-Thread 版本进行开发&#xff1f; RT-Thread 分支与版本介绍 如何选择 发布版本&#xff08;GitHub releases&#xff09; 开发分支&#xff08;GitHub master 主分支&#xff09; 长期支持分支&#xff08;GitHub lts-v3.1.x 分支&#xff09; …

10.轮转数组

文章目录 题目简介题目解答解法一&#xff1a;使用额外的数组代码&#xff1a;复杂度分析&#xff1a; 解法二&#xff1a;数组反转代码&#xff1a;复杂度分析&#xff1a; 题目链接 大家好&#xff0c;我是晓星航。今天为大家带来的是 轮转数组 相关的讲解&#xff01;&#…

STM32:EXTI—外部中断的初始化

文章目录 1、中断1.2 中断系统1.3 中断执行流程 2、STM32中断2.2EXTI&#xff08;外部中断&#xff09;2.3 EXTI 的基本结构2.4 AFIO复用IO口 3、NVIC基本结构3.2 NVIC优先级分组 4、配置EXTI4.2 AFIO 库函数4.3 EXTI 库函数4.4 NVIC 库函数4.5 配置EXTI的步骤4.6 初始化EXTI 1…

Python运维之协程

目录 一、定义协程 二、并发 三、异步请求 协程是一种轻量级的线程&#xff0c;它通过保存和恢复寄存器上下文和栈来实现调度切换&#xff0c;从而保留函数执行的状态。 这种机制使得协程在处理I/O密集型任务时效率较高&#xff0c;因为它们可以在I/O操作期间让出CPU&#…

QT——tableWidget-跳变之舞V1.0-记录学习【1】

QT——tableWidget-跳变之舞V1.0-记录学习【1】 文章目录 QT——tableWidget-跳变之舞V1.0-记录学习【1】前言一、利用QT创建项目文件1.1 完整项目文件如下图所示:1.2 演示&#xff1a; 二、声明文件&#xff1a;2.1 主界面声明文件:mainwindow.h&#xff1b;2.2 控制窗口声明文…

科技查新中医学科研项目查新点如何确立与提炼?案例讲解

一、前言 医学科技查新包括立项查新和成果查新两个部分&#xff0c;其中医学立项查新&#xff0c;它是指在医学科研项目申报开题之前&#xff0c;通过在一定范围内进行该课题的相关文献检索 ( 可以根据项目委托人的具体要求&#xff0c;进行国内检索或者进行国外检索 ) &#x…

区块链(打新)如何被割韭菜

看上去&#xff0c;像我只要去每个都买一遍新发行的代币&#xff0c;一定可以成功的 但是好像没有想象中这么简单&#xff0c;因为这些山寨币&#xff0c;庄家可以自己控盘的&#xff0c;看上去好像有跌宕起伏的买卖&#xff0c;但是一单掀桌子&#xff0c;庄家他自己都不玩了…

Python之数据分析基础

导言&#xff1a; “21世纪的竞争是数据的竞争&#xff0c;谁掌握数据&#xff0c;谁就掌握未来”。如何将大量看似杂乱无章的数据进行聚合&#xff0c;并发现潜在的规律也变得越来越重要。本文将先说明数据分析的步骤&#xff0c;再通过python完成实例数据的处理、分析最终展…

TDM(BPM)-MIMO-FMCW雷达MATLAB仿真

本文通过对车载毫米波雷达信号流程和链路的仿真&#xff0c;建立基本的算法框架&#xff0c;可用于算法性能的验证。并提供基础MATLAB仿真代码&#xff0c;作为分享和参考。 一、信号的产生 车载毫米波雷达广泛使用线性调频连续波雷达&#xff0c;也即发射信号频率随时间线性变…

日本OTC机械手维修需要注意哪些问题呢?

随着工业4.0时代的到来&#xff0c;机器人在制造业中的应用越来越广泛。OTC&#xff08;Over The Counter&#xff09;机器人作为工业机器人的一种&#xff0c;以其高效、精准、稳定的特点受到众多企业的青睐。然而&#xff0c;在实际使用过程中&#xff0c;可能会出现一些OTC机…

如何在路由器上做端口映射

假设现在外网有一台ADSL直接拨号上网的电脑&#xff0c;所获得的是公网IP。然后它想访问局域网内的电脑上面的网站&#xff0c;那么就需要在路由器上做端口映射。在路由器上做端口映射的具体规则是&#xff1a;将所有发向自己端口的数据&#xff0c;都转发到内网的计算机。 访…

github删除自己的仓库

测试Github的时候新建了很多仓库&#xff0c;但是后来想删除&#xff0c;找了半天居然没有找到按钮。 我就推测这个删除的功能肯定藏起来了&#xff0c;后来度娘了一下&#xff0c;发现果然在一个比较隐蔽的位置&#xff0c;不知道以后这个功能会不会改到一个比较明显的位置吧…

c++ 归并排序

归并排序是一种遵循分而治之方法的排序算法。它的工作原理是递归地将输入数组划分为较小的子数组并对这些子数组进行排序&#xff0c;然后将它们合并在一起以获得排序后的数组。 简单来说&#xff0c;归并排序的过程就是将数组分成两半&#xff0c;对每一半进行排序&#xff0c…

原子学习笔记5——点亮 LED

一、应用层操控设备的两种方式 应用层如何操控底层硬件&#xff0c;同样也是通过文件 I/O 的方式来实现&#xff0c;设备文件便是各种硬件设备向应用层提供的一个接口&#xff0c;应用层通过对设备文件的 I/O 操作来操控硬件设备&#xff0c;譬如 LCD 显示屏、串口、按键、摄像…

面向对象设计之套路——设计模式

1、总则 面向对象的分析设计编程思想&#xff0c;通过封装、继承、多态把程序的耦合度降低&#xff0c;用设计模式使得程序更加灵活&#xff0c;容易修改&#xff0c;并且易于复用。 让业务逻辑与界面逻辑分开&#xff0c;让它们的耦合度下降&#xff0c;只有分离&#xff0c;…

nginx--FastCGI

CGI 概念 nginx通过与第三方基于协议实现&#xff0c;即通过某种特定协议将客户端请求转发给第三方服务处理&#xff0c;第三方服务器会新建新的进程处理用户的请求&#xff0c;处理完成后返回数据给Nginx并回收进程(下次处理有需要新建)&#xff0c;最后nginx在返回给客户端…

Jenkins流水线部署Maven项目

使用Jenkins的流水线功能&#xff0c;构建部署Java Maven项目&#xff0c;步骤很简单但是不少细节需要注意。 一、安装 Jenkins的安装步骤和流程就不具体描述&#xff0c;这里主要介绍一下安装时要注意的几个问题。 1、Jenkins尽量安装最新的几个版本&#xff0c;否则安装完成…