easyexcel将对象处理为多列,自增序列

概述

主要记录在开发中遇到的问题:使用easyexcel导出excel,一般数据都是保存在数据库中,如果查询返回的是一个实体类,且里面有嵌套的实体类对象,这时导出的时候要先对查询出的数据进行业务逻辑处理,让它符合导出规范,但是当数据量很大时,容易jvm内存,easyexcel(CellDataTypeEnum)只支持基本数据类型的导入,如图1-1所示,可以通过自定义数据类型(Converter)进行转换,但是这样只能返回一种基本的数据类型,像这种实体类里面通常会有很多信息,如果都要导出,这种方式也不合适。目前我能想到的方式是通过它提供的各种拦截器处理,大概流程如下:

通过自定义数据类型将实体类转换为String类型,然后通过拦截器将字符串拆分,添加对应列的数据。

图1-1 excel内部支持的数据类型

代码展示

  • excel日期转换类

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;import java.text.SimpleDateFormat;
import java.util.Date;/*** @Description excel日期转换类 即将Mongo中类型为long的时间戳转化为yyyy-MM-dd HH:mm:ss时间* @author HuangAnting* @date 2022/4/8 10:16
*/
public class DateConverter implements Converter<Long> {@Overridepublic Class<?> supportJavaTypeKey() {//对象属性类型return Long.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {//CellData属性类型return CellDataTypeEnum.STRING;}@Overridepublic WriteCellData<?> convertToExcelData(WriteConverterContext<Long> context) throws Exception {//对象属性转CellDataLong cellValue = context.getValue();new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(cellValue));if (cellValue == null) {return new WriteCellData<>("");} else {return new WriteCellData<>( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(cellValue)));}}
}
  • 自增序号拦截器
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;/*** @Description 自增序号拦截器* @author HuangAnting* @date 2022/4/12 17:27
*/
public class IndexRowWriteHandler implements RowWriteHandler {private static final String FIRST_CELL_NAME = "序号";/*** 序号的样式,与其他列保持一样的样式*/private CellStyle firstCellStyle;private String description;/*** 列号*/private int count = 0;public IndexRowWriteHandler(String description){this.description = description;}@Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {// 每一行首列单元格Cell indexCell = row.createCell(0);if(!isHead){indexCell.setCellValue(++count);try {row.getCell(3).setCellValue(description);}catch (Exception e){}}else {Workbook workbook = writeSheetHolder.getSheet().getWorkbook();firstCellStyle = firstCellStyle(workbook);indexCell.setCellValue(FIRST_CELL_NAME);indexCell.setCellStyle(firstCellStyle);writeSheetHolder.getSheet().setColumnWidth(0, 6 * 256);}}/*** excel首列序号列样式* @param workbook* @return*/public  CellStyle firstCellStyle(Workbook workbook) {CellStyle cellStyle = workbook.createCellStyle();//居中cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 灰色cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//设置边框cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setBorderRight(BorderStyle.THIN);cellStyle.setBorderTop(BorderStyle.THIN);//文字Font font = workbook.createFont();font.setBold(Boolean.TRUE);cellStyle.setFont(font);return cellStyle;}
}
  • 实体类
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.hat.easyexcel_export.excel.DateConverter;
import com.hat.easyexcel_export.excel.MonPointConverter;
import lombok.Data;/*** @Description 导出实体类* @author HuangAnting* @date 2022/4/12 17:26
*/
@Data
public class Car {/** 名称*/@ExcelProperty(value = "名称",index = 1)private String name;/** 价格*/@ExcelProperty(value = "价格",index = 2)private Double price;/** 描述*/@ColumnWidth(15)@ExcelProperty(value = "描述",index = 3)private String description;/** 坐标*/@ExcelProperty(value = "坐标",converter = MonPointConverter.class,index = 4)private MonPoint monPoint;/** 日期*/@ExcelProperty(value = "日期",converter = DateConverter.class)private Long createDate;
}
  • 自定义对象拦截器

import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.fastjson.JSONObject;
import com.hat.easyexcel_export.entity.MonPoint;
import org.apache.poi.ss.usermodel.*;/*** @Description 行拦截器 将字符串的经纬度转换成两列数据* @author HuangAnting* @date 2022/4/12 17:26
*/
public class CustomRowWriteHandler implements RowWriteHandler {/*** 序号的样式,与其他列保持一样的样式*/private CellStyle firstCellStyle;private static final String LON_CELL_NAME = "经度";private static final String LAT_CELL_NAME = "纬度";/*** 列号*/@Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean isHead) {Cell cell = row.getCell(4);row.removeCell(cell);Cell lon = row.createCell(4);Cell lat = row.createCell(5);if (!isHead) {String stringCellValue = cell.getStringCellValue();try {MonPoint monPoint = JSONObject.parseObject(stringCellValue, MonPoint.class);lon.setCellValue(monPoint.getLon());lat.setCellValue(monPoint.getLat());}catch (Exception e){}}else {Workbook workbook = writeSheetHolder.getSheet().getWorkbook();firstCellStyle = firstCellStyle(workbook);lon.setCellStyle(firstCellStyle);lat.setCellStyle(firstCellStyle);lon.setCellValue(LON_CELL_NAME);lat.setCellValue(LAT_CELL_NAME);}}/*** excel首列序号列样式** @param workbook* @return*/public CellStyle firstCellStyle(Workbook workbook) {CellStyle cellStyle = workbook.createCellStyle();//居中cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 灰色cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//设置边框cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setBorderRight(BorderStyle.THIN);cellStyle.setBorderTop(BorderStyle.THIN);//文字Font font = workbook.createFont();font.setBold(Boolean.TRUE);cellStyle.setFont(font);return cellStyle;}
}

gitee地址:easyexcel_export

以上仅代表本人对easyexcel的认识和了解,欢迎大家批评指正。

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

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

相关文章

python做excel表格代码_python操作excel表格

我们在写测试用例的时候&#xff0c;是创建一个表格.xlsx&#xff0c;然后把各种条件加到这张表格中去&#xff0c;所以&#xff0c;如何对excel表格操作&#xff0c;是相当重要的一环&#xff0c;那么&#xff0c;接下来&#xff0c;这篇博客就直接教会大家如何通过python去处…

Windows 查看程序ip地址(面对小白)

前言&#xff1a;Windows自带资源管理器可以查看程序的IP地址。下面以微信通话为例&#xff0c;详细步骤如下(面向小白)&#xff1a; 打开任务管理器 打开方法(以下方法都可以)&#xff1a; 键盘按住 【ctrl】 【alt】 【delete】 ,选择【任务管理器】Windows 10 以下系统…

【转】C#中相同不同程序集存在相同的命名空间的时候的冲突解决办法

快速解决办法描述描述: 1.将相同命名空间的不同程序集分别进行取别名&#xff1a;【具体操作:右击相同程序的引用&#xff0c;在别名上修改&#xff0c;默认的为global】。 2.调用&#xff1a;在所在调用文件里面最前面写 extern alias 别名&#xff0c;然后using 别名.Names…

chrome webdriver_(最新版)如何正确移除Selenium中的 window.navigator.webdriver

摄影&#xff1a;产品经理产品经理的三文鱼炒饭在《一日一技&#xff1a;如何正确移除Selenium中window.navigator.webdriver的值》一文中&#xff0c;我们介绍了在当时能够正确从Selenium启动的Chrome浏览器中移除window.navigator.webdriver的方法。后来时过境迁&#xff0c;…

【转】2.3async中必须始终返回Task(@Ron.liang)

Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章 目录 前言1. 异常的发生来得太突然2. 问题所在3. 问题的解决方案前言 事情的起因是由于一段简单的数据库连接代码引起&#xff0c;这段代码从语法上看&#xff0c;是没有任何问题&#xff1b;但是就是莫名其妙的报…

php隐藏webshell_PHP 安全的十个必备技巧

在这篇文章中&#xff0c;我将尝试为你提供一些可以提高 PHP 应用程序安全性的具体步骤。我关注的是 PHP 配置本身&#xff0c;所以我们不会讨论 SQL 注入、HTTPS 或其他与 PHP 无关的问题。我将使用我的 docker-entrypoint.sh 脚本中的 bash 行来说明示例&#xff0c;但当然你…

aop实现原理_Java:由浅入深揭开 AOP 实现原理

点击上方“Java专栏”&#xff0c;选择“置顶或者星标”第一时间阅读精彩文章&#xff01;1、☞ 程序员进阶必备资源免费送「21种技术方向&#xff01;」 点击查看☜2、☞ 《Java面试手册》.PDF 点击查看作者&#xff1a;马佩juejin.im/post/5bf4fc84f265da611b57f906概述&a…

【转】C#进阶系列——WebApi 接口参数不再困惑:传参详解

阅读目录 一、get请求 1、基础类型参数2、实体作为参数3、数组作为参数4、“怪异”的get请求二、post请求 1、基础类型参数2、实体作为参数3、数组作为参数4、后台发送请求参数的传递三、put请求 1、基础类型参数2、实体作为参数3、数组作为参数四、delete请求五、总结正文 前…

【转】01Teams的前世今生

说到Teams&#xff0c;这到底是一个什么产品&#xff1f;有人说它是团队协作工具&#xff0c;有人说它是云视频系统&#xff0c;有人说它是Hub&#xff0c;还有人说它是微软有史以来发展最快的一个产品&#xff0c;还有人说它完全是一个高效办公神器。其实都是对的。 Teams集成…

oracle insert 当前时间_Oracle知识点总结

目录1、Oracle的安装与下载2、基础查询3、条件查询 1)对比运算符 2)逻辑运算符 3)模糊查询 4)排序4、函数 1)数值函数 2)字符函数 3)时间日期函数 4)转换函数 5)通用函数5、聚合函数6、分组查询在学习Oracle之前&#xff0c;需要先有一定的数据库基…

