22

I am using exceljs module for creating excel file. The problem is it is neither getting created nor getting saved in the path.

var excel = require('exceljs');
var options = {
    filename: './streamed-workbook.xlsx',
    useStyles: true,
    useSharedStrings: true
};

var workbook = new Excel.stream.xlsx.WorkbookWriter(options);
var sheet = workbook.addWorksheet('My Sheet');
worksheet.columns = [
    { header: 'Id', key: 'id', width: 10 },
    { header: 'Name', key: 'name', width: 32 },
    { header: 'D.O.B.', key: 'DOB', width: 10 }
];

worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
worksheet.commit();

workbook.commit().then(function(){
    console.log('xls file is written.');
});

But when I run the code nothing happens. The excel is not created. What am I missing here?

*********************** Edit ************************** Made the following changes to my code but still its not working.

        var Excel = require('exceljs');
        var workbook = new Excel.Workbook();
        var worksheet = workbook.addWorksheet('My Sheet');
        worksheet.columns = [
            { header: 'Id', key: 'id', width: 10 },
            { header: 'Name', key: 'name', width: 32 },
            { header: 'D.O.B.', key: 'DOB', width: 10 }
        ];
        worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
        worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});
        workbook.commit();
        workbook.xlsx.writeFile('./temp.xlsx').then(function() {
            // done
            console.log('file is written');
        });
codeinprogress
  • 3,193
  • 7
  • 43
  • 69

6 Answers6

28

In order to send the excel workbook to the client you can:

Using async await:

async function sendWorkbook(workbook, response) { 
    var fileName = 'FileName.xlsx';

    response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

     await workbook.xlsx.write(response);

    response.end();
}

Using promise:

function sendWorkbook(workbook, response) { 
    var fileName = 'FileName.xlsx';

    response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

    workbook.xlsx.write(response).then(function(){
        response.end();
    });
}
Danielle
  • 860
  • 10
  • 13
  • 1
    The file is not being downloaded but in the response there's this unreadable content with random characters. Do you have any idea why this method in not working for me? – Kirubel Dec 08 '20 at 07:51
  • @Kirubel if you use postman, you can click Save Response dropdown and choose save to a file. Based on the content type that set to the header, let's say excel format, it will saved as an excel file. – Randi Pratama Jan 12 '21 at 22:06
  • 2
    I am getting a corrupted excel file. – Rohit Vyas Jun 02 '21 at 16:01
8

