复杂excel导出(动态列,按条件改背景色)

  • 依赖
  • 工具类
  • 测试用例

依赖

            <!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>

工具类

@Data
@Slf4j
public class ExcelExportUtil {private static final Logger log = LoggerFactory.getLogger(ExcelExportUtil.class);//给每一列设置一个key值,key值和表头根据数组位置对应;//数据和样式每行各一个map,根据key值进行填充;//样式内容放在一个map内,方便取用。/**各个列的表头*/private List<String> headList;/**各个列的key值*/private List<String> headKey;/**各个列的宽度*/private List<Integer> headWidth;/**需要填充的数据信息*/private List<HashMap> data;/**需要填充的表格样式,key是列的key,value是具体样式的key*/private List<HashMap<String,String>> cellStyleList;/** 样式列表 */private Map<String, CellStyle> styles;/**字体大小*/private int fontSize = 14;/**行高*/private int rowHeight = 30;/**列宽*/private int columWidth = 200;/**工作表*/private String sheetName = "sheet";/**文件名*/private String fileName;HSSFWorkbook wb;HSSFSheet sheet;HSSFCellStyle headCellStyle;HttpServletResponse response;public ExcelExportUtil() {this.wb = new HSSFWorkbook();}public ExcelExportUtil exportExport(HttpServletResponse response) throws IOException {this.response = response;int size = data.size();int count = (size - 1) / 50000 + 1;for (int i = 0; i < count; i++) {sheet = wb.createSheet(sheetName + (i + 1));exportExport(sheet,data.subList(i * 50000, ((i + 1) * 50000 > size ? size : 50000 * (i + 1))));}return this;}private void exportExport(HSSFSheet sheet, List<HashMap> data) throws IOException{//检查参数配置信息checkConfig();HSSFCellStyle cellStyle = wb.createCellStyle();HSSFDataFormat format = wb.createDataFormat();//这样才能真正的控制单元格格式,@就是指文本型cellStyle.setDataFormat(format.getFormat("@"));cellStyle.setAlignment(HorizontalAlignment.RIGHT);HSSFRow headRow = sheet.createRow(0);//设置列头元素for (int i = 0; i < headList.size(); i++) {Integer width = 15;if (headWidth != null && headWidth.size() >= headList.size()){width = headWidth.get(i);}sheet.setColumnWidth(i, 256 * width + 184);HSSFCell cellHead = headRow.createCell(i);cellHead.setCellValue(headList.get(i));cellHead.setCellStyle(headCellStyle);}//开始写入实体数据信息int a = 1;for (int i = 0; i < data.size(); i++) {HSSFRow row = sheet.createRow(a);HashMap map = data.get(i);HashMap styleMap = cellStyleList.get(i);HSSFCell cell;for (int j = 0; j < headKey.size(); j++) {cell = row.createCell(j);Object valueObject = map.get(headKey.get(j));if (valueObject == null) {valueObject = "";}if (valueObject instanceof Integer) {//取出的数据是Integercell.setCellValue(((Integer) (valueObject)).floatValue());cell.setCellType(CellType.NUMERIC);} else if (valueObject instanceof BigDecimal) {//取出的数据是BigDecimalcell.setCellValue(((BigDecimal) (valueObject)).floatValue());cell.setCellType(CellType.NUMERIC);} else if (valueObject instanceof Double) {//取出的数据是BigDecimalcell.setCellValue((Double) valueObject);cell.setCellType(CellType.NUMERIC);}else {//取出的数据是字符串直接赋值cell.setCellValue(StringUtils.isEmpty(String.valueOf(valueObject)) ? "" : String.valueOf(valueObject));}if(styleMap.get(headKey.get(j))!=null){cell.setCellStyle(styles.get(styleMap.get(headKey.get(j))));}else{cell.setCellStyle(cellStyle);}}a++;}}public void flushExplorer() throws Exception{// 告诉浏览器用什么软件可以打开此文件response.setHeader("content-Type", "application/vnd.ms-excel");// 下载文件的默认名称response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "utf-8"));try {wb.write(response.getOutputStream());}catch (Exception e){log.error("导出Excel异常{}", e.getMessage());throw new UtilException("导出Excel失败,请联系网站管理员!");}finally{IOUtils.closeQuietly(wb);}}public HSSFCellStyle getHSSFCellStyle(){return wb.createCellStyle();}/*** 检查数据配置问题** @throws IOException 抛出数据异常类*/protected void checkConfig() throws IOException {if (headKey == null) {throw new IOException("表头不能为空");}if (headWidth != null && headWidth.size() < headKey.size()){throw new IOException("设置宽度的列数必须超过表头列数");}if (fontSize < 0 || rowHeight < 0 || columWidth < 0) {throw new IOException("字体、宽度或者高度不能为负值");}if (StringUtils.isEmpty(sheetName)) {throw new IOException("工作表表名不能为NULL");}createDefaultHeadStyle();}public void createDefaultHeadStyle() {//创建表头样式headCellStyle= wb.createCellStyle();//居中headCellStyle.setAlignment(HorizontalAlignment.CENTER);//背景色headCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);headCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_50_PERCENT.getIndex());//字体HSSFFont font = wb.createFont();font.setFontName("Arial");font.setColor(IndexedColors.WHITE.getIndex());font.setFontHeightInPoints((short)10);//字体增粗font.setBold(true);         headCellStyle.setFont(font);headCellStyle.setBorderBottom(BorderStyle.THIN); // 下边框headCellStyle.setBorderLeft(BorderStyle.THIN);// 左边框headCellStyle.setBorderTop(BorderStyle.THIN);// 上边框headCellStyle.setBorderRight(BorderStyle.THIN);// 右边框}
}

