Сохранение буфера / потока, поступающего с сервера nodejs - PullRequest
0 голосов
/ 24 мая 2019

Я не уверен, что делаю неправильно.

У меня есть HTML-контент, и я хочу сохранить его в формате PDF. Я использую html-pdf (из npm) и библиотеку для скачивания http://danml.com/download.html

На самом деле, когда я напрямую сохраняю файл или показываю его в результате, я могу получить PDF без проблем. Но я вызываю свой метод веб-сервиса из метода js, и у меня есть поток / буфер в качестве возвращаемого значения и сохранение с помощью библиотеки «download»

Вот мой код

pdf.create(html, options).toFile('./mypdf.pdf', function (err, res) {
    if (err) return console.log(err);
        console.log(res);
  });

pdf.create(html,options).toBuffer(function (err, buffer) {
  if (err) return  reject(err);     
      return resolve(buffer);             
 });

//res.setHeader('Content-type', 'application/pdf');
pdf.create(html, options).toStream(function (err, stream) {
  if (err) return res.send(err);
     //res.type('pdf');
   return resolve(stream);// .pipe(res);
 });

Я могу сохранить контент в формате PDF, он отлично работает. но когда я пытаюсь отправить поток или буфер, как-то страница пуста. Я открыл оба файла PDF с помощью блокнота. Есть некоторые отличия. Например, проблемный - 44 КБ, другой - 78 КБ. и пустой содержит также следующие строки

% PDF-1.4 1 0 obj << / Заголовок ( ) / Создатель ( ) / Продюсер ( Q t 5. 5 1) / CreationDate (D: 20190524152156) </p>

endobj

Я думаю, что метод toBuffer или toStream имеет проблему в моем случае. Потому что поток кажется не плохим. по крайней мере, я вижу, что это PDF-файл (без ошибок, просто страница пуста)

В любом случае, вот мой маршрутизатор API

let result = await
routerVoucher.CreatePdfStream(req.query.VoucherCode,req.query.AppName);
res.setHeader('Content-type', 'application/pdf');
res.type('pdf');
//result.pipe(res);
res.end(result, 'binary');

а вот мой потребитель js

    $.ajax({
            type: "GET",
            url: '/api/vouchers/GetLicensePdf',
            data:data,
            success: function (pdfFile) {

                if (!pdfFile) 
                    throw new Error('There is nothing to download');

                    download(pdfFile,voucherCode + '.pdf', 'application/pdf')

1 Ответ

0 голосов
/ 26 мая 2019

Я решил проблему.

Сначала я преобразовал буфер в base64

const base64 = buffer.toString('base64')

, а затем преобразовал base64 в blob, используя следующий код

function base64toBlob (base64Data, contentType) {

    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    //var byteCharacters = decodeURIComponent(escape(window.atob(base64Data)))
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

а затем

снова я использовал мой метод загрузки (из библиотеки download.js), как следует

download(new Blob([base64toBlob(base64PDF,"application/pdf")]),
         voucherCode + '.pdf', "application/pdf");

тогда все в порядке :)

...