get answer from this link https://github.com/exceljs/exceljs/issues/37

    router.get('/createExcel', function (req, res, next) {
    var workbook = new Excel.Workbook();

    workbook.creator = 'Me';
    workbook.lastModifiedBy = 'Her';
    workbook.created = new Date(1985, 8, 30);
    workbook.modified = new Date();
    workbook.lastPrinted = new Date(2016, 9, 27);
    workbook.properties.date1904 = true;

    workbook.views = [
        {
            x: 0, y: 0, width: 10000, height: 20000,
            firstSheet: 0, activeTab: 1, visibility: 'visible'
        }
    ];
    var worksheet = workbook.addWorksheet('My Sheet');
    worksheet.columns = [
        { header: 'Id', key: 'id', width: 10 },
        { header: 'Name', key: 'name', width: 32 },
        { header: 'D.O.B.', key: 'dob', width: 10, outlineLevel: 1, type: 'date', formulae: [new Date(2016, 0, 1)] }
    ];

    worksheet.addRow({ id: 1, name: 'John Doe', dob: new Date(1970, 1, 1) });
    worksheet.addRow({ id: 2, name: 'Jane Doe', dob: new Date(1965, 1, 7) });

    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader("Content-Disposition", "attachment; filename=" + "Report.xlsx");
    workbook.xlsx.write(res)
        .then(function (data) {
            res.end();
            console.log('File write done........');
        });
 }
gandalivs
  • 383
  • 3
  • 4
7

So I figured out that I was getting an error because of the workbook.commit(). I removed the commit and everything started working like a charm. Here is the entire working code of creating and downloading an excel file:

Note: I am using an npm module called tempfile to create a temporary file path for the created excel file. This file path is then automatically removed. Hope this helps.

try {
        var workbook = new Excel.Workbook();
        var worksheet = workbook.addWorksheet('My Sheet');

        worksheet.columns = [
            { header: 'Id', key: 'id', width: 10 },
            { header: 'Name', key: 'name', width: 32 },
            { header: 'D.O.B.', key: 'DOB', width: 10 }
        ];
        worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
        worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

        var tempFilePath = tempfile('.xlsx');
        workbook.xlsx.writeFile(tempFilePath).then(function() {
            console.log('file is written');
            res.sendFile(tempFilePath, function(err){
                console.log('---------- error downloading file: ' + err);
            });
        });
    } catch(err) {
        console.log('OOOOOOO this is the error: ' + err);
    }
codeinprogress
  • 3,193
  • 7
  • 43
  • 69
  • how to call this code from controller.js side. can you tell @codein progress – Vinoth Jun 07 '17 at 12:24
  • 1
    In my case its a router.get() request. so router.get('/download', function(req, res){...the above code}); – codeinprogress Jun 07 '17 at 13:54
  • can you check my code. @Codeinprogress https://stackoverflow.com/questions/44369082/excel-download-is-not-working-in-mean-stack-app?noredirect=1#comment75820326_44369082 I have done like this – Vinoth Jun 08 '17 at 05:19
  • 1
    It looks like you are using a different excel module for node.js. This is the one I am using: https://www.npmjs.com/package/exceljs – codeinprogress Jun 09 '17 at 06:41
  • Hi i am new to AngularJS. I am getting router is not defined error and where should i use this code. var excel = require('exceljs'); var options = { filename: './streamed-workbook.xlsx', useStyles: true, useSharedStrings: true }; – Vinoth Jun 09 '17 at 06:56
  • can you read my question: https://stackoverflow.com/questions/44515992/errorunhandledpromiserejectionwarning-excel-file-not-downloading-in-server-s?noredirect=1#comment76028378_44515992 – Vinoth Jun 14 '17 at 09:38
  • I am fully copy and paste it your code in $http.get() i got error msg '---------- error downloading file: Undefined' – Vinoth Jun 14 '17 at 10:02
  • @Vinoth you cannot just copy paste someone's code and expect it to work directly. I would suggest you do some research and reading on express, router. Thats all I can help you with. – codeinprogress Jun 14 '17 at 12:14
  • after lot of research, finally i completed @codeinprogress – Vinoth Jun 15 '17 at 05:14
  • @Vinoth can u tell what issue were u facing ? – Ratnabh kumar rai Feb 18 '20 at 12:21
1

This code snippet is using node.js with the excel4node and express modules in order to convert JSON data to an Excel file and send it to the client, using Javascript.

const xl = require('excel4node');
const express = require('express');
const app = express();

var json = [{"Vehicle":"BMW","Date":"30, Jul 2013 09:24 AM","Location":"Hauz Khas, Enclave, New Delhi, Delhi, India","Speed":42},{"Vehicle":"Honda CBR","Date":"30, Jul 2013 12:00 AM","Location":"Military Road,  West Bengal 734013,  India","Speed":0},{"Vehicle":"Supra","Date":"30, Jul 2013 07:53 AM","Location":"Sec-45, St. Angel's School, Gurgaon, Haryana, India","Speed":58},{"Vehicle":"Land Cruiser","Date":"30, Jul 2013 09:35 AM","Location":"DLF Phase I, Marble Market, Gurgaon, Haryana, India","Speed":83},{"Vehicle":"Suzuki Swift","Date":"30, Jul 2013 12:02 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Civic","Date":"30, Jul 2013 12:00 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Accord","Date":"30, Jul 2013 11:05 AM","Location":"DLF Phase IV, Super Mart 1, Gurgaon, Haryana, India","Speed":71}]

const createSheet = () => {

  return new Promise(resolve => {

// setup workbook and sheet
var wb = new xl.Workbook();

var ws = wb.addWorksheet('Sheet');

// Add a title row

ws.cell(1, 1)
  .string('Vehicle')

ws.cell(1, 2)
  .string('Date')

ws.cell(1, 3)
  .string('Location')

ws.cell(1, 4)
  .string('Speed')

// add data from json

for (let i = 0; i < json.length; i++) {

  let row = i + 2

  ws.cell(row, 1)
    .string(json[i].Vehicle)

  ws.cell(row, 2)
    .date(json[i].Date)

  ws.cell(row, 3)
    .string(json[i].Location)

  ws.cell(row, 4)
    .number(json[i].Speed)
}

resolve( wb )

  })
}

app.get('/excel', function (req, res) {

  createSheet().then( file => {
    file.write('ExcelFile.xlsx', res);
  })

});

app.listen(3040, function () {
  console.log('Excel app listening on port 3040');
});
philipeachille
  • 185
  • 1
  • 6
0

There is a mistake in your Code.

You have declared your My Sheet with one variable and using a different variable in your entire code.

var sheet = workbook.addWorksheet('My Sheet');

worksheet.columns = [ { header: 'Id', key: 'id', width: 10 }, { header: 'Name', key: 'name', width: 32 }, { header: 'D.O.B.', key: 'DOB', width: 10 } ];

worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});

worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

worksheet.commit();

Change variable Sheet to Worksheet. Like the below code

var worksheet = workbook.addWorksheet('My Sheet');

worksheet.columns = [ { header: 'Id', key: 'id', width: 10 }, { header: 'Name', key: 'name', width: 32 }, { header: 'D.O.B.', key: 'DOB', width: 10 } ];

worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});

worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

worksheet.commit();

This should fix your issue. Thanks

Princess
  • 36
  • 2
0
var excel = require("exceljs");
var workbook1 = new excel.Workbook();
workbook1.creator = 'Me';
workbook1.lastModifiedBy = 'Me';
workbook1.created = new Date();
workbook1.modified = new Date();
var sheet1 = workbook1.addWorksheet('Sheet1');
var reHeader=['FirstName','LastName','Other Name'];
var reColumns=[
    {header:'FirstName',key:'firstname'},
    {header:'LastName',key:'lastname'},
    {header:'Other Name',key:'othername'}
];
sheet1.columns = reColumns;
workbook1.xlsx.writeFile("./uploads/error.xlsx").then(function() {
    console.log("xlsx file is written.");
});

This creates xlsx file in uploads folder.

Karthik
  • 129
  • 2
  • 8
  • Ok, but is there a way to download it as soon as it gets created? I want the users to click a button > the excel file is generated > a download/save option is given to them. – codeinprogress Aug 31 '16 at 10:21
  • I have found the solution for downloading the created file. Please see: http://stackoverflow.com/questions/39667773/how-to-give-download-window-option-to-user-in-a-node-js-express-application/39669021#39669021 – codeinprogress Sep 25 '16 at 10:11