摘要
通过缓存和维护Excel Workbook实例,极速响应Excel数据报表请求。
这是一个真实的大数据“云计算”项目中的解决方案,在给定的时间和资源下,只有这种方法是最简单并且是可行的。
XX公司的需求
简单Excel报表:1个sheet。5秒内可以在界面展示。
复杂Excel报表:7个sheet。20秒内可以在界面展示。
并发响应:20个用户
详细介绍
每个sheet中有大量的Excel公式,如 F=E32-[35764%D1]*[DD]/[LD]。
每个单元格的值,需要后台从Mongodb数据库中取出并计算。
Web前端获得后台返回的数据,插入到Excel单元格中,然后Excel自动执行公式,然后将Excel完整地显示到界面中。
时间瓶颈
后台数据获取和数据计算的时间:
1个sheet要3-4s,7个sheet要10到20s。
前台展示剩下的时间:
1个sheet:1到2秒
7个sheet:0到10秒
读取Excel文件需要的时间
1个sheet:1s左右
7个sheet:2s左右
Excel文件构造成POI XSSFWorkbook对象
1个sheet:1s左右
7个sheet:7s左右
最初,我以为是IO有瓶颈,后来发现不是。主要是POI 构造XSSFWorkbook对象,需要花费很长时间。
XSSFWorkbook这可是一个比较大且复杂的数据结构,维护着一个Excel文档的所有信息。
(令人可气的是,测试机Linux服务器性能竟然还不如我的笔记本)
解决方案
考虑到并发请求最多也就是20,而且这只是一个Demo项目,因此“空间换时间”是可行的。
灵感来源:数据库连接池、对象池、缓存等都可以用来提高程序的性能。
最终方案:维护一份Workbook资源池。程序启动后,写一个定时器,监控资源池中的对象数量,达到资源下界的时候,就构造一些新的对象放进资源池中。
与数据库连接池等不同的是,Workbook资源池中的每一个XSSFWorkbook对象,只能使用一次。用完后,就必须从资源池中删除。
因为,XSSFWorkbook被使用后,很多状态都变了。
资源池代码结构
public class WorkbookPool {
private static int complexMinSize = TemplatePropertyReader.COMPLEX_MIN_SIZE;
// 复杂报表--最大缓存
private static int complexMaxSize = TemplatePropertyReader.COMPLEX_MAX_SIZE;
public WorkbookPool() {
}
public void init() {
simpleReportTimer();
complexReportTimer();
}
// 定时器任务---创建报表对象
private void simpleReportTimer() {
log.info("Simple Producter Timer Start...");
Timer producterTimer = new Timer();
// 在1秒后执行此任务,每次间隔1秒
producterTimer.schedule(new SimpleProducterTask(), 1000, 1000);
}
private void complexReportTimer() {
log.info("Complex Producter Timer Start...");
Timer complexProducterTimer = new Timer();
// 在1秒后执行此任务,每次间隔1秒
complexProducterTimer.schedule(new ComplexProducterTask(), 1000, 1000);
}
// 简单报表--定时器任务
class SimpleProducterTask extends TimerTask {
public void run() {
int simpleSize = simpleVector.size();
if (simpleSize <= simpleMinSize) {
int toBuildSize = simpleMaxSize - simpleSize;
log.info("before : simpleSize=" + simpleSize + ",toBuildSize=" + toBuildSize);
buildSimple(toBuildSize);
log.info("after : simpleSize=" + simpleVector.size());
}
}
}
// 复杂报表--定时器任务
class ComplexProducterTask extends TimerTask {
public void run() {
int complexSize = complexVector.size();
if (complexSize <= complexMinSize) {
int toBuildSize = complexMaxSize - complexSize;
log.info("before: complexSize=" + complexSize + ",toBuildSize=" + toBuildSize);
buildComplex(toBuildSize);
log.info("after: complexSize=" + complexVector.size());
}
}
}
}
启示
数据库连接池、对象池、缓存等很多程序设计中的概念,是存在着相似之处的。
学习和借鉴每一个成熟的概念和解决方案,能够产生更多的好方法。
活学活用,灵活解决实际工作中遇到的问题。
拒绝码农,谢绝书呆子。
相关阅读
原文参见:http://FansUnion.cn/articles/2851 小雷网(FansUnion.cn)
分享到:
相关推荐
通过程序方式从Excel文件中读取数据并导入数据库的传统方法,是通过创建一个OLE对象,打开Excel文件,逐行访问记录行及各个单元,写入数据库表。这种方法一旦数据行通过一定的数量,执行效果就无法忍受了。究其根源...
以往的易程序导出excel太慢了,特别是数据比较多的时候,本程序写excel模板的方法极速导入导出excel或者数据库,1万条数据不用一秒钟的时间,速度杠杠的,大家可以试试效果。本例子是用超级列表框做例子,如有需要...
Excel汇总大师 极速版 将多个excel表格数据内容进行汇总 将多个excel表格数据内容进行汇总 将多个excel表格数据内容进行汇总 将多个excel表格数据内容进行汇总
行业分类-物理装置-一种实现无限存储和数据极速传输的方法
Tableau公司将数据运算与美观的图表完美地嫁接在一起。它的程序很容易上手,各公司可以...本资源提供了《Tableau:数据可视化之极速BI》书中数据,便于大家更好的进行实际动手操作,体验Tableau强大的数据可视化功能。
JOE主题仅1.3M极速响应极致优化
Tableau:数据可视化之极速BI书中数据
已经上传过《Tableau:数据可视化之极速BI.pdf》,这是书中的数据
Tableau数据可视化之极速BI.pdf
Tableau数据可视化之极速BI,随书数据,按章节分开
C#中DATAGRIDVIEW快速导出到EXCEL(极速),直接引用DLL即可。
对WPS来说,合并与数据批量比对是VIP功能,便对于EXCEL来讲,基本就是免费功能,基于工作需要,已将WPS的该功能做成小工具免费供大家使用。支持EXCEL后缀自动识别。工具本来只有不到20K,因为加了图标变成了100多K。...
将超级列表框(报表列表框)导出为Excel表格文件。API+核心支持库,无第三方模块或支持库。易语言超级列表框导出到Excel表格模块源码例程程序调用API函数实现超级列表框导出到Excel表格。易语言超级列表框导出到Excel...
针对这一问题,提出了一种处理不平衡数据集分类的ELM模型(ELM-CIL),该模型按照代价敏感学习的原则为少数类样本赋予较大的惩罚系数,并引入模糊隶属度值减小了外围噪声点的影响。实验表明,提出的方法不仅对提高不...
不同类型数据库之间极速数据转换工具,例如:可以将SQLServer数据转换迁移到MySQL,可以交换数据源,同步表数据、表结构都不在话下
最新2011.10.17.1极速版的EXCEL账务处理系统,极速、简洁、实用,超越SQL的速度。可以出资产负债表,利润表,总账,三栏明细账,数量金额式明细账,多栏账。可以打印凭证。
excel文件批量处理,多个表格合并,筛选后批量输出,从总表中随意选取部分人员,比excel软件简单的不要不要的。
整包仅1.3Mb,却实现超强功能,极其迅速的响应(在开发时,都是使用30000篇文章进行开发测试)
Tableau:数据可视化之极速BI (高清PDF)
Tableau数据可视化之极速BI(高清版)