1

I successfully create a excel file with excel4node and save it in the server, then I use a read stream to send the file to the client:

            res.set({
                'Content-Type': 'application/vnd.openxmlformats',
                'Content-Disposition': 'attachment; filename='+filename
            });

            // This line opens the file as a readable stream
            var readStream = fs.createReadStream(path+filename, {encoding: 'utf8'});

            // This will wait until we know the readable stream is actually valid before piping
            readStream.on('open', function () {
                // This just pipes the read stream to the response object (which goes to the client)
                readStream.pipe(res);
            });
            // This catches any errors that happen while creating the readable stream (usually invalid names)
            readStream.on('error', function(err) {
            res.end(err);
            });

After that I get the data in the browser and download it using Blob:

        var blob = new Blob([data], { type: 'application/vnd.openxmlformats' });
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = "File.xlsx";

        document.body.appendChild(link);

        link.click();

        document.body.removeChild(link);

When I try to open the file I get the following message:

"Excel found unreadable content in 'File.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes"

And if I click yes, excel says that the file is corrupt and can't be recovered.

I would like to know what can I do to retrieve the excel file from the server.

dilver
  • 55
  • 2
  • 11
  • How large is the file? Some browsers have limits as to how long a data url can be. Have you also tried taking a look at the file manually to see what it looks like? – cbr Mar 01 '20 at 18:37
  • The file is small, less than 10KiB, the file it's ok,I opened the file that is created in the backend with excel – dilver Mar 01 '20 at 21:32
  • No, have you taken a look at the file downloaded from the frontend with a text editor or a hex editor? – cbr Mar 01 '20 at 21:50
  • Yes, but it's a bunch of illegible characters – dilver Mar 01 '20 at 22:32

1 Answers1

1

After reading a lot of posts, I found the answer here How to save .xlsx data to file as a blob

I have to encode the stream as base64 in the backend, using 'base64-stream' and the 'excel4node' .write function

wb.write(path+filename, function(err) {
                if (err) {
                    sails.log(err);
                } else {
                    // This line opens the file as a readable stream
                    var readStream = fs.createReadStream(path+filename);

                    // This will wait until we know the readable stream is actually valid before piping
                    readStream.on('open', function () {
                        // This just pipes the read stream to the response object (which goes to the client)
                        readStream.pipe(new Base64Encode()).pipe(res);
                    });
                    // This catches any errors that happen while creating the readable stream (usually invalid names)
                    readStream.on('error', function(err) {
                        res.end(err);
                    });
                }
            });

After that I received the data in the browser as follows:

.done(function(data){

      function s2ab(s) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
      }

        var blob = new Blob([s2ab(atob(data))], { type: 'application/vnd.openxmlformats' });
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = "ExcelFile.xlsx";

        document.body.appendChild(link);

        link.click();

        document.body.removeChild(link);
    })

The problem was in the encoding, and even if you use 'utf16le' the file can't be read by excel, so that was the best solution that I found.

dilver
  • 55
  • 2
  • 11