скачайте PDF с Javascript / Node.Js после генерации данных и сохранения файла в путь - PullRequest
0 голосов
/ 09 июля 2019

Я создал генератор для файлов PDF, который создает файл и автоматически отправляет его по указанному пути.Тем не менее, я хочу скачать его сразу после, но не знал, как это сделать.Любая помощь будет оценена.Это мой generatorPdf.js:

module.exports={
    pdfGenerator:function(data,pathfile){
        var fonts = {
            Roboto: {
                normal: 'server/pdfgenerator/fonts/Roboto-Regular.ttf',
                bold: 'server/pdfgenerator/fonts/Roboto-Medium.ttf',
                italics: 'server/pdfgenerator/fonts/Roboto-Italic.ttf',
                bolditalics: 'server/pdfgenerator/fonts/Roboto-MediumItalic.ttf'
            }
        };

var datePaiements='';
var dateFinPaiements='';
if(data.abonnement[0].datePaiement!=null)
         datePaiements= new Date( data.abonnement[0].datePaiement.toString());
if(datePaiements!=='')
{
        dateFinPaiements= ('0'+datePaiements.getDate()).slice(-2).toString()+'/'+('0'+(datePaiements.getMonth()+1)).slice(-2).toString()+'/'+(datePaiements.getFullYear()+1).toString();
        datePaiements=('0'+datePaiements.getDate()).slice(-2).toString()+'/'+('0'+(datePaiements.getMonth()+1)).slice(-2).toString()+'/'+datePaiements.getFullYear().toString();
    }


var dateFacture= new Date(data.abonnement[0].timestampCreation.toString());
dateFacture= ('0'+dateFacture.getDate()).slice(-2).toString()+'/'+('0'+(dateFacture.getMonth()+1)).slice(-2).toString()+'/'+dateFacture.getFullYear().toString();

var PdfPrinter = require('pdfmake/src/printer');
var printer = new PdfPrinter(fonts);
var fs = require('fs');

var dd = {
    content: [ ..............],
    footer:{.............}
}

    try{
    var pdfDoc = printer.createPdfKitDocument(dd);
    if (fs.existsSync(pathfile)) {//server/pdfgenerator/documentpdf/basics21.pdf
        fs.unlink(pathfile, (err) => {//server/pdfgenerator/documentpdf/basics21.pdf
            if (err) {
            console.error(err)
            return
            }
        })
    }
    pdfDoc.pipe(fs.createWriteStream(pathfile)).on('finish',function(){//server/pdfgenerator/documentpdf/basics21.pdf
    });

    }
    catch(e){
        console.log(e);
        return null;
        }
}
}

, и это мой удаленный метод в Loopback, чтобы отправить PDF-файл в путь и, где, вероятно, мне нужно загрузить файл:

  cm_abonnements.getAbonnementById= async (options,req,res)=>{
    const token = options && options.accessToken;
    const userId = token && token.userId;
    try{
      if(userId!==null){
        let dataComedien= await app.models.cm_comediens.getComedienByUser(userId);
        let argAbn={};
        const form = new formidable.IncomingForm();
        var formPromise = await new Promise(function(resolve,reject){
          form.parse(req,function(err,fields,files){
            if(err)
            {
              reject(err);
              return-1
            }
            console.log(fields.key)
            argAbn.idAbonnement=fields.key;
            resolve();
          })
        })
        let dataFac=await cm_abonnements.find({where :{and :[{idAbonnement:argAbn.idAbonnement},{idComedien : dataComedien.idComedien}]}});
        var data={abonnement:[]};
        data.abonnement=dataFac;
        var str_date= new Date(dataFac[0].timestampCreation.toString());
        var nameFile= 'Fac_'+dataFac[0].idFacture+'_'+str_date.getFullYear().toString()+'-'+('0'+str_date.getMonth()+1).slice(-2).toString()+'-'+('0'+str_date.getDate()).slice(-2).toString()+'.pdf';
        var path='public/upload/Comediens/'+dataComedien.idComedien.toString()+'/factures/'+nameFile;
        createPdf.pdfGenerator(data,path);

        return dataFac;
      }
      return null;
    }
    catch(e){
      console.log(e);
      return null;
    }

  }
  cm_abonnements.remoteMethod(
    'getAbonnementById',{
      http:{
        verb:'POST'
      },
      description:'Get detail facture by number facture',
      accepts:[
        {arg:"options", "type":"object","http":"optionsFromRequest"},
        { arg: 'req', type: 'object', 'http': {source: 'req'}},
        {arg: 'res', type: 'object', 'http': {source: 'res'}}

      ],
      returns:{arg:'data',root:true}
    }
  );

Любая помощь будет оценена.Спасибо

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

После того, как данные сгенерированы и файл PDF сохранен, для реализации функции «загрузки» осталось 2 шага:

  1. Возвращает HTTP-ответ браузеру с заголовком Content-Type как application/pdf и заголовком Content-Disposition как attachment; filename="yourname.pdf". Обычно это автоматически обрабатывается веб-фреймворком. Я не знаком с loopback, поэтому возьмите Express, например:

    В generatorPdf.js добавьте обратный вызов для прослушивания события finish:

    pdfGenerator:function(data, pathfile, callback){
      ...
      pdfDoc.pipe(fs.createWriteStream(pathfile)).on('finish', callback);
      ...
    }
    

    Если используется функция pdfGenerator, передать параметр функции обратного вызова. Если работа в формате pdf «закончена», верните ответ браузеру, используя res.download() (Это Express API, но я считаю, что loopback имеет такой же API, как и loopback, построенный поверх Express):

    var nameFile=...
    var path=...
    createPdf.pdfGenerator(data, path, function() {
      res.download(path, nameFile);
    });
    
  2. В браузере, если это AJAX-запрос (я полагаю, так как вы упомянули, что это POST-запрос), вам нужно обработать запрос с помощью некоторой операции BLOB-объекта. Вот пример фрагмента с пояснительным комментарием:

    var req = new XMLHttpRequest();
    req.open('POST', '/download', true); // Open an async AJAX request.
    req.setRequestHeader('Content-Type', 'application/json'); // Send JSON data
    req.responseType = 'blob'; // Define the expected data as blob
    req.onreadystatechange = function () {
      if (req.readyState === 4) {
        if (req.status === 200) { // When data is received successfully
          var data = req.response;
          var defaultFilename = 'default.pdf';
          // Or, you can get filename sent from backend through req.getResponseHeader('Content-Disposition')
          if (typeof window.navigator.msSaveBlob === 'function') {
            // If it is IE that support download blob directly.
            window.navigator.msSaveBlob(data, defaultFilename);
          } else {
            var blob = data;
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = defaultFilename;
    
            document.body.appendChild(link);
    
            link.click(); // create an <a> element and simulate the click operation.
          }
        }
      }
    };
    req.send(JSON.stringify({test: 'test'}));
    
0 голосов
/ 09 июля 2019

Вам необходимо отправить следующие HTTP-заголовки:

...