极速响应Excel数据报表请求的一种方法
2015-05-03 00:00
423 查看
摘要
通过缓存和维护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被使用后,很多状态都变了。
资源池代码结构
启示
数据库连接池、对象池、缓存等很多程序设计中的概念,是存在着相似之处的。
学习和借鉴每一个成熟的概念和解决方案,能够产生更多的好方法。
活学活用,灵活解决实际工作中遇到的问题。
拒绝码农,谢绝书呆子。
相关阅读
通过缓存和维护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()); } } } }
启示
数据库连接池、对象池、缓存等很多程序设计中的概念,是存在着相似之处的。
学习和借鉴每一个成熟的概念和解决方案,能够产生更多的好方法。
活学活用,灵活解决实际工作中遇到的问题。
拒绝码农,谢绝书呆子。
相关阅读
ExcelToHtmlTable转换算法:将Excel转换成Html表格并展示(项目源码+详细注释+项目截图)
码农:客户是恶魔
原文参见:http://FansUnion.cn/articles/2851 小雷网(FansUnion.cn)相关文章推荐
- 极速响应Excel数据报表请求的一种方法
- 极速响应Excel数据报表请求的一种方法
- 极速响应Excel数据报表请求的一种方法
- VB6数据导出到Excel文件,一种设计界面查询条件的方法,一种简单加密方法(改写)
- java中导出大量数据到Excel的一种方法
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- 一种比较兼容的Excel报表导出方法
- ASP.NET Web API 记录请求响应数据到日志的一个方法
- WINCC中数据EXCEL报表的实现方法
- Python实现导出数据生成excel报表的方法示例
- Jmeter请求后响应数据显示乱码解决方法
- ASP.NET Web API 记录请求响应数据到日志的一个方法
- 将数据导到Excel里面去又一种方法
- 往Excel里导入数据的一种方法(dataset-->excel)
- ASP.NET Web API 记录请求响应数据到日志的一个方法
- 一个反射方法响应web平台所有ajax数据请求,让web开发速度提高一倍
- [JAVA]Java导出Excel数据的一种方法(完美实现,包含表格线)
- Jmeter请求后响应数据显示乱码解决方法
- java输出excel数据的方法示例(一种是到excel,一种是结构化数据到文本文件,可以用editplus之类的看)
- ASP.NET(VB)把数据导出到EXCEL的一种方法(网上转载)