我正在尝试创建一些图像的pdf(以datauri格式)是nodejs并将pdf存储在我的S3中。该函数的返回预期提供文件的 s3 URL。
我在这里使用解析服务器作为服务器和节点画布来创建图像的画布,然后使用 PDFKit 从画布元素创建 pdf。(jsPdf 没有成功)。现在我希望使用 AWS-SDK 将此 pdf 发送到我的 s3 并最终返回文件的 URL。下面是我的代码,直到画布生成。我不知道是否首先创建了 pdf,即使在发送到 s3 之前也是如此。哦!整个事情都在heroku上运行。
Parse.Cloud.define('getBulkMeta',async (req)=>{
const PDFDocument = require('pdfkit'),
{Canvas,loadImage} = require('canvas');
try {
let baseImg = await loadImage('data:image/png;base64,'+req.params.labels[0]);
let labels = req.params.labels,
allCanvas = [],
rowH = baseImg.naturalHeight,
rowW = baseImg.naturalWidth,
perpage = req.params.size[1],
pages = Math.ceil(labels.length/perpage),
imgInd = 0,
g = 10;
size = req.params.size[0];
for(var p=0;p<pages;p++){
let canvas = new Canvas(rowW*((size=='A4')?2:1),rowH*((size=='A4')?2:1)),
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height)
ctx.fillStyle = "#fff";
ctx.fill();
if(perpage == 1){
let img = await loadImage('data:image/png;base64,'+labels[imgInd++]);
ctx.drawImage(img,g,g,rowW-(2*g),rowH-(2*g));
} else {
var thisImgInd = 0;
for (var r=0;r<2;r++){
for(var c=0;c<2;c++){
let img = await loadImage('data:image/png;base64,'+labels[imgInd++]);
ctx.drawImage(img,g+(c*(rowW-g/2)),g+(r*(rowH-g/2)),rowW-(1.5*g),rowH-(1.5*g));
thisImgInd++
if(thisImgInd>=perpage||imgInd>=labels.length){break;}
}
if(thisImgInd>=perpage||imgInd>=labels.length){break;}
}
}
allCanvas.push(canvas)
}
var thisPDF = new PDFDocument({layout: 'landscape',size:size});
var bcoded;
thisPDF.pipe(()=>{bcoded = new Buffer.from(thisPDF).toString('base64')});
allCanvas.forEach((c,i)=>{
if(i){thisPDF.addPage();}
thisPDF.image(c.toDataURL(),0,0,thisPDF.page.width,thisPDF.page.width);
})
thisPDF.end();
const S3_BUCKET = process.env.S3_BUCKET;
aws.config.region = process.env.AWS_REGION;
aws.config.signatureVersion = 'v4';
let s3 = new aws.S3();
let fileName = req.params.name;
let s3Params = {
Bucket: S3_BUCKET,
Body: bcoded,
Key: fileName,
ContentType : 'application/pdf',
ACL: 'public-read'
};
s3.putObject(s3Params, (err, data) => {
if(err){
console.log('\n\n\n\n\n\n\n'+err+'\n\n\n\n\n\n\n');
throw 'Error: '+ (err);
}
let returnData = {
signedRequest: data,
url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`
};
return (returnData);
})
} catch (e) {throw e;}
})
更新。我已经使用以下代码将pdf文件保存在s3中:
Parse.Cloud.define('getBulkMeta',async (req)=>{
const PDFDocument = require('pdfkit'),
{Canvas,loadImage} = require('canvas');
try {
let baseImg = await loadImage('data:image/png;base64,'+req.params.labels[0]);
let labels = req.params.labels,
allCanvas = [],
rowH = baseImg.naturalHeight,
rowW = baseImg.naturalWidth,
perpage = req.params.size[1],
pages = Math.ceil(labels.length/perpage),
imgInd = 0,
g = 10;
size = req.params.size[0];
for(var p=0;p<pages;p++){
let canvas = new Canvas(),
ctx = canvas.getContext("2d");
canvas.height = rowH*((size=='A4')?2:1);
canvas.width = rowW*((size=='A4')?2:1);
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height)
ctx.fillStyle = "#fff";
ctx.fill();
if(perpage == 1){
let img = await loadImage('data:image/png;base64,'+labels[imgInd++]);
ctx.drawImage(img,g,g,rowW-(2*g),rowH-(2*g));
} else {
var thisImgInd = 0;
for (var r=0;r<2;r++){
for(var c=0;c<2;c++){
let img = await loadImage('data:image/png;base64,'+labels[imgInd++]);
ctx.drawImage(img,g+(c*(rowW-g/2)),g+(r*(rowH-g/2)),rowW-(1.5*g),rowH-(1.5*g));
thisImgInd++
if(thisImgInd>=perpage||imgInd>=labels.length){break;}
}
if(thisImgInd>=perpage||imgInd>=labels.length){break;}
}
}
allCanvas.push(canvas)
}
var thisPDF = new PDFDocument({layout: 'landscape',size:size});
let buffers = [],pdfData,returnData='Hi';
thisPDF.on('data', buffers.push.bind(buffers));
thisPDF.on('end',() => {
pdfData = Buffer.concat(buffers);
const S3_BUCKET = process.env.S3_BUCKET;
aws.config.region = process.env.AWS_REGION;
aws.config.signatureVersion = 'v4';
let s3 = new aws.S3();
let fileName = req.params.name;
let s3Params = {
Bucket: S3_BUCKET,
Body: pdfData,
Key: (+new Date())+'-'+fileName,
ContentType : 'application/pdf',
ACL: 'public-read'
};
s3.putObject(s3Params,(err, data) => {
delete pdfData,thisPDF;
pdfData = null;thisPDF = null;
if(err){ throw 'Error: '+ (err); }
returnData = { signedRequest: data, url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}` };
})
})
allCanvas.forEach((c,i)=>{
if(i){thisPDF.addPage();}
thisPDF.image(c.toDataURL(),0,0,{fit:[thisPDF.page.width,thisPDF.page.height]});
})
thisPDF.end();
return returnData;
} catch (e) {throw e;}
})
然而,returnData
总是给出“Hi”作为输出,而且函数似乎没有关闭——Heroku 每次都会抛出内存超出错误。