Downloading excel file on the frontend using excel4node in the backend

4.4k Views Asked by At

I'm aware that this has been asked before, but I'm not able to get it to work. The backend is sending the file using wb.write('filename.xlsx', res) but on the frontend, I just get an object response. How do I get the browser to download the .xlsx file instead?

// express backend
const x1 = require('excel4node');
router.get('/excel', async (req, res) => {
  const wb = new x1.Workbook();
  // do some stuff
  wb.write('excel.xlsx', res);
});
// frontend
axis(config).then((res) => {
  // What do I do here? res is an object.  How do I handle this response so that the browser is downloading the file instead?
}).catch(...);
2

There are 2 best solutions below

2
developerKumar On BEST ANSWER

Answer for front-end side,

You can write the axios code as follows:

axios.get('URL TO GET FILE BLOB', {
 responseType: 'blob'
}).then(response => {
   let headerLine = response.headers['content-disposition'];
   let startFileNameIndex = headerLine.indexOf('"') + 1
   let endFileNameIndex = headerLine.lastIndexOf('"')
   let filename = headerLine.substring(startFileNameIndex, endFileNameIndex)
   const url = window.URL.createObjectURL(new Blob([response.data], 
   {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}));
   const link = document.createElement('a');

   link.href = url;
   link.setAttribute('download', filename);
   document.body.appendChild(link);
   link.click();
   link.remove();
}).catch(error => {
   console.log(error)
})

Backend:

You need to make sure that you configured CORS properly, For your reference, please check the code below.

const express = require('express');
const xl = require('excel4node');
const cors = require('cors')  //use this

const app = express();
app.use(cors({exposedHeaders: '*'})) //and this
const PORT = process.env.PORT || 3001;

app.get('/', (req, res) => {
  var wb = new xl.Workbook();
 
  // Add Worksheets to the workbook
  var ws = wb.addWorksheet('Sheet 1');
  var ws2 = wb.addWorksheet('Sheet 2');
 
  // Create a reusable style
  var style = wb.createStyle({
    font: {
      color: '#FF0800',
      size: 12,
    },
    numberFormat: '$#,##0.00; ($#,##0.00); -',
  });
 
 // Set value of cell A1 to 100 as a number type styled with 
 ws.cell(1, 1)
    .number(100)
    .style(style);
 
 // Set value of cell B1 to 200 as a number type styled with 

paramaters of style
ws.cell(1, 2)
  .number(200)
  .style(style);
 
// Set value of cell C1 to a formula styled with paramaters of style
ws.cell(1, 3)
  .formula('A1 + B1')
  .style(style);
 
// Set value of cell A2 to 'string' styled with paramaters of style
ws.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.
ws.cell(3, 1)
  .bool(true)
  .style(style)
  .style({font: {size: 14}});

wb.write('Excel.xlsx', res);
});

app.listen(PORT, () => console.log(`Server is listening on port ${PORT}`));

At front-end side, we can extract file name along with extension from content disposition header. This is the same name that we set wb.write('Excel.xlsx', res);

0
Richard Rublev On

Try with blob response type

axios.request({url,method,responseType: 'blob'})
.then(({ data }) => {
const downloadUrl = window.URL.createObjectURL(new Blob([data]));