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

相关文章

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服