业务场景

由于业务需要导出如下图中订单数据和订单项信息,而一个订单对应多个订单项,所以会涉及到自定义合并行

1.简单处理
项目使用的EasyExcel,经查找发现Excel种有个AbstractMergeStrategy抽象类,可以用于合并单元格。
于是先简单的写一个工具类实现根据数据自定义合并单元行,基本思路是获取当前单元格内容和上一行的单元格内容比对,如果相同则添加合并区域,如果不同则不处理,如果上一个单元格在合并区域中,则先移除合并区域再将当前单元格添加到合并区域中。

2.优化数据显示
第一个版本上线后财务反馈数据有问题。如图,求和数值实际应该是45,但是显示为90,导致财务不好对账

z

经排查发现图中C3、C5单元格虽然已经合并了,但是数据仍然存在,导致下拉选中的时候将他们的值也计算进去了。于是在1.0的基础上调整,将合并单元格仅保留首行数据,其他行内容直接清空

3.优化合并策略
第二版上线后数据问题已经解决,但是财务反馈导出大量数据时太慢。本来打算调整为异步导出解决此问题,但是经过测试发现10000条数据如果不合并直接生成excel只要几秒,但是使用合并自定义合并策略就非常慢,需要一二十分钟,这个时间差大的太离谱了,于是查看合并策略代码有哪些地方可以优化的。
经过查看代码可以发现在上述2.1步骤中一直查找合并单元格数据,然后一直删除再新增。假设10000条数据,有3列需要自动合并,每三行合并,执行以上代码会执行6666️3次新增和3333️3次删除,大大的影响了效率。于是调整代码,处理数据时只保存需要合并的单元格信息,导出完成再统一添加合并信息到sheet

经过测试,原本生成文件需要20分钟左右,现优化到只需要20多秒了。

工具类

/**
* excel线程上下文.
*
*/
public class ExcelThreadContext {

private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = ThreadLocal.withInitial(HashMap::new);

public static void clear() {
THREAD_LOCAL.remove();
}

public static void setData(String key, Object value) {
Map<String, Object> map = get();
map.put(key, value);
}

public static Integer getInteger(String key) {
return getInteger(key, 1);
}

public static Integer getInteger(String key, Integer defaultValue) {
Map<String, Object> map = get();
return Convert.toInt(map.get(key), defaultValue);
}

public static <K, V> Map<K, V> getMap(String key) {
return getMap(key, new HashMap<>());
}

public static <K, V> Map<K, V> getMap(String key, Map<K, V> defaultValue) {
Map<String, Object> map = get();
try {
return (Map<K, V>) map.getOrDefault(key, defaultValue);
} catch (Exception e) {
return defaultValue;
}
}

public static <T> T getObject(String key) {
return getObject(key, null);
}

public static <T> T getObject(String key, T defaultValue) {
Map<String, Object> map = get();
try {
return (T) map.getOrDefault(key, defaultValue);
} catch (Exception e) {
return defaultValue;
}
}

private static void set(Map<String, Object> map) {
THREAD_LOCAL.set(map);
}

public static Map<String, Object> get() {
return THREAD_LOCAL.get();
}
}

因为数据是存储在线程中的,需要每次使用后清理线程数据

