134

I am a nodejs programmer . Now I have a table of data that I want to save in Excel File format . How do I go about doing this ?

I found a few Node libraries . But most of them are Excel Parsers rather than Excel Writers .I am using a Linux Server . Hence need something that can run on Linux . Please let me know if there are any helpful libraries that you know of .

Or is there a way I can convert a CSV file to an xls file ( programmatically ) ?

1
  • Easiest way I found is just to read and write a .xlsx file instead of .xls: Create a multi-tab spreadsheet in Excel and save it out as a Strict XML Spreadsheet (.xlsx). Then rename to .zip, unzip, change contents, rezip, change to .xlsx. Easy. Saves faffing with other libraries, especially if you want to use it in client React etc which these days requires polyfills to get node libraries working. Commented Mar 24, 2023 at 7:50

11 Answers 11

149

Update 2024: You may wish to check @defraggled's answer below, as xlsx aka 'SheetJS' now has more downloads than excel4node

excel4node is a maintained, native Excel file creator built from the official specification. It's similar to, but more maintained than msexcel-builder mentioned in the other answer.

// Require library
var excel = require('excel4node');

// Create a new instance of a Workbook class
var workbook = new excel.Workbook();

// Add Worksheets to the workbook
var worksheet = workbook.addWorksheet('Sheet 1');
var worksheet2 = workbook.addWorksheet('Sheet 2');

// Create a reusable style
var style = workbook.createStyle({
  font: {
    color: '#FF0800',
    size: 12
  },
  numberFormat: '$#,##0.00; ($#,##0.00); -'
});

// Set value of cell A1 to 100 as a number type styled with paramaters of style
worksheet.cell(1,1).number(100).style(style);

// Set value of cell B1 to 300 as a number type styled with paramaters of style
worksheet.cell(1,2).number(200).style(style);

// Set value of cell C1 to a formula styled with paramaters of style
worksheet.cell(1,3).formula('A1 + B1').style(style);

// Set value of cell A2 to 'string' styled with paramaters of style
worksheet.cell(2,1).string('string').style(style);

// Set value of cell A3 to true as a boolean type styled with paramaters of style but with an adjustment to the font size.
worksheet.cell(3,1).bool(true).style(style).style({font: {size: 14}});

workbook.write('Excel.xlsx');
Sign up to request clarification or add additional context in comments.

13 Comments

Hi mikemaccana , where should i use this code. do i have to use this code in controller or any schema code. can you answer this question:stackoverflow.com/questions/44369082/…
I receive an error Error: Cannot find module 'excel4node', and installed it with npm install before used
@raz You should ask this as a question.
@mikemaccana is there any posssible way to export array list.
@tamilselvans Use an array.forEach(value, index) and worksheet.cell(column, row).string(value). Bette yet read the docs!
|
64

I just figured a simple way out . This works -

Just create a file with Tabs as delimiters ( similar to CSV but replace comma with Tab ). Save it with extension .XLS . The file can be opened in Excel .

Some code to help --

var fs = require('fs');
var writeStream = fs.createWriteStream("file.xls");

var header="Sl No"+"\t"+" Age"+"\t"+"Name"+"\n";
var row1 = "0"+"\t"+" 21"+"\t"+"Rob"+"\n";
var row2 = "1"+"\t"+" 22"+"\t"+"bob"+"\n";

writeStream.write(header);
writeStream.write(row1);
writeStream.write(row2);

writeStream.close();

This creates the file in XLS file format . It doesnt work if you try XLSX instead of XLS .

13 Comments

Why not use commas and create a CSV file with node and then import it into Excel? This way Excel can do its thing and create the xls/xlsx file properly.
Ah gotcha. Neat fix you found however.
In order to also support special characters, i made a simple wrapper with oh-csv github.com/SimpliField/oh-csv#excel-compatible-csv see stackoverflow.com/questions/6588068/…
"This creates the file in XLS file format." No it doesn't. It's still a CSV file and not capable of doing excel things,eg, multiple worksheets.
This does not answer the question at all, as it is not an excel file.
|
32

