How to use exceljs for downloading?

Hi there! I use ‘exceljs’ package and I can’t understand how to use it for downloading a generated file. I use this code:

const { Workbook } = require('exceljs')

class SomeController {
  async someMethod() {
    const workbook = new Workbook
    const worksheet = workbook.addWorksheet(`Default`)
    
    // some code of filling the worksheed

    response.header(`Content-Type`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`)
    response.header(`Content-Disposition`, `attachment; filename="template.xlsx`)

    return workbook.xlsx.write(response)
  }
}

but it throws an exception all the time:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:516:11)
    at Object.Cookie._append (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/node-cookie/index.js:165:7)
    at Object.Cookie.create (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/node-cookie/index.js:387:10)
    at Response.cookie (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/@adonisjs/framework/src/Response/index.js:550:16)
    at Cookie.write (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/@adonisjs/session/src/Session/Drivers/Cookie.js:79:20)
    at Session.commit (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/@adonisjs/session/src/Session/index.js:201:34)
    at SessionMiddleware.handle (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/@adonisjs/session/src/Session/Middleware.js:84:25)
    at async BodyParser.handle (/Users/dakiesse/Development/scope-dev/reviewapply/backend/node_modules/@adonisjs/bodyparser/src/BodyParser/index.js:284:7)

What do I do wrong?

Look at https://adonisjs.com/docs/4.1/response#_making_response

Especially But… I like my callbacks! some lines below.

Thing is that as soon as you return something Adonis sends out response, but then comes workbook.xlsx.write(response) that tries to send another response to same request.

Also you might need to add double response in there like workbook.xlsx.write(response), since response is AdonisJS response object and response.response is raw NodeJS response

Add this line before modifying response header.
response.implicitEnd = false;

2 Likes