Search code examples
javascriptnode.jsexpressresponseexceljs

How to generate xlsx file trough Express with Exceljs and send it to client?


I want to separate controllers and services in my Express app, currently, I have a service that generates an XLSX file using ExcelJS, I want to reuse the service so, I don't want to pass the response object to the service, is there a way I can return the file from the service to the controller?

Right now I have the following

const generateXLSX = (res, data) => {
  let baseFile = "path/to/template.xlsx";
  let wb = new Excel.Workbook();
  wb.xlsx
    .readFile(baseFile)
    .then(async () => {
       // add data to template
     }
      await wb.xlsx.write(res);
      res.end();
    })
    .catch((err) => {
      console.log(err);
      res.status(500);
    });
};

In this function I'm using the response object in the service, I want to know if there's a way to return the file without using write(res), and send it in the controller


Solution

  • Your generateXLSX function could return a "pass-through" readable stream which you then pipe into the res object. Something like

    const {PassThrough} = require("stream");
    function generateXLSX(data) {
      let baseFile = "path/to/template.xlsx";
      let wb = new Excel.Workbook();
      let readable = new PassThrough();
      wb.xlsx
        .readFile(baseFile)
        .then(async function() {
          // add data to template
          await wb.xlsx.write(readable);
          readable.end();
        })
        .catch((err) => {
          readable.destroy(err);
        });
      return readable;
    }
    
    app.use("/path", function(req, res) {
      generateXLSX(req.query.data).pipe(res);
    });