业务场景

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

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. 探索实用的Java工具类

    1.排序 有时需要对集合进行排序.此时可以使用Collections的sort方法. List<Integer> list = new ArrayList<>(); list. ...

  2. 记一次vsix安装异常

    vsix是vs扩展安装的包,里面包含了vs扩展功能的相关内容和元数据. 由于个人需求,我通过zip工具,对其中的许可文件进行了更新,将EULA.rtf替换为eula.txt.但在安装过程中报错,日志提 ...

  3. 在Python工具箱中,创建对应子工具集

    目录 问题描述 实现方法 问题描述 在Pro中,新建自定义工具箱后,直接通过操作可以添加工具集. 但是新建python工具箱后,却没有新建的操作.因为python工具箱的对象定义,都是在脚本中定义的, ...

  4. three.js优化

    Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用. three.js 性能优化方面,整理一下常用的优化方法或者方向,供大家一个优化思考的方向 尽量重用Material和G ...

  5. 服务迁移之《tomcat性能优化》

    删除无用的connector,因为一般的tomcat前面都会挂有nginx服务 增加connnector使用的线程池的数量 删除没有用的listener host优化项:autoDeploy设置为fa ...

  6. python3(iJmeter-master)接口测试程序部署实践

    记录学习性能测试过程遇到的问题,加油! 环境 安装环境如下: Windows 10 1803 VMWare Workstation 15 Pro Centos Linux release 7.9.20 ...

  7. ChatGPT生成测试用例的最佳实践(一)

    前面介绍的案例主要展示了ChatGPT在功能.安全和性能测试用例生成方面的应用和成果.通过ChatGPT生成测试用例,测试团队不仅可以提升工作效率,还可以加快测试工作的速度,尽早发现被测系统中的问题. ...

  8. 通过本地私有的镜像仓库harbor解决网络原因导致的jdk无法加载而造成的docker打包错误

    ​各种网络原因,或是docker.io无法访问,或是阿里的镜像源故障,导致java打包发布的时候报错,很影响代码发布的质量. 解决思路:墙出去把jdk下载下来,代码使用本地的harbor库进行引用,一 ...

  9. COS数据工作流+云函数最佳实践 - 文件哈希值计算

    01 文件哈希值是什么? 文件哈希值,即文件内容的HASH值.是通过对文件内容进行加密运算得到的一组二进制值,主要用途是用于文件校验或签名.正是因为这样的特点,它常常用来判断两个文件是否相同. COS ...

  10. Qt编写物联网管理平台44-告警邮件转发

    一.前言 上一篇文章说的是告警短信发送,这种效率非常高,缺点也很明显,需要购买特定的短信硬件设备支持才行,而且每条短信都要收费,如果要求发送的短信数量特别多,这个费用常年累月下来也是不少的,客户就不愿 ...