EasyExcel合并行处理并优化的更多相关文章

  1. 互联网IP合全局路由优化的原则-Dijkstra算法证明

    周末继续写东西的一半填补了,为了达到完美的一天.我们知道一个事实,IP地址太多.统一管理是不可能的了,无论从控制平面从数据/管理层表示,飞机是如此. 所以.IP协议被设计为可伸缩.供IP路由术语,跳路 ...

  2. MySQL数据库基础知识及优化

    MySQL数据库基础知识及优化必会的知识点,你掌握了多少? 推荐阅读: 这些必会的计算机网络知识点你都掌握了吗 关于数据库事务和锁的必会知识点,你掌握了多少? 关于数据库索引,必须掌握的知识点 目录 ...

  3. 记一次 Java 导出大批量 Excel 优化

    常用的excel导出方案,详情见Spring Boot 入门(十二):报表导出,对比poi.jxl和esayExcel的效率,其中jxl.esayEscel 底层都是基于 poi,它们仅仅是对 poi ...

  4. 基于Kafka+ELK搭建海量日志平台

    早在传统的单体应用时代,查看日志大都通过SSH客户端登服务器去看,使用较多的命令就是 less 或者 tail.如果服务部署了好几台,就要分别登录到这几台机器上看,等到了分布式和微服务架构流行时代,一 ...

  5. Fastjson到了说再见的时候了

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  6. 局部线性嵌入(LLE)原理总结

    局部线性嵌入(Locally Linear Embedding,以下简称LLE)也是非常重要的降维方法.和传统的PCA,LDA等关注样本方差的降维方法相比,LLE关注于降维时保持样本局部的线性特征,由 ...

  7. FPGA设计思想与技巧(转载)

    题记:这个笔记不是特权同学自己整理的,特权同学只是对这个笔记做了一下完善,也忘了是从那DOWNLOAD来的,首先对整理者表示感谢.这些知识点确实都很实用,这些设计思想或者也可以说是经验吧,是很值得每一 ...

  8. 2017年10月WEB前端开发实习生面试题总结

    从大一开始学习前端,今年大三,10月份开始投简历,陆续收到很多家公司的面试,目前为止的面试通过率是百分之百,总结下面试题. 不定期更新中... 百度第一次 一面 1.AJAX流程 2.promise简 ...

  9. 前端三部曲之Html -- 1(html的基本结构和常见的meta标签的作用)

    一个H5页面的基本结构是什么 我么在编辑器中输入html:5可以得到 <!DOCTYPE html> <!-- 声明文档类型 --> <html lang="e ...

  10. 模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理、分类及应用

    模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理.分类及应用 lqfarmer 深度学习研究员.欢迎扫描头像二维码,获取更多精彩内容. 946 人赞同了该文章 Atte ...

随机推荐

  1. Beautiful of programming

    作者:Linus Torvalds 我不知道该如何清楚地描述我对编程的痴迷.对编程的人来说,这是世界上最有趣的事情.这是一个比国际象棋更复杂的游戏,在这个游戏中,你可以制定自己的规则,并基于这些规则得 ...

  2. nodejs安装和环境配置

    nodejs安装和环境配置 1.下载安装node.js 官方下载地址: https://nodejs.org/en/ 下载LTS版本(长期稳定版本) 安装可以更改安装路径(我的更改是D:\Progra ...

  3. st包无效

    本机正常安装了 oracle11g  和 ArcSDE10, 想要查询某个空间图层表的shape字段值,所以写了如下sql语句在PL/SQL里执行,select sde.st_astext(shape ...

  4. uni-app Vue3项目引入Tailwind CSS

    前情 Tailwind CSS 是一个原子类 CSS 框架,它将基础的 CSS 全部拆分为原子级别,同时还补全各种浏览器模式前缀,兼容性也不错.它的工作原理是扫描所有 HTML 文件.JavaScri ...

  5. Qt tr 无法翻译

    项目中碰到部分tr无法翻译的问题,最后发现由于继承QObject的子类没有加上Q_OBJECT宏.

  6. 数据库开发规范v1.0

    一.建表规约 [强制]表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint( 1 表示是,0 表示否). 说明:任何字段如果为非负数,必须是 unsi ...

  7. 东方通TongWeb7.0.4.9M4部署SuperMap iServer 11.2.1

    一.软件版本 操作系统: CentOS Linux release 7.5.1804 (Core) JDK:11.0.18 东方通:TongWeb7.0.4.9M4 SuperMap iServer: ...

  8. GooseFS透明加速能力,助力加速 CosN 访问 COS 的性能

    01 前言 原生的对象存储接口协议并不兼容HDFS文件语义,因此对象存储COS提供了COSN工具这一的标准的 Hadoop 文件系统实现,可以为 Hadoop.Spark 以及 Tez 等大数据计算框 ...

  9. bytecode 生成器

    基础 objectweb asm 很难用,找了几个高级点的. activej codegen 这个库很像 .net DLR 风格,采用 Expression 抽象,例如 Expressions.add ...

  10. drf知识点

    目录 drf知识点 1.web应用模式.API接口.接口测试工具postman.restful规范 2.序列化与反序列化的概念.基于django原生编写5个接口.drf介绍和快速使用.cbv源码分析 ...