首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Nodejs、pdfKit和qr-image

Nodejs、pdfKit和qr-image
EN

Stack Overflow用户
提问于 2018-02-14 16:21:49
回答 4查看 2.9K关注 0票数 1

我正在做一个在node和express中生成pdf的小项目,l正在使用pdfkit npm模块,但要生成pdf。L还使用了qr-image npm模块来生成二维码图像,但是l正在努力将生成的二维码附加到pdf上。这是l用来生成二维码的代码:

代码语言:javascript
运行
复制
var file = "./"+certificationnumber+".png";
var qr_svg = qr.image(file, { type: 'png' });
qr_svg.pipe(require('fs').createWriteStream(file));

这就是l尝试使用pdfkit npm模块将其附加到pdf的方法:

代码语言:javascript
运行
复制
doc.image(qr_svg.pipe(require('fs').createWriteStream(file)))

因为每个pdf都有一个唯一的二维码。

提前感谢

EN

回答 4

Stack Overflow用户

发布于 2018-03-07 17:24:59

我完全有同样的问题,在64位编码形式的PDF,我必须附加qr图像到它。

下面是代码片段。

代码语言:javascript
运行
复制
PDFDocument = require('pdfkit');
const base64 = require('base64-stream');
const doc = new PDFDocument();

doc.image('test.jpeg', {
  fit: [250, 300],
  align: 'center',
  valign: 'center'
});

const finalString = pdf.response;

// contains the base64 string
//logic to append the qr image.

const stream = doc.pipe(base64.encode());
stream.on('data', chunk => finalString += chunk);

stream.on('end', () => {
  // the stream is at its end, so push the resulting base64 string to the response
  const backToPDF  = new Buffer(finalString, 'base64');
  read.writeFileSync('./Report.pdf', backToPDF);
});

doc.end();
票数 3
EN

Stack Overflow用户

发布于 2021-07-20 04:32:33

这是我想出的解决方案。使用pdf-lib、express和qrcode

代码语言:javascript
运行
复制
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"));
票数 1
EN

Stack Overflow用户

发布于 2020-06-20 02:48:30

我也有同样的问题。

看起来这是一个异步问题。

如果您将二维码的生成视为一个承诺,然后运行create pdf code,它就会起作用。

我的代码如下(使用promise)。它也应该使用async await工作

代码语言:javascript
运行
复制
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)
    })


}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48782583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档