在服务端生成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 variablesconst 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都能提供更加优良的性能和稳定性体现,能够释怀将其作为将来我的项目的首选计划。