Search code examples
javascriptnode.jsgetnestjsexceljs

How to CONVERT json data to excel file with nodejs


I'm trying to get excel file of my data as below. However, my code doesn't work. Does anyone know, why? I don't get any result or any error. It just doesn't do anything. This method is in a controller. So I'm calling this method from postman

import {Workbook} from  "exceljs";
import * as tmp from  "tmp";

    @Get()
    @Header("Content-Type", "text/xlsx")
    async getExcel(@Response() res) {

        let rows = []

        let data = [{name: "shelly", surname: "shelly"}, {name: "shelly1", surname: "shelly1"},]
          
          data(doc => {
            rows.push(Object.values(doc))
          })

          let book = new Workbook();
          let sheet = book.addWorksheet(`sheet1`);
          rows.unshift(Object.keys(data[0]));
          sheet.addRows(rows)

          
          let File = await new Promise((resolve,reject) =>{
            tmp.file({discardDescriptor: true, prefix: `ExcelSheet`, postfix:`.xlsx`, mode: parseInt(`0600`,8)}, async (err, file) =>{
                if(err)
                    throw new BadRequestException(err);
                
                book.xlsx.writeFile(file).then(_ =>{
                    resolve(file)
                }).catch(err => {
                    throw new BadRequestException(err)
                })
            })
          })


          res.download(`${File}`)
    }

Using nodejs with nestjs framework.


Solution

  • The code is basically valid and it works. It has a couple of syntax errors and that's it.

    Here is the fixed code with differences related to syntax errors commented on.

    // Missing imports (possibly just not copy-pasted)
    import { BadRequestException, Controller, Get, Header, Res } from "@nestjs/common";
    import { Workbook } from "exceljs";
    import * as tmp from "tmp";
    
    @Controller('json-to-excel')
    export class JsonToExcelController {
      @Get()
      @Header("Content-Type", "text/xlsx")
      // Decorator @Res is provided by Nest to describe Response, not @Response.
      async getExcel(@Res() res) {
    
        let rows = []
    
        let data = [{name: "shelly", surname: "shelly"}, {name: "shelly1", surname: "shelly1"},]
    
        // Array was called as a function. It has method 'forEach' to iterate.
        data.forEach(doc => {
          rows.push(Object.values(doc))
        })
    
        let book = new Workbook();
        let sheet = book.addWorksheet(`sheet1`);
        rows.unshift(Object.keys(data[0]));
        sheet.addRows(rows)
    
    
        let File = await new Promise((resolve,reject) =>{
          tmp.file({discardDescriptor: true, prefix: `ExcelSheet`, postfix:`.xlsx`, mode: parseInt(`0600`,8)}, async (err, file) =>{
            if(err)
              throw new BadRequestException(err);
    
            book.xlsx.writeFile(file).then(_ =>{
              resolve(file)
            }).catch(err => {
              throw new BadRequestException(err)
            })
          })
        })
    
    
        res.download(`${File}`)
      }
    }
    

    Was this the issue?