suggest npm packages for Array to excel in Nodejs - node.js

All,
I have two simple arrays as below and want to dump the data in to excel in Nodejs. Please suggest a good npm packages for the same.
var Headers = ['ChangeId', 'ChangeDescription', 'ChangeDate', 'Enhancement/Fix', 'ExcutorTeam'];
var Data = ['INC1234', 'Multiple Cert cleanup', '04/07/2022', 'Enhancement', 'IlevelSupport'];

You can use xlsx npm package and do something like this
This is a quick example that works, things could be improved but it will at least give you a starting point
const xlsx = require('xlsx');
let Headers = ['ChangeId', 'ChangeDescription', 'ChangeDate', 'Enhancement/Fix', 'ExcutorTeam'];
let Data = ['INC1234', 'Multiple Cert cleanup', '04/07/2022', 'Enhancement', 'IlevelSupport'];
let workbook = xlsx.utils.book_new();
let worksheet = xlsx.utils.aoa_to_sheet([]);
xlsx.utils.book_append_sheet(workbook, worksheet);
xlsx.utils.sheet_add_aoa(worksheet, [Headers], { origin: 'A1' });
xlsx.utils.sheet_add_aoa(worksheet, [Data], { origin: 'A2' });
xlsx.writeFile(workbook, "Test.xlsx");

CSV format is just comma separated string with new lines. With that in mind we want to create a string that has the format:
ChangeId,ChangeDescription,ChangeDate,Enhancement/Fix,ExcutorTeam
INC1234,Multiple Cert cleanup,04/07/2022,Enhancement,IlevelSupport
We can iterate over Data in Headers.length sized chunks:
const numColumns = Headers.length;
let file = `${Headers.join(",")}\n`;
for (let i = 0; i < Data.length; i += numColumns) {
file += `${Data.slice(i, i + numColumns).join(",")}\n`;
}
fs.writeFileSync("file.csv", file);
Hope that gets you started in the right direction.

Related

How to get known Windows folder path with Node

I need to access per-machine configuration data in my Node application running on Windows. I've found this documentation for how to find the location:
Where Should I Store my Data and Configuration Files if I Target Multiple OS Versions?
So, in my case, I would like to get the path for CSIDL_COMMON_APPDATA (or FOLDERID_ProgramData). However, the examples are all in C, and I would prefer to not have to write a C extension for this.
Is there any other way to access these paths from Node, or should I just hardcode them?
After doing a bit of research, I've found that it's possible to call the relevant Windows API proc. (SHGetKnownFolderPath) to get these folder locations, see docs at: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx.
We call the APi using the FFI npm module: https://www.npmjs.com/package/ffi.
It is possible to find the GUIDs for any known folder here:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
Here is a script that finds the location of several common folders,
some of the code is a little hacky, but is easily cleaned up.
const ffi = require('ffi');
const ref = require('ref');
const shell32 = new ffi.Library('Shell32', {
SHGetKnownFolderPath: ['int', [ ref.refType('void'), 'int', ref.refType('void'), ref.refType(ref.refType("char"))]]
});
function parseGUID(guidStr) {
var fields = guidStr.split('-');
var a1 = [];
for(var i = 0; i < fields.length; i++) {
var a2 = [...Buffer.from(fields[i], 'hex')];
if (i < 3) a2 = a2.reverse();
a1 = a1.concat(a2);
}
return new Buffer(a1);
}
function getWindowsKnownFolderPath(pathGUID) {
let guidPtr = parseGUID(pathGUID);
guidPtr.type = ref.types.void;
let pathPtr = ref.alloc(ref.refType(ref.refType("void")));
let status = shell32.SHGetKnownFolderPath(guidPtr, 0, ref.NULL, pathPtr);
if (status !== 0) {
return "Error occurred getting path: " + status;
}
let pathStr = ref.readPointer(pathPtr, 0, 200);
return pathStr.toString('ucs2').substring(0, (pathStr.indexOf('\0\0') + 1)/2);
}
// See this link for a complete list: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
const WindowsKnownFolders = {
ProgramData: "62AB5D82-FDC1-4DC3-A9DD-070D1D495D97",
Windows: "F38BF404-1D43-42F2-9305-67DE0B28FC23",
ProgramFiles: "905E63B6-C1BF-494E-B29C-65B732D3D21A",
Documents: "FDD39AD0-238F-46AF-ADB4-6C85480369C7"
}
// Enumerate common folders.
for(let [k,v] of Object.entries(WindowsKnownFolders)) {
console.log(`${k}: `, getWindowsKnownFolderPath(v));
}

