从服务端生成Excel电子表格(GcExcel + SpreadJS)
在服务端生成Excel电子表格,除了使用 Node.js + SpreadJS 外,葡萄城官方推荐使用 SpreadJS + GcExcel。该方案不仅能够解决批量绑定数据源并导出Excel、批量修改大量Excel内容及样式、服务端批量打印以及生成PDF文档等需求,还提供了远超行业标准的组件性能。
为了验证SpreadJS + GcExcel的处理性能,本文将就GcExcel for Java和Node.js中运行SpreadJS的各项数据进行对比。由于SpreadJS和GcExcel的组件功能非常丰富,本文仅选择最为常见的两个功能点做对比,分别是设置区域数据和导出Excel文档。
一、本次测试的几个大前提
由于Node.js是基于V8引擎来执行JavaScript的,因此它的js也是基于事件机制的非阻塞单线程运行,其文件的I/O都是异步执行的,而Node.js之所以选择单线程的方式是因为编码简单、开发难度低、对"码农"码农的心智消耗相对较小;而且它的文件I/O是异步执行的,所以不需要像Java那样需要创建、回收线程(Node.js的I/O操作在底层也是线程,这里不做深入讨论),这方面开销较小。
但是,单线程在做复杂运算方面相比多线程则没有任何优势,也无法利用多线程来有效调配多核CPU进行优化,因此在Node.js中运行SpreadJS就只能是单线程JS,这也会影响SpreadJS 的数据处理性能。
所以,为了获得更加准确的测试结果,本篇中设计的测试用例,在两个环境(Java 和 Node.js)中都采用单线程执行,并且选择了与Node.js更加匹配的批量I/O操作作为测试用例。
二、 Node.js 与 SpreadJS 的测试代码和结果:
| 软件版本 | CPU | 内存 |
|---|---|---|
| Node.js 16.10.0 | Intel(R) Core(TM) i7-9750HQ CPU @ 2.80 GHz | 32G |
测试代码:如下所示,用一个Performance类执行1000次设置数据、导出Excel文档的操作。
const fs = require('fs');
// Initialize the mock browser variables
const mockBrowser = require('mock-browser').mocks.MockBrowser;
global.window = mockBrowser.createWindow();
global.document = window.document;
global.navigator = window.navigator;
global.HTMLCollection = window.HTMLCollection;
global.getComputedStyle = window.getComputedStyle;
const fileReader = require('filereader');
global.FileReader = fileReader;
const GC = require('@grapecity/spread-sheets');
const GCExcel = require('@grapecity/spread-excelio');
GC.Spread.Sheets.LicenseKey = GCExcel.LicenseKey = "Your License";
const dataSource = require('./data');
function runPerformance(times) {
const timer = `test in ${times} times`;
console.time(timer);
for(let t=0; t<times; t++) {
// const hostDiv = document.createElement('div');
// hostDiv.id = 'ss';
// document.body.appendChild(hostDiv);
const wb = new GC.Spread.Sheets.Workbook()//global.document.getElementById('ss'));
const sheet = wb.getSheet(0);
for(let i=0; i<dataSource.length; i++) {
sheet.setValue(i, 0, dataSource[i]["Film"]);
sheet.setValue(i, 1, dataSource[i]["Genre"]);
sheet.setValue(i, 2, dataSource[i]["Lead Studio"]);
sheet.setValue(i, 3, dataSource[i]["Audience Score %"]);
sheet.setValue(i, 4, dataSource[i]["Profitability"]);
sheet.setValue(i, 5, dataSource[i]["Rating"]);
sheet.setValue(i, 6, dataSource[i]["Worldwide Gross"]);
sheet.setValue(i, 7, dataSource[i]["Year"]);
}
exportExcelFile(wb, times, t);
}
}
function exportExcelFile(wb, times, t) {
const excelIO = new GCExcel.IO();
excelIO.save(wb.toJSON(), (data) => {
fs.appendFile('results/Invoice' + new Date().valueOf() + '_' + t + '.xlsx', new Buffer(data), function (err) {
if (err) {
console.log(err);
}else {
if(t === times-1) {
console.log('Export success');
console.timeEnd(`test in ${times} times`);
}
}
});
}, (err) => {
console.log(err);
}, { useArrayBuffer: true });
}
runPerformance(1000)
完整的测试工程请参考:https://gitee.com/GrapeCity/Node.js-SpreadJS-two.git
测试工程运行方式:
- npm install
- node ./app.js
运行结果:平均每次花费 18.1 ms