【转】C#各类控件的输入输出(思维导图、知识点分析、案例解析)

第六周学习笔记—C#各类控件的输入输出 1.思维导图 知识点汇总&#xff1a; 着重介绍几个常用控件&#xff1a; 数据显示控件 DataGridView控件 列设置 a)、列的宽度铺满这个控件 设置如下&#xff1a;把AutoSizeColumnsModeFill;//可以在属性窗口中设置 b)、列名居中 代…

sqlserver连接字符串_10分钟使用EF Core连接MSSQL数据库

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;Ron.liangcnblogs.com/viter/p/10243577.html前言在 .NET Core 2.2中Microsoft.AspNetCore.App 默认内置了EntityFramework Core 包&#xff0c;所以在使用过程中&#xff0c;我们无需再从NuGet仓库单独应用 EFCore 包…

【转】ADO.Net之SqlConnection、 Sqlcommand的应用学习心得(思维导图,知识解析,案例分析)

ADO.Net之SqlConnection、 Sqlcommand的应用 一、思维导图&#xff1a; ADO.NET与SQL连接&#xff1a; 二、知识点介绍&#xff1a; SqlConnection和Sqlcommand都是组成数据提供程序的类。 SqlConnection使用它来建立和数据库的连接&#xff0c;Sqlcommand使用它执行SQL命令…

