node.js - 使用 Puppeteer 打印除最后一页之外的所有 pdf 页
问题描述
我需要为最后一个 pdf 页面生成不同的页脚。经过调查,我意识到最好的方法是生成两个不同的 pdf 并将它们组合起来。当我需要为第一页更改页脚或使用不同的模板时,或者当我知道哪些页面应该看起来不同(使用pageRanges
选项)但我找不到仅获取最后(最后 n)页的方法时,它工作正常如果总页码未知。有什么想法可以只为最后(最后 n)页生成 pdf 吗?
任何答案将不胜感激。
我正在使用 Puppeteer v 2.1.0 和 node.js v 8.16.0
这是我现在用来生成 pdf 文件的脚本。
const puppeteer = require('puppeteer');
const fs = require('fs');
const DEFAULT_HEADER = '<span></span>';
const DEFAULT_FOOTER_HEIGHT = 90;
const DEFAULT_PAGE_PADDING = 36;
const createPdf = async () => {
let browser;
try {
browser = await puppeteer.launch();
const page = await browser.newPage();
const [, , bodyFilePath, outputFilePath, footerFilePath] = process.argv;
await page.goto(`file:${bodyFilePath}`, { waitUntil: 'networkidle0' });
let footerTemplate = DEFAULT_HEADER;
if (footerFilePath) {
footerTemplate = fs.readFileSync(footerFilePath, 'utf8');
}
await page.pdf({
path: outputFilePath,
format: 'A4',
margin: {
top: DEFAULT_PAGE_PADDING,
right: DEFAULT_PAGE_PADDING,
bottom: DEFAULT_FOOTER_HEIGHT,
left: DEFAULT_PAGE_PADDING,
},
printBackground: true,
displayHeaderFooter: true,
headerTemplate: DEFAULT_HEADER,
footerTemplate,
});
} catch (err) {
console.log(err.message);
} finally {
if (browser) {
browser.close();
}
process.exit();
}
};
createPdf();
我正在转换为 pdf 的模板是.html.erb
文件
解决方案
也许有更好的方法来解决这个问题,但此时我已经使用了这种方法 - 我正在使用与上面相同的脚本生成导出,而不是使用另一个脚本来打开以前的 pdf 文件,计算页数并生成两个新文件(我将它们合并到后端的一个文件中) - 除了最后一个之外的所有页面,并且只有最后一页具有不同的页脚。
const puppeteer = require('puppeteer');
const fs = require('fs');
const pdf = require('pdf-parse');
const DEFAULT_HEADER = '<span></span>';
const DEFAULT_FOOTER_HEIGHT = 90;
const DEFAULT_PAGE_PADDING = 36;
const createPdf = async () => {
let browser;
try {
browser = await puppeteer.launch();
const page = await browser.newPage();
const [
,
,
bodyFilePath,
outputFilePath,
footerFilePath,
lastPagePath,
lastPageFooterPath,
] = process.argv;
await page.goto(`file:${bodyFilePath}`, { waitUntil: 'networkidle0' });
let footerTemplate = DEFAULT_HEADER;
let lastPageFooterTemplate = DEFAULT_HEADER;
if (footerFilePath) {
footerTemplate = fs.readFileSync(footerFilePath, 'utf8');
}
if (lastPageFooterPath) {
lastPageFooterTemplate = fs.readFileSync(lastPageFooterPath, 'utf8');
}
const dataBuffer = fs.readFileSync(outputFilePath);
const pdfInfo = await pdf(dataBuffer);
const numPages = pdfInfo.numpages;
const baseOptions = {
path: outputFilePath,
format: 'A4',
margin: {
top: DEFAULT_PAGE_PADDING,
right: DEFAULT_PAGE_PADDING,
bottom: DEFAULT_FOOTER_HEIGHT,
left: DEFAULT_PAGE_PADDING,
},
printBackground: true,
displayHeaderFooter: true,
headerTemplate: DEFAULT_HEADER,
pageRanges: `${numPages}`,
footerTemplate: lastPageFooterTemplate,
};
if (numPages === 1) {
await page.pdf(baseOptions);
} else {
await page.pdf({
...baseOptions,
footerTemplate,
pageRanges: `-${numPages - 1}`,
});
await page.pdf({
...baseOptions,
path: lastPagePath,
footerTemplate: lastPageFooterTemplate,
});
}
} catch (err) {
console.log(err.message);
} finally {
if (browser) {
browser.close();
}
process.exit();
}
};
createPdf();
希望这对有同样问题的人有所帮助。
推荐阅读
- java - JavaFX 中的多个 setOnAction 清理并在 5 个问题后停止应用程序
- android - Android:如何将自定义布局设置为透明
- bash - 根据文件名将文件移动到相应的文件夹
- java - 从查询中我会得到 2 行,但是在返回地图时我没有得到 2 行,我只得到最后一行
- mysql - mysql查询返回不正确的值
- python - Django 使用 datetime.date() 作为 DateField 的输入来实现过去的日期输入
- html - HTML5 日期时间本地选择器 日期和时间格式到另一个字段
- javascript - 如何永久更改烧瓶网页中单击按钮的外观?
- swap - 如何在 Clojure 中的映射嵌套向量中更新试剂原子过滤
- tensorflow - TensorFlow 数据集如何处理无法装入服务器内存的大数据?