[英]download a PDF with Javascript/Node.Js after generating data and storing the file into a path
我为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}
}
);
任何帮助,将不胜感激。 谢谢
您需要发送以下HTTP标头:
Content-Type
: application/pdf
Content-Disposition
: inline; filename="download.pdf"
inline; filename="download.pdf"
生成数据并存储pdf文件后,尚需执行2个步骤来实现“下载”功能:
将HTTP响应返回给浏览器,其中Content-Type
标头为application/pdf
, Content-Disposition
标头为attachment; filename="yourname.pdf"
attachment; filename="yourname.pdf"
。 通常,这将由Web框架自动处理。 我对环回不熟悉,因此以Express为例:
在generatorPdf.js
,添加一个回调以侦听finish
事件:
pdfGenerator:function(data, pathfile, callback){ ... pdfDoc.pipe(fs.createWriteStream(pathfile)).on('finish', callback); ... }
使用pdfGenerator
函数时,传递一个回调函数参数。 如果pdf工作已“完成”,请使用res.download()
将响应返回到浏览器(这是Express API,但我相信回送具有类似的API,因为回送基于Express之上):
var nameFile=... var path=... createPdf.pdfGenerator(data, path, function() { res.download(path, nameFile); });
在浏览器端,如果它是一个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'}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.