三、 GcExcel 的测试代码和结果
| 软件版本 | CPU | 内存 |
|---|---|---|
| GcExcel V5.0 | Intel(R) Core(TM) i7-9750HQ CPU @ 2.80 GHz | 32G |
测试代码如下所示:
public class Performance {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir") + "/sources/jsonData");
String jsonStr = readTxtFileIntoStringArrList(System.getProperty("user.dir") + "/sources/jsonData");
JSONArray jsonArr = JSON.parseArray(jsonStr);
//JSONObject jsonObj = (JSONObject) jsonArr.get(0);
//System.out.println(jsonObj.get("Film"));
run(1000, jsonArr);
}
public static void run(int times, JSONArray dataArr) {
String path = System.getProperty("user.dir") + "/results/";
System.out.println(path + "result.xlsx");
long start = new Date().getTime();
for (int i = 0; i < times; i++) {
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getWorksheets().get(0);
for (int j = 0; j < dataArr.size(); j++) {
JSONObject jsonObj = (JSONObject) dataArr.get(j);
worksheet.getRange(j, 0, 1, 8).get(0).setValue(jsonObj.get("Film"));
worksheet.getRange(j, 0, 1, 8).get(1).setValue(jsonObj.get("Genre"));
worksheet.getRange(j, 0, 1, 8).get(2).setValue(jsonObj.get("Lead Studio"));
worksheet.getRange(j, 0, 1, 8).get(3).setValue(jsonObj.get("Audience Score %"));
worksheet.getRange(j, 0, 1, 8).get(4).setValue(jsonObj.get("Profitability"));
worksheet.getRange(j, 0, 1, 8).get(5).setValue(jsonObj.get("Rating"));
worksheet.getRange(j, 0, 1, 8).get(6).setValue(jsonObj.get("Worldwide Gross"));
worksheet.getRange(j, 0, 1, 8).get(7).setValue(jsonObj.get("Year"));
}
workbook.save(path + "result" + i + ".xlsx");
}
System.out.println("运行"+times+"次花费时常(ms): " + (new Date().getTime() - start));
}
public static String readTxtFileIntoStringArrList(String filePath) {
StringBuilder list = new StringBuilder();
try {
String encoding = "GBK";
File file = new File(filePath);
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
list.append(lineTxt);
}
bufferedReader.close();
read.close();
} else {
System.out.println("找不到指定的文件");
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
}
return list.toString();
}
}
完整的测试工程zip请参考附件:https://gitee.com/GrapeCity/Node.js-SpreadJS-two.git
测试脚本运行方式:导入Eclipse后直接run as Application
运行结果如下所示:平均每次花费 8.4 ms