professional中文_Microsoft office 2007 简体中文版

点击蓝字 关注小白软件名称&#xff1a;Microsoft office 2007软件语言&#xff1a;简体中文软件大小&#xff1a;0.67GB安装环境&#xff1a;Win10/8/7下载链接&#xff1a;https://pan.baidu.com/s/1DybozQ-rn-t2s2EC7FrvFw 提取码&#xff1a;zoa0安装步骤1、解压安装包&…

【转】设计模式 ( 十七) 状态模式State(对象行为型)

设计模式 ( 十七) 状态模式State&#xff08;对象行为型&#xff09; 1.概述 在软件开发过程中&#xff0c;应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到。然后使用if... ellse语句来做状态判断来进行不同情况的处理。…

【OSG学习】准备开发调试环境

环境 本人当前使用的环境是VS2013 Ultimate Update5 WIN10。 OSG编译安装 下载编译OSG源码不要克隆github上的源码&#xff0c;而是下载稳定版本的OSG源码进行编译。因为github上的源码处于开发阶段&#xff0c;我们应该优先选择稳定版本&#xff0c;我使用的是OpenSceneGr…

【Qt开发经验】Qt信号槽连接不成功问题原因汇总

以下几种情况会导致信号槽连接不成功&#xff0c;下面分别描述。 1. 拥有信号槽的类&#xff0c;必须继承QObject&#xff0c;声明Q_OBJECT宏。 Qt帮助手册里搜索 “Signals & Slots”&#xff0c;可以看到以下说明&#xff1a; 想要使用信号槽&#xff0c;必须继承QOb…

【转】.Net中的异步编程总结

一直以来很想梳理下我在开发过程中使用异步编程的心得和体会&#xff0c;但是由于我是APM异步编程模式的死忠&#xff0c;当TAP模式和TPL模式出现的时候我并未真正的去接纳这两种模式&#xff0c;所以导致我一直没有花太多心思去整理这两部分异步编程模型。今天在CodeProject上…

学习swing鼠标点击事件心得体会_西门子COMOS软件开发定制学习8-查询列表间的数据交互...

​本篇在西门子COMOS软件开发定制学习6-管理界面定制基础上定制&#xff0c;简单介绍两个查询列表之间的数据交互。实现效果&#xff1a;在左侧列表中选择某一设备&#xff0c;右侧列表自动根据所选设备&#xff0c;显示该设备相关的设计图纸(如PID图纸或电气图纸等)&#xff1…

【转】异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

最近我为大家陆续介绍了“IAsyncResult异步编程模型 (APM)”和“基于事件的异步编程模式(EAP)”两种异步编程模型。在.NET4.0 中Microsoft又为我们引入了新的异步编程模型“基于任务的异步编程模型(TAP)”&#xff0c;并且推荐我们在开发新的多线程应用程序中首选TAP&#xff0…