从服务端生成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 javaGcExcel for .NET)来说显然更加合适。

以上就是本篇的全部内容,结合本文的测试结果,对于批量处理、修改、导出Excel,以及服务端批量打印和生成PDF文档的需求, SpreadJS + GcExcel都能提供更加优秀的性能和稳定性表现,可以放心将其作为未来项目的首选方案。


本文是由葡萄城技术开发团队发布,转载请注明出处:葡萄城官网

推荐这些文章:

从服务端生成Excel电子表格(Node.js+SpreadJS)

Node.js是一个基于Chrome V8引擎的JavaScript运行环境,通常用于创建网络应用程序。它可以同时处理多个连接,并且不像其他大多数模型那样依赖线程。
对于 Web 开发者来说,从数据库或Web服务器获取数据,然后输出到Excel文件以进行进一步分析的场景时有发生。我们的技术团队在跟国内外各行各业用户交流的过程中,就曾发现有很多的用户尝试在Node.js的环境下运行SpreadJS 纯前端表格控件,借助该控件,可以在服务器不预装任何Excel依赖项的情况下,收集用户输入的信息,并将其自动导出到Excel文件中。
为了满足广大技术爱好者的需要,同时减少大家在未来技术选型方面所走的...

用汇编语言绘制电子表格(简单的Excel)

问题
请问如何使用汇编语言绘制简单的电子表格。类似与表格工具中的插入表格(选择行和列)自动生成相应的表格。

最佳回答
用汇编语言生成一个excel文件吗?感觉有点和自己过不去啊

...

在asp中,如何实现把查询的数据生成到Excel中。

问题

如果数据是由多个表联合查询的,还要分成多个sheet。把各个表里的内容独立在每个Sheet中。请教高手,在线等待。

最佳回答
这里关于Office的开发可能对你有用 http://www.cnblogs.com/2018/category/249767.html

...

用java读取Excel并依据模板图生成对应的图片

package test;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.sun.image.codec.jpeg.JPEGCodec;...

文章标题:从服务端生成Excel电子表格(GcExcel + SpreadJS)
文章链接:https://www.dianjilingqu.com/51480.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。
THE END
< <上一篇
下一篇>>