四、总结分析:
1 、测试结果分析:node.js平均每次花费 18.1 ms,GcExcel平均每次花费 8.4 ms,两者同时执行1000次设置数据、导出Excel文档的操作,性能相差2倍。
2、处理性能的对比分析:
即便对于单线程的批量I/O操作,SpreadJS 在 Node.js的运行性能仍不如SpreadJS 在GcExcel for Java中运行,一方面是由于GcExcel性能的确非常优秀,它在Java平台上运用了很多优秀、成熟的解决方案,做到了同类产品中最一流的性能表现,另一方面是由于GcExcel对Excel和SpreadJS有更加全面的功能支持。目前,GcExcel已经作为行业内服务器端处理Excel文档的首选方案。
3 、技术选型的分析:
除了性能、编码难度外,对于技术选型而言,有一点也不容忽视,即平台。如果项目本身采用的是Java Web或 .Net Web架构,那么对于提供双平台支持的GcExcel(GcExcel for java和 GcExcel for .NET)来说显然更加合适。
以上就是本篇的全部内容,结合本文的测试结果,对于批量处理、修改、导出Excel,以及服务端批量打印和生成PDF文档的需求, SpreadJS + GcExcel都能提供更加优秀的性能和稳定性表现,可以放心将其作为未来项目的首选方案。
从服务端生成Excel电子表格(GcExcel + SpreadJS)的更多相关文章
- 从服务端生成Excel电子表格(Node.js+SpreadJS)
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,通常用于创建网络应用程序.它可以同时处理多个连接,并且不像其他大多数模型那样依赖线程. 对于 Web 开发者来说,从数据库 ...
- Highcharts结合PhantomJS在服务端生成高质量的图表图片
项目背景 最近忙着给部门开发一套交互式的报表系统,来替换原有的静态报表系统. 老系统是基于dotnetCHARTING开发的,dotnetCHARTING的优势是图表类型丰富,接口调用简单,使用时只需 ...
- fastadmin 随笔 刷新表格数据 获取当前登录人信息 服务端导出Excel
table.bootstrapTable('refresh',{url:'你的url'}); 获取当前登录人信息 $this->auth就能获取当前用户信息,比如$this->auth-& ...
- 根据服务端生成的WSDL文件创建客户端支持代码的三种方式
第一种:使用wsimport是JDK自带的工具,来生成 生成java客户端代码常使用的命令参数说明: 参数 说明 -p 定义客户端生成类的包名称 -s 指定客户端执行类的源文件存放目录 -d 指定客户 ...
- 分布式监控系统开发【day37】:服务端生成配置数据(四)
一.目录结构 二.引子与代码 1.客户端获取服务列表接口 1.解决了什么问题 客户端要给我获取服务列表的的时候,他肯定要告诉他是谁?他怎么告诉我,客户端必须有一个id号 Saltsack你装一个客户端 ...
- Netbackup8.0以上版本,服务端生成证书,客户端获取、更新证书方式(整理中)
创建重发令牌 如果非主控主机已在主服务器上注册但其基于主机ID的证书不再有效,则可以重新颁发基于主机ID的证书.例如,证书在过期,被撤销或丢失时无效. 重发令牌是一种可用于重新颁发证书的令牌.它是一种 ...
- 服务端生成word并压缩打包下载
所需工具 phpwrod 库 php_zip 扩展 下载phpword库,放到类加载路径. 安装php_zip扩展 下载地址 http://pecl.php.net/package/zip linux ...
- .net服务端生成二维码
mvc4 net4.0 1.引用附件的DLL文件 2.两个函数即可 #region 生成二维码 public ActionResult getQrCode() { using (var ms = ...
- Django服务端读取excel文件并且传输到接口
path_name = "opboss_download_" + str(int(time.time())) + ".csv" print(path_name) ...
随机推荐
- 你真的会用react hooks?看看eslint警告吧!(如何发请求、提升代码性能等问题)
前言 看过几个react hooks 的项目,控制台上几百条警告,大多是语法不规范,react hooks 使用有风险,也有项目直接没开eslint.当然,这些项目肯定跑起来了,因为react自身或者 ...
- RTD2172替代方案|TYPEC转HDMI4K@60HZ拓展坞|CS5265替代RTD2172
瑞昱RTD2172是TYPEC转HDMI4K60HZ音视频数据转换器芯片.CS5265可以替代兼容RTD2172,除了实现同等的转换功能外且整体方案成本和性价比方面比RTD2172要高,且外围器件较少 ...
- Android开发布局 案例二
实践案例: XML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- MD5,SHA1及SHA256等哈希加密方法实现:Java,C#,Golang,Python
哈希算法又称散列算法,它可以从任何数据中快速的创建一个凭证,而这个凭证很难被推倒出来,因为一丁点的变化会导致凭证的差别恨到,也就是说哈希算法具有不可逆性,因此它在密码数据校验方面用的很广,比如我们常用 ...
- Git_同一个本地仓库上传到不同的远端仓库(github、gitee)
一.背景 github访问.推拉代码都太慢了,于是想把github上面的项目全部迁移到gitee(码云)上,但又不想放弃在github上维护项目,于是想同时维护两个远端仓库 二.准备工作 1.创建相同 ...
- 使用 try-catch
ECMA-262 第 3 版引入了 try-catch 语旬,当 try-catch 语句中发生错误时, 浏览器会认为错误已经被处理了 ,因而不会报告错误.对于那些不要求用户懂技术,也不需要用户理解错 ...
- 从内存管理原理,窥探OS内存管理机制
摘要:本文将从最简单的内存管理原理说起,带大家一起窥探OS的内存管理机制,由此熟悉底层的内存管理机制,写出高效的应用程序. 本文分享自华为云社区<探索OS的内存管理原理>,作者:元闰子 . ...
- 常用Cron表达式范例
描述 表达式 每隔5秒执行一次 */5 * * * * ? 每隔1分钟执行一次 0 */1 * * * ? 每天23点执行一次 0 0 23 * * ? 每天凌晨1点执行一次 0 0 1 * * ? ...
- MATLAB的基识(整理)
%正弦函数在MATLAB中如何实现%1.sin(45°)注意:参数值需要用"弧度"去定义>>x=sin(45*pi/180);%2.MATLAB中注意:开方-sqrt( ...
- 龙芯 3A4000 安装 Debian stable
2022-01-17 版权声明:原创文章,未经博主允许不得转载 3A5000 开始,龙芯转向 loongarch ,新的架构虽然甩掉了历史包袱,但也需要一段时间来积累生态.在这半年多的时间里, loo ...