Создайте файл XLSX из содержимого файла с сервера и сохраните его

У меня есть сервер Node JS, который получает содержимое файла XLSX из метабазы:

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);

        });

Он возвращает содержимое файла, например

Поэтому, когда я делаю запрос на сервер и получаю ответ, он выглядит как содержимое файла выше. Мне нужно загрузить эти данные как обычный файл Excel на стороне браузера.

Что я пробовал:

// 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();

Но я получаю сообщение об ошибке:

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

Я думаю, что я делаю что-то не так, и есть более простой способ скачать файл.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
209
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не видя, как ты собираешься, трудно понять. Но вы должны иметь возможность использовать response.blob() для загрузки результата.

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();
  });

Ваш ответ помог мне понять, что я делаю неправильно, спасибо

Alexander Guskov 28.09.2022 05:08
Ответ принят как подходящий

Как упомянул Joey Ciechanowicz, мы должны возвращать response.buffer() из бэкэнда и работать с его данными в виде большого двоичного объекта во внешнем интерфейсе. Я имею в виду

Сторона NodeJS (с использованием Got):

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

    return await result.buffer()
    

Внешний интерфейс (чистый 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();

Другие вопросы по теме