关于javascript:从服务端生成Excel电子表格NodejsSpreadJS

Node.js是一个基于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库,您须要下载该软件包,而后通过导航到我的项目文件夹(一旦创立)并运行以下命令,将其手动装置到我的项目中:

npm install

装置实现后,您可能须要关上我的项目的package.json文件并将其增加到” dependencies”局部。文件内容应如下所示:

{
"name": "spread-sheets-node-jsapp",
"version": "0.0.0",
"description": "SpreadSheetsNodeJSApp",
"main": "app.js",
"author": {
   "name": "admin"
},
"dependencies": {
   "FileReader": "^0.10.2",
   "bufferjs": "1.0.0",
   "mock-browser": "^0.92.14"
  }
}

在此示例中,咱们将应用Node.js的文件系统模块。咱们能够将其加载到:

var fs = require('fs')

为了将SpreadJS与Node.js联合应用,咱们还须要加载已装置的Mock-Browser:

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

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

global.window =mockBrowser.createWindow()
global.document = window.document
global.navigator = window.navigator
global.HTMLCollection =window.HTMLCollection
global.getComputedStyle =window.getComputedStyle

初始化FileReader库:

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

二、应用SpreadJS npm 包

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

您能够通过右键单击解决方案资源管理器的” npm”局部并将它们增加到您的我的项目中,而后抉择”装置新的NPM软件包”。您应该可能搜寻” GrapeCity”并装置以下2个软件包:

@grapecity/spread-sheets
@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文件中引入它:

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

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

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

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

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

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

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

初始化工作簿和ExcelIO变量:

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

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

// Instantiate the spreadsheet and modifyit
console.log('\nManipulatingSpreadsheet\n---');
try {
   var file = fs.readFileSync('./content/billingInvoiceTemplate.xlsx');
   excelIO.open(file.buffer, (data) => {
       wb.fromJSON(data);
       const readline = require('readline');
       var invoice = {
            generalInfo: [],
            invoiceItems: [],
            companyDetails: []
       };
   });
} catch (e) {
   console.error("** Error manipulating spreadsheet **");
   console.error(e);
}

四、收集用户输出信息

上图显示了咱们正在应用的Excel文件。咱们能够在excelio.open调用中创立一个独自的函数,以在控制台中提醒用户须要的每一项内容。咱们也能够创立一个独自的数组,将数据保留到每个输出后,而后将其推送到咱们创立的invoice.generalInfo数组中:

fillGeneralInformation();
function fillGeneralInformation() {
   console.log("-----------------------\nFill in InvoiceDetails\n-----------------------")
   const rl = readline.createInterface({
       input: process.stdin,
       output: process.stdout
   });
   var generalInfoArray = [];
   rl.question('Invoice Number: ', (answer) => {
       generalInfoArray.push(answer);
       rl.question('Invoice Date (dd Month Year): ', (answer) => {
           generalInfoArray.push(answer);
            rl.question('Payment Due Date (ddMonth Year): ', (answer) => {
                generalInfoArray.push(answer);
                rl.question('Customer Name: ',(answer) => {
                   generalInfoArray.push(answer);
                    rl.question('CustomerCompany Name: ', (answer) => {
                       generalInfoArray.push(answer);
                        rl.question('Customer Street Address:', (answer) => {
                           generalInfoArray.push(answer);
                           rl.question('Customer City, State, Zip (<City>, <State Abbr><Zip>): ', (answer) => {
                                generalInfoArray.push(answer);
                               rl.question('Invoice Company Name: ', (answer) => {
                                   generalInfoArray.push(answer);
                                   rl.question('Invoice Street Address: ', (answer) => {
                                       generalInfoArray.push(answer);
                                       rl.question('Invoice City, State, Zip (<City>, <State Abbr><Zip>): ', (answer) => {
                                            generalInfoArray.push(answer);
                                           rl.close();
                                           invoice.generalInfo.push({
                                               "invoiceNumber": generalInfoArray[0],
                                               "invoiceDate": generalInfoArray[1],
                                               "paymentDueDate": generalInfoArray[2],
                                               "customerName": generalInfoArray[3],
                                               "customerCompanyName": generalInfoArray[4],
                                               "customerStreetAddress": generalInfoArray[5],
                                               "customerCityStateZip": generalInfoArray[6],
                                               "invoiceCompanyName": generalInfoArray[7],
                                               "invoiceStreetAddress": generalInfoArray[8],
                                               "invoiceCityStateZip": generalInfoArray[9],
                                            });
                                           console.log("General Invoice Information Stored");
                                           fillCompanyDetails();
                                        });
                                    });
                               });
                            });
                        });
                    });
                });
            });
       });
   });
}

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

