我正在开发一个小项目,用于在node和express中生成pdf,我正在使用pdfkit npm模块但生成pdf。我也使用qr-image npm模块生成QR码图像,但我很难将生成的QR码附加到pdf上。这是我用来生成QR码的代码:
var file = "./"+certificationnumber+".png";
var qr_svg = qr.image(file, { type: 'png' });
qr_svg.pipe(require('fs').createWriteStream(file));
这就是我正在尝试使用pdfkit npm模块将其附加到pdf:
doc.image(qr_svg.pipe(require('fs').createWriteStream(file)))
因为每个pdf都有一个唯一的QR码。
提前致谢
答案 0 :(得分:2)
我完全有同样的问题,以64位编码形式获取PDF,我必须将qr图像附加到它。
以下是代码段。
PDFDocument = require('pdfkit');
var base64 = require('base64-stream'); var doc = new PDFDocument();
doc.image('test.jpeg', {
fit: [250, 300],
align: 'center',
valign: 'center'
});
var finalString = pdf.response;
// contains the base64 string
//logic to append the qr image.
var stream = doc.pipe(base64.encode());
stream.on('data', function(chunk) {
finalString += chunk;
});
stream.on('end', function() {
// the stream is at its end, so push the resulting base64 string to the response
var backToPDF = new Buffer(finalString, 'base64');
read.writeFileSync('./Report.pdf', backToPDF);
});
doc.end();
答案 1 :(得分:0)
我有同样的问题。
似乎是一个异步问题。
如果您将QR代码的生成视为承诺,然后运行创建的pdf代码,则它会起作用。
我的代码在下面(使用promise)。它也应该使用async await
const createPDF = (ticketID) => {
const doc = new pdf
doc.pipe(fs.createWriteStream(`${ticketID}.pdf`))
doc.text('Your Tickets').fontSize(25)
doc.image(`./qrCodes/${ticketID}.png`, {
fit: [250, 300],
align: 'center',
valign: 'center'
});
doc.end()
}
const createQRCode = (ticketID) => {
QR.toFile(`./qrCodes/${ticketID}.png`, String(ticket), {width: 250}).then(qr => {
createPDF(ticketID)
})
}
答案 2 :(得分:0)
这是我想出的解决方案。使用 pdf-lib、express 和 qrcode
const fs = require("fs");
const path = require("path");
const express = require("express");
const http = require("http");
const cors = require("cors");
const multer = require("multer");
const app = express();
const server = http.createServer(app);
const { PDFDocument } = require("pdf-lib");
const QRCode = require("qrcode");
const Joi = require("joi");
const { readFile, writeFile, unlink } = require("fs/promises");
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const dir = "public";
const subDirectory = "public/uploads";
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
fs.mkdirSync(subDirectory);
}
const generateQRCodeImage = async function (filePath, text, color) {
return new Promise((resolve, reject) => {
QRCode.toFile(
filePath,
text,
{
color,
},
function (err) {
if (err) return reject(err);
resolve();
}
);
});
};
const run = async ({
width,
height,
x,
y,
pathToImage,
pathToPDF,
pathToOutputPDF,
qrCodeText,
qrDarkColor = "#000",
qrLightColor = "#0000",
}) => {
await generateQRCodeImage(pathToImage, qrCodeText, {
dark: qrDarkColor,
light: qrLightColor,
});
const pdfDoc = await PDFDocument.load(await readFile(pathToPDF));
const img = await pdfDoc.embedPng(await readFile(pathToImage));
Array.from({ length: pdfDoc.getPageCount() }).forEach((_, index) => {
let imagePage = pdfDoc.getPage(index);
imagePage.drawImage(img, {
x,
y,
width,
height,
});
});
const pdfBytes = await pdfDoc.save();
await writeFile(pathToOutputPDF, pdfBytes);
};
const pdfFileFilter = function (req, file, callback) {
const ext = path.extname(file.originalname);
if (ext !== ".pdf") {
return callback("This extension is not supported");
}
callback(null, true);
};
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/uploads");
},
filename: function (req, file, cb) {
cb(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
});
const filesToProcess = multer({ storage: storage, fileFilter: pdfFileFilter });
const schema = Joi.object({
width: Joi.string().regex(/^\d+$/).required(),
height: Joi.string().regex(/^\d+$/).required(),
x: Joi.string().regex(/^\d+$/).required(),
y: Joi.string().regex(/^\d+$/).required(),
qrCodeData: Joi.string().required(),
qrDarkColor: Joi.string(),
qrLightColor: Joi.string(),
});
app.post("/addQrToPdf", filesToProcess.array("file", 1), async (req, res) => {
const pathToImage = "public/uploads/" + Date.now() + "temp-qr.png";
const pathToOutputPDF = "public/uploads/" + Date.now() + "-output.pdf";
if (req.files) {
const [file] = req.files;
if (!file) {
res.send("No file detected on input");
}
const pathToPDF = file.path;
try {
const { width, height, x, y, qrCodeData, qrDarkColor, qrLightColor } =
await schema.validateAsync(req.body);
await run({
width: +width,
height: +height,
x: +x,
y: +y,
qrDarkColor,
qrLightColor,
qrCodeText: qrCodeData,
pathToImage,
pathToOutputPDF,
pathToPDF,
});
const pdfFile = await readFile(pathToOutputPDF);
res.contentType("application/pdf");
res.send(pdfFile);
await unlink(pathToImage);
await unlink(pathToPDF);
await unlink(pathToOutputPDF);
} catch (error) {
try {
await unlink(pathToPDF);
await unlink(pathToImage);
} catch (err) {
console.warn(err);
}
res.send(error);
}
}
});
server.listen(4000, () => console.log("listening on port *:4000"));