Although this question has several answers, they may now be a little dated.

New readers may prefer to consider the 'xlsx' also known as 'sheetsJS' module, which now seems to now be by far the most popular node package for this use case.

The current top answer recommends excel4node , which does look quite good - but the latter package seems less maintained (and far less popular) than the former.

Answering the question directly, using xlsx:

const XLSX = require('xlsx');

/* create a new blank workbook */
const workbook = XLSX.utils.book_new();

// Do stuff, write data
//
//

// write the workbook object to a file
XLSX.writeFile(workbook, 'out.xlsx');

4 Comments

For some people excel4node will be easier to grasp, especially if you come from the JQuery world were you chain things. But JQuery is dying for a good reason and XLSX is a much cleaner way of doing things, and gives alot more control.
I lost many hours trying to understand why it messed up my excel styles, only to find that the free community edition of sheetjs does not support styles. You have to buy the pro that does not even have a public price.
Nice, I added an update to my answer asking people to check this out instead.
If this leads to empty workbook error then try this: github.com/SheetJS/sheetjs/issues/365#issuecomment-181726459
25

Use msexcel-builder. Install it with:

npm install msexcel-builder

Then:

// Create a new workbook file in current working-path 
var workbook = excelbuilder.createWorkbook('./', 'sample.xlsx')

// Create a new worksheet with 10 columns and 12 rows 
var sheet1 = workbook.createSheet('sheet1', 10, 12);

// Fill some data 
sheet1.set(1, 1, 'I am title');
for (var i = 2; i < 5; i++)
  sheet1.set(i, 1, 'test'+i);

// Save it 
workbook.save(function(ok){
  if (!ok) 
    workbook.cancel();
  else
    console.log('congratulations, your workbook created');
});

6 Comments