function fillCompanyDetails() {
   console.log("-----------------------\nFill in CompanyDetails\n-----------------------")
   const rl = readline.createInterface({
       input: process.stdin,
       output: process.stdout
   });
   var companyDetailsArray = []
   rl.question('Your Name: ', (answer) => {
       companyDetailsArray.push(answer);
       rl.question('Company Name: ', (answer) => {
            companyDetailsArray.push(answer);
            rl.question('Address Line 1: ',(answer) => {
               companyDetailsArray.push(answer);
                rl.question('Address Line 2: ',(answer) => {
                   companyDetailsArray.push(answer);
                    rl.question('Address Line3: ', (answer) => {
                       companyDetailsArray.push(answer);
                        rl.question('AddressLine 4: ', (answer) => {
                           companyDetailsArray.push(answer);
                           rl.question('Address Line 5: ', (answer) => {
                               companyDetailsArray.push(answer);
                               rl.question('Phone: ', (answer) => {
                                   companyDetailsArray.push(answer);
                                   rl.question('Facsimile: ', (answer) => {
                                       companyDetailsArray.push(answer);
                                        rl.question('Website: ', (answer)=> {
                                           companyDetailsArray.push(answer);
                                           rl.question('Email: ', (answer) => {
                                                companyDetailsArray.push(answer);
                                               rl.question('Currency Abbreviation: ', (answer) => {
                                                   companyDetailsArray.push(answer);
                                                    rl.question('Beneficiary: ',(answer) => {
                                                       companyDetailsArray.push(answer);
                                                       rl.question('Bank: ', (answer) => {
                                                            companyDetailsArray.push(answer);
                                                           rl.question('Bank Address: ', (answer) => {
                                                               companyDetailsArray.push(answer);
                                                               rl.question('Account Number: ', (answer) => {
                                                                   companyDetailsArray.push(answer);
                                                                    rl.question('RoutingNumber: ', (answer) => {
                                                                       companyDetailsArray.push(answer);
                                                                       rl.question('Make Checks Payable To: ', (answer) => {
                                                                           companyDetailsArray.push(answer);
                                                                            rl.close();
                                                                           invoice.companyDetails.push({
                                                                               "yourName": companyDetailsArray[0],
                                                                               "companyName": companyDetailsArray[1],
                                                                               "addressLine1": companyDetailsArray[2],
                                                                               "addressLine2": companyDetailsArray[3],
                                                                               "addressLine3": companyDetailsArray[4],
                                                                               "addressLine4": companyDetailsArray[5],
                                                                               "addressLine5": companyDetailsArray[6],
                                                                                "phone":companyDetailsArray[7],
                                                                               "facsimile": companyDetailsArray[8],
                                                                                "website":companyDetailsArray[9],
                                                                               "email": companyDetailsArray[10],
                                                                               "currencyAbbreviation":companyDetailsArray[11],
                                                                               "beneficiary": companyDetailsArray[12],
                                                                               "bank":companyDetailsArray[13],
                                                                               "bankAddress": companyDetailsArray[14],
                                                                               "accountNumber": companyDetailsArray[15],
                                                                               "routingNumber": companyDetailsArray[16],
                                                                               "payableTo": companyDetailsArray[17]
                                                                           });
                                                                           console.log("Invoice Company Information Stored");
                                                                            console.log("-----------------------\nFillin Invoice Items\n-----------------------")
                                                                           fillInvoiceItemsInformation();
                                                                        });
                                                                   });
                                                               });
                                                           });
                                                       });
                                                   });
                                               });
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
                });
            });
       });
   });
}




当初咱们曾经有了用户的根本信息,咱们能够集中精力收集单个我的项目,并另命名为” fillInvoiceItemsInformation”函数。在每个我的项目执行之前,咱们会询问用户是否要增加一个我的项目。如果他们持续输出” y”,那么咱们将收集该项目标信息,而后再次询问直到他们键入” n”:

function fillInvoiceItemsInformation() {
   const rl = readline.createInterface({
       input: process.stdin,
       output: process.stdout
   });
   var invoiceItemArray = [];
   rl.question('Add item?(y/n): ', (answer) => {
       switch (answer) {
            case "y":
               console.log("-----------------------\nEnter ItemInformation\n-----------------------");
                rl.question('Quantity: ',(answer) => {
                   invoiceItemArray.push(answer);
                    rl.question('Details: ',(answer) => {
                       invoiceItemArray.push(answer);
                        rl.question('UnitPrice: ', (answer) => {
                           invoiceItemArray.push(answer);
                           invoice.invoiceItems.push({
                               "quantity":invoiceItemArray[0],
                               "details": invoiceItemArray[1],
                               "unitPrice": invoiceItemArray[2]
                            });
                            console.log("ItemInformation Added");
                            rl.close();
                           fillInvoiceItemsInformation();
                        });
                    });
                });
                break;
            case "n":
               rl.close();
                return fillExcelFile();
                break;
            default:
                console.log("Incorrectoption, Please enter 'y' or 'n'.");
       }
   });
}

五、填入您的Excel 文件

在收集所有必须的用户信息后,咱们能够将其填入到Excel文件中:

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

为了避免用户增加的数量超过工作表最大行数,咱们能够在工作表中主动增加更多行。在设置数组中表单中的我的项目之前,默认增加行:

function fillInvoiceItems() {
   var sheet = wb.getSheet(0);
   var rowsToAdd = 0;
   if (invoice.invoiceItems.length > 15) {
       rowsToAdd = invoice.invoiceItems.length - 15;
       sheet.addRows(22, rowsToAdd);
   }
   var rowIndex = 8;
   if (invoice.invoiceItems.length >= 1) {
       for (var i = 0; i < invoice.invoiceItems.length; i++) {
            sheet.getCell(rowIndex,1).value(invoice.invoiceItems.quantity);
            sheet.getCell(rowIndex,2).value(invoice.invoiceItems.details);
            sheet.getCell(rowIndex,3).value(invoice.invoiceItems.unitPrice);
            rowIndex++;
       }
   }
}

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

在工作簿中填写完信息后,咱们能够将工作簿导出到Excel文件中。为此,咱们将应用excelio关上性能。在这种状况下,只需将日期输出文件名即可:

function exportExcelFile() {
   excelIO.save(wb.toJSON(), (data) => {
       fs.appendFileSync('Invoice' + new Date().valueOf() + '.xlsx', newBuffer(data), function (err) {
            console.log(err);
       });
       console.log("Export success");
   }, (err) => {
       console.log(err);
   }, { useArrayBuffer: true });
}

实现的文件将如下所示:

以上就是第一篇《从服务端生成Excel电子表格(Node.js+SpreadJS)》的全部内容。为了可能解决批量绑定数据源并导出Excel、批量批改大量Excel内容及款式、服务端批量打印以及生成PDF文档等需要,咱们提供了更为成熟的官网伎俩:SpreadJS + GcExcel,该计划提供了比Node.js+SpreadJS更加优良的性能和稳定性,这就是咱们下一篇《从服务端生成Excel电子表格(GcExcel + SpreadJS)》的次要内容,敬请期待。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理