Read XLSX file data with Exceljs library

Kindly see below code. I want to read data from xlsx file, worksheet name is : WPA ext libs 2017.10.05. for now I want to read values of first column. What changes should I do in code below?
please see exceljs link.
var Excel = require("exceljs");
var workbook = new Excel.Workbook();
workbook.xlsx.readFile("./CIoT_External Libraries & 3rd Party Content.xlsx")
.then(function(data){
var worksheet = workbook.getWorksheet("WPA ext libs 2017.10.05");
var lN = worksheet.getColumn(1);
console.log(lN.collapsed);
});
Yoo.. I got answer. if someone knows better answer than this please let me know. :)
var Excel = require("exceljs");
var workbook = new Excel.Workbook();
workbook.xlsx.readFile("./CIoT_External Libraries & 3rd Party Content.xlsx" )
.then(function(data){
var worksheet = workbook.getWorksheet("WPA ext libs 2017.10.05");
for(var v=1;v<=worksheet.actualRowCount;v++)
{
var lN = worksheet.getCell("B"+v).value;
console.log(" V :"+v+"------ Name :" +lN);
}
});
The best way to loop through the rows of an excel file using exceljs is using the builtin method .eachRow()
var Excel = require("exceljs");
var workbook = new Excel.Workbook();
workbook.xlsx.readFile("./CIoT_External Libraries & 3rd Party Content.xlsx" )
.then(function(data){
var worksheet = workbook.getWorksheet("WPA ext libs 2017.10.05");
worksheet.eachRow(function (row, rowNumber){
// row_values contains the values, (first column is indexed by
var row_values = row_1.values;
// Now you can access the columns directly by the column index
Console.log("Value of Column B is : "+ row_values[2])
}
});

Angular export Excel client side

I'm using Angular v4, i guess how can I build an Excel spreadsheet starting from an object in a component. I need to download the Excel file on the click of a button and I have to do this client side. I have a json file composed of arrays and I need to transfer this on an excel file, possibly customizable in style. Is it possible? If yes, how?
Edit:
No js libraries please, need to do this with Typescript and Angular
yourdata= jsonData
ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
var row = "";
for (var index in objArray[0]) {
//Now convert each value to string and comma-separated
row += index + ',';
}
row = row.slice(0, -1);
//append Label row with line break
str += row + '\r\n';
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (line != '') line += ','
line += array[i][index];
}
str += line + '\r\n';
}
return str;
}
in your html:
<button (click)="download()">export to excel</button>
in component:
download(){
var csvData = this.ConvertToCSV(yourdata);
var a = document.createElement("a");
a.setAttribute('style', 'display:none;');
document.body.appendChild(a);
var blob = new Blob([csvData], { type: 'text/csv' });
var url= window.URL.createObjectURL(blob);
a.href = url;
a.download = 'User_Results.csv';/* your file name*/
a.click();
return 'success';
}
Hope you it will help you
Vishwanath answer was working for me when i replaced "," with ";". In Typescript the implementation could look like this:
ConvertToCSV(objArray: any) {
const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
let str = '';
let row = '';
for (const index of Object.keys(objArray[0])) {
row += `${index};`;
}
row = row.slice(0, -1);
str += `${row}\r\n`;
for (let i = 0; i < array.length; i++) {
let line = '';
for (const index of Object.keys(array[i])) {
if (line !== '') {
line += ';';
}
line += array[i][index];
}
str += `${line}\r\n`;
}
return str;
}
I hope this helps someone.
I think you will not get that done without js libraries in the background. What you need are the typings for utilizing it in your Angular project with typescript.
For creating an excel file you could use something like exceljs. To use it in your project also install the typings you can find here. I am not sure if this library fits... haven't used it before.
For downloading you should use FileSaver.js (I have already used it).
npm install file-saver --save
... and the typings:
npm install #types/file-saver --save-dev
For using FileSaver.js put the following import to your component:
import * as FileSaver from 'file-saver';
To trigger the download use that:
FileSaver.saveAs(fileData, "filename.xlsx")
'fileData' has to be a Blob.
Hope this helps a little.
it not is possible.
XLS is a binary format.
The project Apache POI(https://en.wikipedia.org/wiki/Apache_POI) name class as HSSF (Horrible SpreadSheet Format).
my recommendation, make it in server side.

how can i read data from specific row and column to specific row and column from excel sheet to json format in nodejs

I am using xlsx package. Please suggest any other package if available
I tried this but i am not getting complete data
var sheet, jsonData,
excelString = new Buffer(base64, 'base64').toString('binary'),
workbook = excelParser.read(excelString, {type: 'binary'});
if (workbook.Sheets['Sheet1']) {
sheet = workbook.Sheets['Sheet1'];
workbook.Sheets['Sheet1'] = sheet;
jsonData = excelParser.utils.sheet_to_json(workbook.Sheets['Sheet1'], {});
you can use
npm install excel
use this.
var parseXlsx = require('excel');
parseXlsx('Spreadsheet.xlsx', function(err, data) {
if(err) throw err;
// data is an array of arrays
});
and you can also visit Converting excel file to json in nodejs
Note: Make sure your Excel file is not opened by any other software (especially Excel !).
Happy coding.
var XLSX = require('xlsx');
var workbook = XLSX.readFile('Test1.xlsx');
var first_sheet_name = workbook.SheetNames[0];
// to read the value of individual cell
var address_of_cell = 'C4';
var worksheet = workbook.Sheets[first_sheet_name];
var desired_cell = worksheet[address_of_cell];
var desired_value = (desired_cell ? desired_cell.v : undefined);
console.log(desired_value);
For further clarification read through the documentation of xlsx https://www.npmjs.com/package/xlsx
var XLSX = require('xlsx');
var workbook = XLSX.readFile(path);
var sheet_name_list = workbook.SheetNames;
var xlData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);
for (let i = 0; i < xlData.length; i++) {
let employee_choice1 = xlData[i].employee_choice
var employee_choice = employee_choice1.split(',')
//implement your condition
}

JSON to Excel convertion in Nodejs

I'm trying to convert large amount of json data to excel and tried couple of modules
Below are my findings, if anyone used better node module which handle more data please let me know so that i can explore
json2xls
JSON array with 100000 length took 402574ms
once i exceeded to 200000 it failed with this error FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
node-xls
JSON array with 100000 length took 444578ms
I tried this in windows 7 system with 8GB RAM, Intel Core i7, CPU # 2.10Ghz - 2.70Ghz
First push your data into a temporary array with required column and then convert it into xls, I have done it in following manner:
// use the below package to convert json to xls
var json2xls = require('json2xls');
json.forEach(function(instance, indexx,record){
var tempArry = {
'ColoumnName1' : record[indexx].columnNameVlaue,
'ColoumnName2' : record[indexx].columnNameVlaue,
'ColoumnName3' : record[indexx].columnNameVlaue,
'ColoumnName4' : record[indexx].columnNameVlaue
}
jsonArray.push(tempArry);
});
//this code is for sorting xls with required value
jsonArray.sort(function(a, b) {
return parseFloat(b.ColoumnName4) - parseFloat(a.ColoumnName4);
});
var xls = json2xls(jsonArray);
fs.writeFileSync('yourXLName.xlsx', xls, 'binary');
Dont try to add all the data into the excel file, use the specific columns you want in the file to be saved.
If its a nodejs project then do this,
const xlsx = require("xlsx")//npm install xlsx
const fs = require("fs")//npm install fs
var rawFile = fs.readFileSync("./datas.json")//dir of your json file as param
var raw = JSON.parse(rawFile)
var files = []
for (each in raw){
files.push(raw[each])
}
var obj = files.map((e) =>{
return e
})
var newWB = xlsx.book_new()
var newWS = xlsx.utils.json_to_sheet(obj)
xlsx.utils.book_append_sheet(newWB,newWS,"name")//workbook name as param
xlsx.writeFile(newWB,"Sample-Sales-Data.xlsx")//file name as param
In Ratul Das' answer, there is a typo on the following line:
var newWB = xlsx.book_new()
The code should read:
var newWB = xslx.utils.book_new()
The snippet below is the code I use to generate an Excel spreadsheet from an array of JSON objects named imageList:
const workSheet = XLSX.utils.json_to_sheet(imageList);
const workBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workBook, workSheet, "Product Image Catalog");
// Generate buffer
XLSX.write(workBook, {bookType: 'xlsx', type: 'buffer'})
// Binary String
XLSX.write(workBook, {bookType: 'xlsx', type: 'binary'})
XLSX.writeFile(workBook, 'image-catalog.xlsx')
Building the buffer helps with large amounts of data.
If your JSON is already properly formatted, you juste have to do:
const json2xls = require('json2xls');
// Example JSON
const json = [{firstName: 'Bob', name: 'Lennon'}, {firstName: 'Jack', name: 'Sparrow'}]
const xls = json2xls(json);
fs.writeFileSync('exported.xlsx', xls, 'binary');
Works fine, and very simple.

Resources