测试用例

 @GetMapping("/exportSum")public void exportSum(HttpServletResponse response, AttendanceCountDetail detail) throws Exception {/*表头*/List<String> headList = new ArrayList<>();/*表头对应的key值*/List<String> headKey = new ArrayList<>();/*每一列的宽度*/List<Integer> widList = new ArrayList<>();headList.add("开始");headKey.add("begin");widList.add(15);headList.add("结束");headKey.add("end");widList.add(15);headList.add("总出勤天数");headKey.add("sumDays");widList.add(13);headList.add("夜班天数");headKey.add("yeDays");widList.add(13);Date tmp = DateUtils.dateTime("yyyyMMdd","20220925");Date  endDate =  DateUtils.dateTime("yyyyMMdd","20221024");HashMap holidays = HolidayUtil.getHoliday(2022);// 动态列,日期,同时节假日标注工资倍数while (tmp.getTime() <= endDate.getTime()) {Integer yyyyMMdd = Integer.valueOf(DateUtils.fmtDateToStr(tmp, "yyyyMMdd"));if(holidays.get(yyyyMMdd)!=null){headList.add(DateUtils.fmtDateToStr(tmp,"MM/dd")+"("+holidays.get(yyyyMMdd)+"倍"+")");headKey.add(DateUtils.fmtDateToStr(tmp,"yyyyMMdd"));}else{headList.add(DateUtils.fmtDateToStr(tmp,"MM/dd"));headKey.add(DateUtils.fmtDateToStr(tmp,"yyyyMMdd"));}widList.add(8);// 天数加上1tmp = DateUtils.addDays(tmp,1);}/*数据集合,每行一个hashmap*/ArrayList<HashMap> dataList = new ArrayList<>();/*样式集合,每行一个hashmap,再根据value去具体样式的hashmap找cellStyle*/ArrayList<HashMap<String, String>> styleList = new ArrayList<>();Set set = new HashSet();HashMap<String, Object> dataMap = new HashMap<>();HashMap<String, String> styleMap = new HashMap<>();Integer sum = 1;Integer yeDays = 0;/**/ArrayList<AttendanceCountDetail> aList = attendanceCountService.getCountSum(detail);for (AttendanceCountDetail a : aList) {if (set.contains(a.getStaffName())) {/*加班时间判断*/if(a.getOverTimeStr()==null){dataMap.put(a.getInDate().toString(), "异常");}else if(a.getOverTimeStr()<0){dataMap.put(a.getInDate().toString(), "假");//请假}else{if(holidays.get(a.getInDate())!=null){dataMap.put(a.getInDate().toString(), a.getOverTimeStr()+8);}else {dataMap.put(a.getInDate().toString(), a.getOverTimeStr());}}/*夜班判断*/if(a.getBanciType() == AttendanceCountServiceImpl.Banci.YEBAN.value()){yeDays+=1;styleMap.put(a.getInDate().toString(), "bColor");}dataMap.put("end",a.getInDate());sum+=1;}else{if(dataMap.size()!=0) {dataMap.put("sumDays",sum);dataMap.put("yeDays",yeDays);dataList.add(dataMap);styleList.add(styleMap);dataMap = new HashMap<>();styleMap  = new HashMap<String, String>();sum = new Integer(0);yeDays = new Integer(0);}if(a.getStaffName()==null){break;}dataMap.put("begin",a.getInDate());/*加班时间判断*/if(a.getOverTimeStr()==null){dataMap.put(a.getInDate().toString(), "异常");}else if(a.getOverTimeStr()<0){dataMap.put(a.getInDate().toString(), "假");}else{if(holidays.get(a.getInDate())!=null){dataMap.put(a.getInDate().toString(), a.getOverTimeStr()+8);}else{dataMap.put(a.getInDate().toString(), a.getOverTimeStr());}}/*夜班判断*/if(a.getBanciType() == AttendanceCountServiceImpl.Banci.YEBAN.value()){yeDays+=1;styleMap.put(a.getInDate().toString(), "bColor");}dataMap.put("end",a.getInDate());sum+=1;}}ExcelExportUtil excelExportUtil = new ExcelExportUtil();/*存放具体样式*/HSSFCellStyle cellStyle = excelExportUtil.getHSSFCellStyle();cellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_YELLOW.getIndex());cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);HashMap<String, CellStyle> styles = new HashMap<>(1);styles.put("bColor",cellStyle);excelExportUtil.setStyles(styles);/*存放表头信息*/   excelExportUtil.setHeadList(headList);excelExportUtil.setHeadKey(headKey);excelExportUtil.setHeadWidth(widList);/*存放表格内容,样式id*/excelExportUtil.setCellStyleList(styleList);excelExportUtil.setData(dataList);excelExportUtil.setSheetName("考勤统计");excelExportUtil.setFileName("考勤");excelExportUtil.exportExport(response).flushExplorer();}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceCountDetail {/**姓名**/private String staffName;/**序列**/private String positionSeq;/**部门**/private String department;/**班次 1=白,2=夜,3=缺失,4=异常**/private Integer banciType;/**上班日期**/private Integer inDate;/**上班时间 **/private Integer inTime;/**下班日期**/private Integer outDate;/**下班时间**/private Integer outTime;/**加班时间(单位h,向下取最近的.5h)**/private Double overTimeStr;/**是否迟到  0:False   1:True **/private Integer isLate;}

复杂excel导出(动态列,条件背景色)相关推荐

  1. 使用easypoi导出excel实现动态列

    使用easypoi导出excel实现动态列 说明 使用的是easypoi进行导出 行头是动态生成 依据key进行列匹配,进行数据填充 第一列进行纵向动态合并 自己的一个使用,记录一下 工具依赖 < ...

  2. 阿里巴巴 Excel工具easyExcel 导出 - 动态列扩展。

    阿里巴巴 Excel工具easyExcel 导出 最近有个需要要求既要动态列扩展.又要列和数据对应.最重要的是一定要通用,满足当前项目的需求 无实体兼容实体对象动态列扩展. 1.实体类 import ...

  3. EXCEL导出动态表头

    一般在项目里需要导出数据时都是表头固定的,这样用EasyExcel导出时,只要先定义和POJO类,然后注释的方式定义好表头即可,如下: @Getter @Setter @EqualsAndHashCo ...

  4. 使用 easypoi 导出 excel 实现动态列,完美解决!

    点击关注公众号,利用碎片时间学习 说明 使用的是easypoi进行导出 行头是动态生成 依据key进行列匹配,进行数据填充 第一列进行纵向动态合并 自己的一个使用,记录一下 工具依赖 <depe ...

  5. Java Excel导出动态自定义单元格样式

    根据表格内容定义单元格样式 效果图: 文章描述两种,一种创建生成时定义样式,另一种在excel在写入文件前修改样式 关键代码一 /*** 数据动态设置样式** @param cell 单元格* @pa ...

  6. java poi excel导出

    直接上代码 0. pom依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypo ...

  7. Java之Excel导出工具类使用教程

    前言: 本工具类经过PostMan和web页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具. 市面上有很多封装好的导出工具(如:阿里的eas ...

  8. POI导出Excel设置背景色踩坑,解决背景色全黑(无效)的问题及指定列添加背景色,自定义颜色

    POI导出Excel设置背景色踩坑,解决背景色全黑的问题及指定列添加背景色,自定义颜色 一.自定义颜色 二.背景色全黑(无效)的问题解决![在这里插入图片描述](https://img-blog.cs ...

  9. java Excel导出功能之 不固定列表格

    背景:考勤周期为本月19号至上月20号,则每个月考勤周期表的列是动态变化的.所有数据显示和excel导出功能都需要动态的进行处理. 显示格式如下图 前端 checkin.jsp<%@ page ...

最新文章

  1. 一起来了解React的四种优秀甘特图方案(下篇)
  2. 周信东c语言实验二实验报告,周信东主编最新版C语言程序设计基础实验一实验报告.doc...
  3. 5折交叉验证_[Machine Learning] 模型评估——交叉验证/K折交叉验证
  4. docker 主机ip_docker容器指定ip
  5. 介绍一个好用的抓取dump的工具-ProcDump
  6. VS SPEC FLOW接口自动化之环境搭建及一个简单项目(一)
  7. Proxy 补充学习笔记
  8. 操作系统(一)计算机系统概述
  9. cmd查看所有数据库 db2_民生银行数据库自动化部署的探索与实践
  10. python列重命名_Python目录–创建,重命名,删除,列出,更改
  11. 【算法学习】将MSRCR中的模糊处理由FFT修改为时域纯高斯模糊
  12. 1001 Hello,World!
  13. C语言实现高尔顿钉板实验(模拟正态分布)
  14. Matlab分号的使用
  15. 十分钟django后台 simpleui -含自定义后台首页
  16. quartz mysql死锁问题_Quartz 并发
  17. VxWorks6.6运行简单的ACE/TAO CORBA程序
  18. 《响应式Web设计实践》一1.2 设备来了,设备来了
  19. 手机移动OA:指尖上也可以拥有会议助手
  20. html浪漫恋爱情侣表白网站模板-html创意情侣表白网站整站源码

热门文章

  1. 实验十四:Wireshark数据抓包分析之ARP协议
  2. 对Chrome OS不要有三个指望
  3. 【52ABP实战教程】0.2-- VSTS中的账号迁移到东亚
  4. 微信小程序--使用swiper实现滚动广告
  5. 社区团购系统市场分析
  6. 线上教育遭受DDoS攻击激增,你还能忽视DDoS防护吗?
  7. 04-WIFI通讯服务端搭建
  8. python字符串拼接带空格_使用Python连接字符串和空格
  9. Java值传递和地址传递的区别,看完这图就明白了
  10. 2015年12月31日播出《芈月传…