easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置

本文主要是介绍easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency>

一,分批导入

1.首先配置表格头映射类
@Getter
@Setter
@EqualsAndHashCode
public class IndexOrNameData {/*** 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配*/@ExcelProperty(index = 2)private Double doubleData;/*** 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据*/@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;
}
2.编写excel数据读监听器
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class DemoDataListener implements ReadListener<IndexOrNameData > {/*** 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;/*** 缓存的数据*/private List<IndexOrNameData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private DemoDAO demoDAO;public DemoDataListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数demoDAO = new DemoDAO();}/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来** @param demoDAO*/public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;}/*** 这个每一条数据解析都会来调用** @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*/@Overridepublic void invoke(IndexOrNameData  data, AnalysisContext context) {log.info("解析到一条数据:{}", JSON.toJSONString(data));cachedDataList.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();log.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {log.info("{}条数据,开始存储数据库!", cachedDataList.size());demoDAO.save(cachedDataList);log.info("存储数据库成功!");}
}

分批插入的实现是在invoke方法中,当读取缓存数达到我们预期的插入数量时就进行插入,然后重新更新list,原本的list就会被回收,达到方式内存溢出的效果,可以在这个方法中进行行参数校验,有异常抛出即可

3.编写读入方法
 // 写法1:fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, IndexOrNameData.class, new DemoDataListener()).sheet().doRead();// 写法2fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 一个文件一个readertry (ExcelReader excelReader = EasyExcel.read(fileName, IndexOrNameData.class, new DemoDataListener()).build()) {// 构建一个sheet 这里可以指定名字或者noReadSheet readSheet = EasyExcel.readSheet(0).build();// 读取一个sheetexcelReader.read(readSheet);}

二,动态表头分批导出

1.构建表头和数据
//获取表头    
private static List<String> makeHeads() {List<String> heads = new ArrayList<>(); //表头信息heads.add("唯一标识");heads.add("名称");heads.add("类型");return heads;}//获取数据private static List<Map<String, Object>> makeData() {List<Map<String, Object>> list = new ArrayList<>();//Map<String,Object> test1 = new LinkedHashMap<>(); //手动添加测试数据(可根据需要从数据库查询)test1.put("id", 1);test1.put("name", 2);test1.put("str", 3);list.add(test1);//Map<String,Object> test2 = new LinkedHashMap<>();test2.put("id", 11);test2.put("name", 22);test2.put("str", 33);list.add(test2);return list;}
2.写出代码
    public void exportExcel(HttpServletResponse httpServletResponse,@RequestParam(required = false) String fileName,@RequestParam(required = false) List<String> heads, @RequestParam(required = false) List<Map<String, Object>> list) throws IOException {if (StringUtils.isEmpty(fileName)){ //文件名称也可以动态获取fileName = System.currentTimeMillis() + ".xlsx";} else {fileName = fileName + ".xlsx";}if(heads == null || heads.size() == 0){heads = makeHeads();}if(list == null || list.size() == 0){list = makeData();}OutputStream os= responseInfo(httpServletResponse, fileName); // 调用responseInfo方法List<List<String>> hs = new ArrayList<>();for (String s : heads) {hs.add(Arrays.asList(s));}List<List<Object>> list2 = new ArrayList<>();for (int i = 0; i < list.size(); i++) {List<Object> objects = new ArrayList<>();Collection<Object> values = list.get(i).values();for (Object value : values) {objects.add(value.toString());}list2.add(objects);}// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 背景设置为红色headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)20);headWriteCellStyle.setWriteFont(headWriteFont);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 背景绿色contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小contentWriteFont.setFontHeightInPoints((short)20);contentWriteCellStyle.setWriteFont(contentWriteFont);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy horizontalCellStyleStrategy =new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);//创建一个行高设置处理器,我这里直接用匿名内部类类了AbstractRowHeightStyleStrategy abstractRowHeightStyleStrategy = new AbstractRowHeightStyleStrategy() {@Overrideprotected void setHeadColumnHeight(Row row, int relativeRowIndex) {if (relativeRowIndex==0){row.setHeightInPoints(50);}else {row.setHeightInPoints(10);}}@Overrideprotected void setContentColumnHeight(Row row, int relativeRowIndex) {//默认主体的高度row.setHeightInPoints(10);}};//创建列宽设置处理器AbstractHeadColumnWidthStyleStrategy abstractHeadColumnWidthStyleStrategy = new AbstractHeadColumnWidthStyleStrategy() {@Overrideprotected Integer columnWidth(Head head, Integer columnIndex) {switch (columnIndex) {case 0:return 6;case 1:return 20;case 2:return 20;default:return 13;}}};WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();//开始写出ExcelWriter build = EasyExcel.write(os).head(hs)//注册内容以及表头处理器.registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle ,contentWriteCellStyle))//注册行高处理器.registerWriteHandler(abstractRowHeightStyleStrategy)//注册列宽处理器.registerWriteHandler(abstractHeadColumnWidthStyleStrategy).build();//然后就可以用上边的buid对象往指定的sheet中写入数据了,当数据量大的时候,我们就可以分批写入,伪代码如下for(a a:list){build.write(list2,writeSheet);}}/*** 功能:公用方法,写回浏览器* [response, fileName]* @return {@link OutputStream}* @throws*/public static OutputStream responseInfo(HttpServletResponse response, String fileName) throws IOException {// 这里注意有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postmanresponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment; filename*=utf-8''" + fileName);OutputStream os=response.getOutputStream();return os;}/*** 如果要兼容swagger用这个,上面的注释掉* 功能:公用方法* 参数:fileName 文件名称, 如:123.xlsxpublic static OutputStream responseInfo(HttpServletResponse response, String fileName) throws IOException {response.setCharacterEncoding("utf-8");response.setContentType("APPLICATION/OCTET-STREAM");response.addHeader("Content-Disposition", "attachment;filename=" + fileName);OutputStream os=response.getOutputStream();return os;}*/

这篇关于easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403764

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

SpringBatch数据写入实现

《SpringBatch数据写入实现》SpringBatch通过ItemWriter接口及其丰富的实现,提供了强大的数据写入能力,本文主要介绍了SpringBatch数据写入实现,具有一定的参考价值,... 目录python引言一、ItemWriter核心概念二、数据库写入实现三、文件写入实现四、多目标写入

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

SpringSecurity JWT基于令牌的无状态认证实现

《SpringSecurityJWT基于令牌的无状态认证实现》SpringSecurity中实现基于JWT的无状态认证是一种常见的做法,本文就来介绍一下SpringSecurityJWT基于令牌的无... 目录引言一、JWT基本原理与结构二、Spring Security JWT依赖配置三、JWT令牌生成与

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL