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

 2444

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


Node是一个基于Chrome V8引擎的JavaScript运行环境,通常用于创建网络应用程序。它可以同时处理多个连接,并且不像其他大多数模型那样依赖线程。

对于 Web 开发者来说,从数据库或Web服务器获取数据,然后输出到Excel文件以进行进一步分析的场景时有发生。我们的技术团队在跟国内外各行各业用户交流的过程中,就曾发现有很多的用户尝试在Node.js的环境下运行SpreadJS 纯前端表格控件,借助该控件,可以在服务器不预装任何Excel依赖项的情况下,收集用户输入的信息,并将其自动导出到Excel文件中。

为了满足广大技术爱好者的需要,同时减少大家在未来技术选型方面所走的弯路,本文将就SpreadJS 与 Node.js之间的技术性方案进行探讨!

一、安装 SpreadJS 和 Node .js

首先,我们需要安装Node.js以及Mock-Browser,BufferJS和FileReader,大家可以前往以下链接进行下载,同步操作:

Installing Node.js viaPackage Manager

Mock-Browser

BufferJS

FileReader

我们将使用Visual Studio创建应用程序。打开Visual Studio后,使用JavaScript> Node.js>Blank Node.js控制台应用程序模板创建一个新应用程序。这将自动创建所需的文件并打开" app.js"文件,也是我们将要更改的唯一文件。

对于BufferJS库,您需要下载该软件包,然后通过导航到项目文件夹(一旦创建)并运行以下命令,将其手动安装到项目中:

  1. npm install

安装完成后,您可能需要打开项目的package.json文件并将其添加到" dependencies"部分。文件内容应如下所示:

  1. {
  2.    "name": "spread-sheets-node-jsapp",
  3.    "version": "0.0.0",
  4.    "description": "SpreadSheetsNodeJSApp",
  5.    "main": "app.js",
  6.    "author": {
  7.       "name": "admin"
  8.    },
  9.    "dependencies": {
  10.       "FileReader": "^0.10.2",
  11.       "bufferjs": "1.0.0",
  12.       "mock-browser": "^0.92.14"
  13.    }
  14. }

在此示例中,我们将使用Node.js的文件系统模块。我们可以将其加载到:

  1. var fs = require('fs')

为了将SpreadJS与Node.js结合使用,我们还需要加载已安装的Mock-Browser:

  1. var mockBrowser =require('mock-browser').mocks.MockBrowser

在加载SpreadJS脚本之前,我们需要初始化模拟浏览器。初始化我们稍后在应用程序中可能需要使用的变量,尤其是" window"变量:

  1. global.window =mockBrowser.createWindow()
  2. global.document = window.document
  3. global.navigator = window.navigator
  4. global.HTMLCollection =window.HTMLCollection
  5. global.getComputedStyle =window.getComputedStyle

初始化FileReader库:

  1. var fileReader = require('filereader');
  2. global.FileReader = fileReader;


二、使用SpreadJS npm 包

将SpreadJS安装文件中的SpreadJS Sheets和ExcelIO包添加到项目中。

您可以通过右键单击解决方案资源管理器的" npm"部分并将它们添加到您的项目中,然后选择"安装新的NPM软件包"。您应该能够搜索" GrapeCity"并安装以下2个软件包:

  1. @grapecity/spread-sheets
  2. @grapectiy/spread-excelio

将SpreadJS npm软件包添加到项目后,正确的依赖关系将被写入package.json:

  1. {
  2.    "name": "spread-sheets-node-jsapp",
  3.    "version": "0.0.0",
  4.    "description": "SpreadSheetsNodeJSApp",
  5.    "main": "app.js",
  6.    "author": {
  7.       "name": "admin"
  8.    },
  9.    "dependencies":{
  10.       "@grapecity/spread-excelio": "^11.2.1",
  11.       "@grapecity/spread-sheets": "^11.2.1",
  12.       "FileReader": "^0.10.2",
  13.       "bufferjs": "1.0.0",
  14.       "mock-browser": "^0.92.14"
  15.    }
  16. }

现在我们需要在app.js文件中引入它:

  1. var GC =require('@grapecity/spread-sheets')
  2. var GCExcel =require('@grapecity/spread-excelio');

使用npm软件包时,还需要设置许可证密钥(点击此处,免费申请许可证密钥):

  1. GC.Spread.Sheets.LicenseKey ="<YOUR KEY HERE>"

在这个特定的应用程序中,我们将向用户显示他们正在使用哪个版本的SpreadJS。为此,我们可以引入package.json文件,然后引用依赖项以获取版本号:

  1. var packageJson =require('./package.json')
  2. console.log('\n** Using Spreadjs Version"' + packageJson.dependencies["@grapecity/spread-sheets"] +'" **')


三、将 Excel 文件加载到您的 Node.js 应用程序中

点击此处,下载现成的Excel模板文件,该文件包含了从用户那里获取数据。接下来,将数据放入文件中并导出。在这种情况下,文件是用户可以编辑的状态。

初始化工作簿和ExcelIO变量:

  1. var wb = new GC.Spread.Sheets.Workbook();
  2. var excelIO = new GCExcel.IO();

我们在读取文件时将代码包装在try / catch块中。然后,初始化变量" readline",让您读取用户输入到控制台的数据。接下来,我们将其存储到一个JavaScript数组中,以便轻松填写Excel文件:

  1. // Instantiate the spreadsheet and modifyit
  2. console.log('\nManipulatingSpreadsheet\n---');
  3. try {
  4.    var file = fs.readFileSync('./content/billingInvoiceTemplate.xlsx');
  5.    excelIO.open(file.buffer, (data) => {
  6.        wb.fromJSON(data);
  7.        const readline = require('readline');
  8.        var invoice = {
  9.             generalInfo: [],
  10.             invoiceItems: [],
  11.             companyDetails: []
  12.        };
  13.    });
  14. } catch (e) {
  15.    console.error("** Error manipulating spreadsheet **");
  16.    console.error(e);
  17. }


四、收集用户输入信息

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


上图显示了我们正在使用的Excel文件。我们可以在excelio.open调用中创建一个单独的函数,以在控制台中提示用户需要的每一项内容。我们也可以创建一个单独的数组,将数据保存到每个输入后,然后将其推送到我们创建的invoice.generalInfo数组中:

  1. fillGeneralInformation();
  2. function fillGeneralInformation() {
  3.    console.log("-----------------------\nFill in InvoiceDetails\n-----------------------")
  4.    const rl = readline.createInterface({
  5.        input: process.stdin,
  6.        output: process.stdout
  7.    });
  8.    var generalInfoArray = [];
  9.    rl.question('Invoice Number: ', (answer) => {
  10.        generalInfoArray.push(answer);
  11.        rl.question('Invoice Date (dd Month Year): ', (answer) => {
  12.            generalInfoArray.push(answer);
  13.             rl.question('Payment Due Date (ddMonth Year): ', (answer) => {
  14.                 generalInfoArray.push(answer);
  15.                 rl.question('Customer Name: ',(answer) => {
  16.                    generalInfoArray.push(answer);
  17.                     rl.question('CustomerCompany Name: ', (answer) => {
  18.                        generalInfoArray.push(answer);
  19.                         rl.question('Customer Street Address:', (answer) => {
  20.                            generalInfoArray.push(answer);
  21.                            rl.question('Customer City, State, Zip (<City>, <State Abbr><Zip>): ', (answer) => {
  22.                                 generalInfoArray.push(answer);
  23.                                rl.question('Invoice Company Name: ', (answer) => {
  24.                                    generalInfoArray.push(answer);
  25.                                    rl.question('Invoice Street Address: ', (answer) => {
  26.                                        generalInfoArray.push(answer);
  27.                                        rl.question('Invoice City, State, Zip (<City>, <State Abbr><Zip>): ', (answer) => {
  28.                                             generalInfoArray.push(answer);
  29.                                            rl.close();
  30.                                            invoice.generalInfo.push({
  31.                                                "invoiceNumber": generalInfoArray[0],
  32.                                                "invoiceDate": generalInfoArray[1],
  33.                                                "paymentDueDate": generalInfoArray[2],
  34.                                                "customerName": generalInfoArray[3],
  35.                                                "customerCompanyName": generalInfoArray[4],
  36.                                                "customerStreetAddress": generalInfoArray[5],
  37.                                                "customerCityStateZip": generalInfoArray[6],
  38.                                                "invoiceCompanyName": generalInfoArray[7],
  39.                                                "invoiceStreetAddress": generalInfoArray[8],
  40.                                                "invoiceCityStateZip": generalInfoArray[9],
  41.                                             });
  42.                                            console.log("General Invoice Information Stored");
  43.                                            fillCompanyDetails();
  44.                                         });
  45.                                     });
  46.                                });
  47.                             });
  48.                         });
  49.                     });
  50.                 });
  51.             });
  52.        });
  53.    });
  54. }

该函数被称为" fillCompanyDetails",目的是收集有关公司的信息以填充到工作簿的第二张表中:

  1. function fillCompanyDetails() {
  2.    console.log("-----------------------\nFill in CompanyDetails\n-----------------------")
  3.    const rl = readline.createInterface({
  4.        input: process.stdin,
  5.        output: process.stdout
  6.    });
  7.    var companyDetailsArray = []
  8.    rl.question('Your Name: ', (answer) => {
  9.        companyDetailsArray.push(answer);
  10.        rl.question('Company Name: ', (answer) => {
  11.             companyDetailsArray.push(answer);
  12.             rl.question('Address Line 1: ',(answer) => {
  13.                companyDetailsArray.push(answer);
  14.                 rl.question('Address Line 2: ',(answer) => {
  15.                    companyDetailsArray.push(answer);
  16.                     rl.question('Address Line3: ', (answer) => {
  17.                        companyDetailsArray.push(answer);
  18.                         rl.question('AddressLine 4: ', (answer) => {
  19.                            companyDetailsArray.push(answer);
  20.                            rl.question('Address Line 5: ', (answer) => {
  21.                                companyDetailsArray.push(answer);
  22.                                rl.question('Phone: ', (answer) => {
  23.                                    companyDetailsArray.push(answer);
  24.                                    rl.question('Facsimile: ', (answer) => {
  25.                                        companyDetailsArray.push(answer);
  26.                                         rl.question('Website: ', (answer)=> {
  27.                                            companyDetailsArray.push(answer);
  28.                                            rl.question('Email: ', (answer) => {
  29.                                                 companyDetailsArray.push(answer);
  30.                                                rl.question('Currency Abbreviation: ', (answer) => {
  31.                                                    companyDetailsArray.push(answer);
  32.                                                     rl.question('Beneficiary: ',(answer) => {
  33.                                                        companyDetailsArray.push(answer);
  34.                                                        rl.question('Bank: ', (answer) => {
  35.                                                             companyDetailsArray.push(answer);
  36.                                                            rl.question('Bank Address: ', (answer) => {
  37.                                                                companyDetailsArray.push(answer);
  38.                                                                rl.question('Account Number: ', (answer) => {
  39.                                                                    companyDetailsArray.push(answer);
  40.                                                                     rl.question('RoutingNumber: ', (answer) => {
  41.                                                                        companyDetailsArray.push(answer);
  42.                                                                        rl.question('Make Checks Payable To: ', (answer) => {
  43.                                                                            companyDetailsArray.push(answer);
  44.                                                                             rl.close();
  45.                                                                            invoice.companyDetails.push({
  46.                                                                                "yourName": companyDetailsArray[0],
  47.                                                                                "companyName": companyDetailsArray[1],
  48.                                                                                "addressLine1": companyDetailsArray[2],
  49.                                                                                "addressLine2": companyDetailsArray[3],
  50.                                                                                "addressLine3": companyDetailsArray[4],
  51.                                                                                "addressLine4": companyDetailsArray[5],
  52.                                                                                "addressLine5": companyDetailsArray[6],
  53.                                                                                 "phone":companyDetailsArray[7],
  54.                                                                                "facsimile": companyDetailsArray[8],
  55.                                                                                 "website":companyDetailsArray[9],
  56.                                                                                "email": companyDetailsArray[10],
  57.                                                                                "currencyAbbreviation":companyDetailsArray[11],
  58.                                                                                "beneficiary": companyDetailsArray[12],
  59.                                                                                "bank":companyDetailsArray[13],
  60.                                                                                "bankAddress": companyDetailsArray[14],
  61.                                                                                "accountNumber": companyDetailsArray[15],
  62.                                                                                "routingNumber": companyDetailsArray[16],
  63.                                                                                "payableTo": companyDetailsArray[17]
  64.                                                                            });
  65.                                                                            console.log("Invoice Company Information Stored");
  66.                                                                             console.log("-----------------------\nFillin Invoice Items\n-----------------------")
  67.                                                                            fillInvoiceItemsInformation();
  68.                                                                         });
  69.                                                                    });
  70.                                                                });
  71.                                                            });
  72.                                                        });
  73.                                                    });
  74.                                                });
  75.                                             });
  76.                                         });
  77.                                     });
  78.                                 });
  79.                             });
  80.                         });
  81.                     });
  82.                 });
  83.             });
  84.        });
  85.    });
  86. }


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


现在我们已经有了用户的基本信息,我们可以集中精力收集单个项目,并另命名为" fillInvoiceItemsInformation"函数。在每个项目执行之前,我们会询问用户是否要添加一个项目。如果他们继续输入" y",那么我们将收集该项目的信息,然后再次询问直到他们键入" n":

  1. function fillInvoiceItemsInformation() {
  2.    const rl = readline.createInterface({
  3.        input: process.stdin,
  4.        output: process.stdout
  5.    });
  6.    var invoiceItemArray = [];
  7.    rl.question('Add item?(y/n): ', (answer) => {
  8.        switch (answer) {
  9.             case "y":
  10.                console.log("-----------------------\nEnter ItemInformation\n-----------------------");
  11.                 rl.question('Quantity: ',(answer) => {
  12.                    invoiceItemArray.push(answer);
  13.                     rl.question('Details: ',(answer) => {
  14.                        invoiceItemArray.push(answer);
  15.                         rl.question('UnitPrice: ', (answer) => {
  16.                            invoiceItemArray.push(answer);
  17.                            invoice.invoiceItems.push({
  18.                                "quantity":invoiceItemArray[0],
  19.                                "details": invoiceItemArray[1],
  20.                                "unitPrice": invoiceItemArray[2]
  21.                             });
  22.                             console.log("ItemInformation Added");
  23.                             rl.close();
  24.                            fillInvoiceItemsInformation();
  25.                         });
  26.                     });
  27.                 });
  28.                 break;
  29.             case "n":
  30.                rl.close();
  31.                 return fillExcelFile();
  32.                 break;
  33.             default:
  34.                 console.log("Incorrectoption, Please enter 'y' or 'n'.");
  35.        }
  36.    });
  37. }


五、填入您的Excel 文件