Can I pipe the result file to a Response object instead of saving to a disk?
sure, try npm request.
This is an excellent answer (unlike the current marked answer, which doesn't create an Excel file at all) but mxexcel-builder hasn't had any updates for four years. I've added an answer using excel4node below.
Hi Hesham Yassin, can you answer this question:stackoverflow.com/questions/44369082/…
I am getting this warning in console when run their sample code from npm: (node:11702) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated.
|
20

You should check ExcelJS

Works with CSV and XLSX formats.

Great for reading/writing XLSX streams. I've used it to stream an XLSX download to an Express response object, basically like this:

app.get('/some/route', function(req, res) {
  res.writeHead(200, {
    'Content-Disposition': 'attachment; filename="file.xlsx"',
    'Transfer-Encoding': 'chunked',
    'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  })
  let workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res })
  let worksheet = workbook.addWorksheet('some-worksheet')
  worksheet.addRow(['foo', 'bar']).commit()
  worksheet.commit()
  workbook.commit()
}

Works great for large files, performs much better than excel4node (got huge memory usage & Node process "out of memory" crash after nearly 5 minutes for a file containing 4 million cells in 20 sheets) since its streaming capabilities are much more limited (does not allows to "commit()" data to retrieve chunks as soon as they can be generated)

See also this SO answer.

Comments

10

XLSx in the new Office is just a zipped collection of XML and other files. So you could generate that and zip it accordingly.

Bonus: you can create a very nice template with styles and so on:

  1. Create a template in 'your favorite spreadsheet program'
  2. Save it as ODS or XLSx
  3. Unzip the contents
  4. Use it as base and fill content.xml (or xl/worksheets/sheet1.xml) with your data
  5. Zip it all before serving

However I found ODS (openoffice) much more approachable (excel can still open it), here is what I found in content.xml

<table:table-row table:style-name="ro1">
    <table:table-cell office:value-type="string" table:style-name="ce1">
        <text:p>here be a1</text:p>
    </table:table-cell>
    <table:table-cell office:value-type="string" table:style-name="ce1">
        <text:p>here is b1</text:p>
    </table:table-cell>
    <table:table-cell table:number-columns-repeated="16382"/>
</table:table-row>

2 Comments

Learning the OOXML is a non-trivial task. Also using a different file format isn't an answer to the question - this would be better as a comment.
bonus section is very helpful, a short summary on how to get started with manipulating xlsx files
10

Using fs package we can create excel/CSV file from JSON data.

Step 1: Store JSON data in a variable (here it is in jsn variable).

Step 2: Create empty string variable(here it is data).

Step 3: Append every property of jsn to string variable data, while appending put '\t' in-between 2 cells and '\n' after completing the row.

Code:

var fs = require('fs');

var jsn = [{
    "name": "Nilesh",
    "school": "RDTC",
    "marks": "77"
   },{
    "name": "Sagar",
    "school": "RC",
    "marks": "99.99"
   },{
    "name": "Prashant",
    "school": "Solapur",
    "marks": "100"
 }];

var data='';
for (var i = 0; i < jsn.length; i++) {
    data=data+jsn[i].name+'\t'+jsn[i].school+'\t'+jsn[i].marks+'\n';
 }
fs.appendFile('Filename.xls', data, (err) => {
    if (err) throw err;
    console.log('File created');
 });

Output

2 Comments

Isnt this just a copy of one of the answers ?
Probable I have extended previous answer.
6

install exceljs

npm i exceljs --save

import exceljs

var Excel = require('exceljs');
var workbook = new Excel.Workbook();

create workbook

var options = {
                filename: __dirname+'/Reports/'+reportName,
                useStyles: true,
                useSharedStrings: true
            };

            var workbook = new Excel.stream.xlsx.WorkbookWriter(options);

after create worksheet

var worksheet = workbook.addWorksheet('Rate Sheet',{properties:{tabColor:{argb:'FFC0000'}}});

in worksheet.column array you pass column name in header and array key pass in key

worksheet.columns = [
            { header: 'column name', key: 'array key', width: 35},
            { header: 'column name', key: 'array key', width: 35},
            { header: 'column name', key: 'array key', width: 20},

            ];

after using forEach loop append row one by one in exel file

array.forEach(function(row){ worksheet.addRow(row); })

you can also perfome loop on each exel row and cell

worksheet.eachRow(function(row, rowNumber) {
    console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});
row.eachCell(function(cell, colNumber) {
    console.log('Cell ' + colNumber + ' = ' + cell.value);
});

Comments

4

Or - build on @Jamaica Geek's answer, using Express - to avoid saving and reading a file:

  res.attachment('file.xls');

  var header="Sl No"+"\t"+" Age"+"\t"+"Name"+"\n";
  var row1 = [0,21,'BOB'].join('\t')
  var row2 = [0,22,'bob'].join('\t');

  var c = header + row1 + row2;
  return res.send(c);

1 Comment

Unfortunately this is not a good idea. your data will likely break such naive code: Problems you will encounter using the above method: 1. broken columns when your cells include quote character or a new line ; and 2. encoding issues when importing to Excel on Mac (you must include correct BOM decodeURIComponent("%EF%BB%BF") and encode using UTF16LE. I recommend using a proper library instead
3

Use exceljs library for creating and writing into existing excel sheets.

You can check this tutorial for detailed explanation.

link

Comments

1

First parameter is the source file

Second parameter is the separator

Third parameter is the resulting file (*.xlsx)

Attention: to increase node heap use: node --max-old-space-size=4096 index.js

const fs = require('fs');
var xl = require('excel4node');
const data = fs.readFileSync(process.argv[2], 'utf-8');
const lines = data.split(/\r?\n/);
const linesFromOne = [null].concat(lines);
var wb = new xl.Workbook();
var ws = wb.addWorksheet('Planilha 1');
for (let j=1;j<=linesFromOne.length-1;j++){             
  // Create a reusable style
  var style = wb.createStyle({
    font: {
      color: '#050000',
      size: 12,
    },

  });

    pieces = linesFromOne[j].split(process.argv[3])
    pieces.forEach((element, index) =>{
    ws.cell(j, index+1).string(element)
    .style(style);
    });

} 

wb.write(process.argv[4]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.