Home > Net >  Create XLSX file from file contents from server and save it
Create XLSX file from file contents from server and save it

Time:09-28

I got Node JS server which gets XLSX file contents from metabase:

app.get('/channels', async (req, res) => {
            // make request to metabase and take response as XLSX
            const queryRequestURL = `${api}/public/card/${cardId}/query/xlsx?parameters=${params}`;
                
        const result = got(queryRequestURL);
                
        res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        res.setHeader("Content-Disposition", "attachment; filename=file.xlsx");
                
        return res.send(res);

        });

It returns file contents like

So when i make request to server and receive response - it comes as file contents above. I need to download this data as ordinary excel file on browser side.

What i've tried:

// make request with typical fetch and get result to res variable.
const filename = 'file.xlsx';
const file = new File(res, filename ,{ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

// create link and click it virtually to download created file
var a = document.createElement('a');
a.href = window.URL.createObjectURL(file);
a.download = filename;
a.click();

But I'm getting the error:

Uncaught (in promise) TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.

I think that I'm doing something wrong and there is more simple way to download file.

CodePudding user response:

Without seeing how you're fetching, it's hard to know. But you should be able to use response.blob() to download the result.

fetch("${api}/channels}", {
  method: "GET",
})
  .then((response) => response.blob())
  .then((blob) => {
    var url = window.URL.createObjectURL(blob);
    var a = document.createElement("a");
    a.href = url;
    a.download = "file.xlsx";
    document.body.appendChild(a);
    a.click();
    a.remove();
  });

CodePudding user response:

As Joey Ciechanowicz mentioned, we should return response.buffer() from backend and work with its data as blob at frontend. I mean

NodeJS side (using Got):

const result = got(queryRequestURL, {
        headers: headers
    });

    return await result.buffer()
    

Frontend side (pure JavaScript):

// fetch data
const result = await fetch(api   path);
return result.blob();

// download file
const filename = 'export.xlsx';

var url = window.URL.createObjectURL(result);
var a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
a.remove();
  • Related