在收集所有必需的用户信息后,我们可以将其填入到Excel文件中:

  1. function fillExcelFile() {
  2.    console.log("-----------------------\nFilling in Excelfile\n-----------------------");
  3.    fillBillingInfo();
  4.    fillCompanySetup();
  5. }
  6. function fillBillingInfo() {
  7.    var sheet = wb.getSheet(0);
  8.    sheet.getCell(0, 2).value(invoice.generalInfo[0].invoiceNumber);
  9.    sheet.getCell(1, 1).value(invoice.generalInfo[0].invoiceDate);
  10.    sheet.getCell(2, 2).value(invoice.generalInfo[0].paymentDueDate);
  11.    sheet.getCell(3, 1).value(invoice.generalInfo[0].customerName);
  12.    sheet.getCell(4, 1).value(invoice.generalInfo[0].customerCompanyName);
  13.    sheet.getCell(5, 1).value(invoice.generalInfo[0].customerStreetAddress);
  14.    sheet.getCell(6, 1).value(invoice.generalInfo[0].customerCityStateZip);
  15.    sheet.getCell(3, 3).value(invoice.generalInfo[0].invoiceCompanyName);
  16.    sheet.getCell(4, 3).value(invoice.generalInfo[0].invoiceStreetAddress);
  17.    sheet.getCell(5, 3).value(invoice.generalInfo[0].invoiceCityStateZip);
  18. }
  19. function fillCompanySetup() {
  20.    var sheet = wb.getSheet(1);
  21.    sheet.getCell(2, 2).value(invoice.companyDetails[0].yourName);
  22.    sheet.getCell(3, 2).value(invoice.companyDetails[0].companyName);
  23.    sheet.getCell(4, 2).value(invoice.companyDetails[0].addressLine1);
  24.    sheet.getCell(5, 2).value(invoice.companyDetails[0].addressLine2);
  25.    sheet.getCell(6, 2).value(invoice.companyDetails[0].addressLine3);
  26.    sheet.getCell(7, 2).value(invoice.companyDetails[0].addressLine4);
  27.    sheet.getCell(8, 2).value(invoice.companyDetails[0].addressLine5);
  28.    sheet.getCell(9, 2).value(invoice.companyDetails[0].phone);
  29.    sheet.getCell(10, 2).value(invoice.companyDetails[0].facsimile);
  30.    sheet.getCell(11, 2).value(invoice.companyDetails[0].website);
  31.    sheet.getCell(12, 2).value(invoice.companyDetails[0].email);
  32.    sheet.getCell(13, 2).value(invoice.companyDetails[0].currencyAbbreviation);
  33.    sheet.getCell(14, 2).value(invoice.companyDetails[0].beneficiary);
  34.    sheet.getCell(15, 2).value(invoice.companyDetails[0].bank);
  35.    sheet.getCell(16, 2).value(invoice.companyDetails[0].bankAddress);
  36.    sheet.getCell(17, 2).value(invoice.companyDetails[0].accountNumber);
  37.    sheet.getCell(18, 2).value(invoice.companyDetails[0].routingNumber);
  38.    sheet.getCell(19, 2).value(invoice.companyDetails[0].payableTo);
  39. }

为了防止用户添加的数量超过工作表最大行数,我们可以在工作表中自动添加更多行。在设置数组中表单中的项目之前,默认添加行:

  1. function fillInvoiceItems() {
  2.    var sheet = wb.getSheet(0);
  3.    var rowsToAdd = 0;
  4.    if (invoice.invoiceItems.length > 15) {
  5.        rowsToAdd = invoice.invoiceItems.length - 15;
  6.        sheet.addRows(22, rowsToAdd);
  7.    }
  8.    var rowIndex = 8;
  9.    if (invoice.invoiceItems.length >= 1) {
  10.        for (var i = 0; i < invoice.invoiceItems.length; i++) {
  11.             sheet.getCell(rowIndex,1).value(invoice.invoiceItems.quantity);
  12.             sheet.getCell(rowIndex,2).value(invoice.invoiceItems.details);
  13.             sheet.getCell(rowIndex,3).value(invoice.invoiceItems.unitPrice);
  14.             rowIndex++;
  15.        }
  16.    }
  17. }

六、将文档内容从 Node.js 导出到 Excel 文件

在工作簿中填写完信息后,我们可以将工作簿导出到Excel文件中。为此,我们将使用excelio打开功能。在这种情况下,只需将日期输入文件名即可:

  1. function exportExcelFile() {
  2.    excelIO.save(wb.toJSON(), (data) => {
  3.        fs.appendFileSync('Invoice' + new Date().valueOf() + '.xlsx', newBuffer(data), function (err) {
  4.             console.log(err);
  5.        });
  6.        console.log("Export success");
  7.    }, (err) => {
  8.        console.log(err);
  9.    }, { useArrayBuffer: true });
  10. }

完成的文件将如下所示:


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


本文网址:https://www.zztuku.com/detail-13052.html
站长图库 - 教你Node.js+SpreadJS从服务端生成Excel电子表格
申明:本文转载于《博客园》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