Next.js API:使用 URL 中的查询参数为 PDF 加水印
Next.js API: Watermark PDF using query parameters in URL
这是我第一次测试 Next.js API,我对整个 Next 也很陌生。js/React 世界请多多包涵。
此 API 路由的目标是触发自动下载带有自定义水印的 PDF,该自定义水印由 API URL 查询参数生成,如下所示:/api/PDFWatermark?id=123&firstname=John&lastname=Doe
为了创建水印,我使用 pdf-lib and I am using a modified version of this 代码为我的 PDF 添加水印。为了生成原始 PDF pdfDoc
的修改和可下载版本,我尝试使用 pdfBytes
after 水印创建一个 blob。创建 blob 后,我想我可以将它添加到附加到 DOM.
的锚点
注释掉blob
和anchor
代码时,出现两个错误:
- ReferenceError: Blob 未定义
- ReferenceError: document is not defined(可能是因为没有DOM附加锚点link)
此时我只能将 pdfBytes
打印为 json,我无法创建和下载实际的水印 PDF 文件。
有没有办法在调用 API 时自动将 pdfBytes
下载为 PDF 文件?
更新
将 modifyPDF
更改为 return 缓冲区后,下面的工作代码:
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
并且:
export default async function handler(req, res) {
const filename = "test.pdf";
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf'); // Displsay
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
res.send(pdfBuffer);
}
正在工作:
import {PDFDocument, rgb, StandardFonts } from 'pdf-lib';
export async function modifyPDF(firstname, lastname, id) {
const order_id = id;
const fullname = firstname + " " + lastname;
const existingPdfBytes = await fetch("https://pdf-lib.js.org/assets/us_constitution.pdf").then((res) => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);
const watermark = fullname + " (OrderID: " + id + ")";
// Set Document Metadata
pdfDoc.setSubject(watermark);
// Get pages
const pages = pdfDoc.getPages();
// Iterate every page, skip first
//pages.slice(1).forEach(page => {
pages.forEach(page => {
// Get the width and height of the page
const {
width,
height
} = page.getSize()
// Watermark the page
page.drawText(watermark, {
x: 70,
y: 8,
size: 10,
font: helveticaFont,
color: rgb(0.95, 0.1, 0.1),
})
})
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
}
export default async function handler(req, res) {
const filename = "test.pdf";
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf'); // Displsay
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
res.send(pdfBuffer);
}
将您的 modifyPDF
更改为 return 缓冲区
[...]
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
[...]
让APIreturnPDF通过处理程序到浏览器:
export default async function handler(req, res) {
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
// Edited as the linked example reports:
// res.type('pdf'); // and might not work
res.send(pdfBuffer);
}
未经测试,但您应该明白要点。
这是我第一次测试 Next.js API,我对整个 Next 也很陌生。js/React 世界请多多包涵。
此 API 路由的目标是触发自动下载带有自定义水印的 PDF,该自定义水印由 API URL 查询参数生成,如下所示:/api/PDFWatermark?id=123&firstname=John&lastname=Doe
为了创建水印,我使用 pdf-lib and I am using a modified version of this 代码为我的 PDF 添加水印。为了生成原始 PDF pdfDoc
的修改和可下载版本,我尝试使用 pdfBytes
after 水印创建一个 blob。创建 blob 后,我想我可以将它添加到附加到 DOM.
注释掉blob
和anchor
代码时,出现两个错误:
- ReferenceError: Blob 未定义
- ReferenceError: document is not defined(可能是因为没有DOM附加锚点link)
此时我只能将 pdfBytes
打印为 json,我无法创建和下载实际的水印 PDF 文件。
有没有办法在调用 API 时自动将 pdfBytes
下载为 PDF 文件?
更新
将 modifyPDF
更改为 return 缓冲区后,下面的工作代码:
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
并且:
export default async function handler(req, res) {
const filename = "test.pdf";
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf'); // Displsay
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
res.send(pdfBuffer);
}
正在工作:
import {PDFDocument, rgb, StandardFonts } from 'pdf-lib';
export async function modifyPDF(firstname, lastname, id) {
const order_id = id;
const fullname = firstname + " " + lastname;
const existingPdfBytes = await fetch("https://pdf-lib.js.org/assets/us_constitution.pdf").then((res) => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);
const watermark = fullname + " (OrderID: " + id + ")";
// Set Document Metadata
pdfDoc.setSubject(watermark);
// Get pages
const pages = pdfDoc.getPages();
// Iterate every page, skip first
//pages.slice(1).forEach(page => {
pages.forEach(page => {
// Get the width and height of the page
const {
width,
height
} = page.getSize()
// Watermark the page
page.drawText(watermark, {
x: 70,
y: 8,
size: 10,
font: helveticaFont,
color: rgb(0.95, 0.1, 0.1),
})
})
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
}
export default async function handler(req, res) {
const filename = "test.pdf";
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf'); // Displsay
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
res.send(pdfBuffer);
}
将您的 modifyPDF
更改为 return 缓冲区
[...]
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes.buffer, 'binary');
[...]
让APIreturnPDF通过处理程序到浏览器:
export default async function handler(req, res) {
const {id, firstname, lastname} = req.query;
const pdfBuffer = await modifyPDF(firstname, lastname, id);
res.status(200);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename='+filename);
// Edited as the linked example reports:
// res.type('pdf'); // and might not work
res.send(pdfBuffer);
}
未经测试,但您应该明白要点。