我正在尝试从我的网站页面生成pdf。
为此,我有一个运行Puppeteer的快递服务器,它做一些事情:
-当用户查看页面时,采用浏览器的宽度。
-调整Chrome无头浏览器的大小。
-计算页面的高度。
-将宽度/高度信息作为参数传递到page.pdf({})
。
我网站的某些页面在一页上呈现得很好。但是其他的确在两页上渲染,好像某些元素将内容的高度推到高于Puppeteer上javascript中计算的高度一样。
如果确实有帮助,我想我可以在代码await page.emulateMedia('screen');
的开头使用此代码段遮住我的后背。
我检查了两个假设: -使用调试控制台,我可以在调整页面大小时获得文档的实际高度。 -我检查了此信息是否已正确传递给Puppeteer。 -通过将其转换为像素,我检查了以英寸为单位的高度是否正确。
这三个假设是正确的。
这是我的木偶代码:
const page = await browser.newPage();
await page.emulateMedia('screen');
// Resize window to the width it had when the client has seen it.
async function resizeWindow(width, height) {
await page.setViewport({height, width});
// Window frame - probably OS and WM dependent.
height += 85;
// Any tab.
const {targetInfos: [{targetId}]} = await browser._connection.send(
'Target.getTargets'
);
// Tab window.
const {windowId} = await browser._connection.send(
'Browser.getWindowForTarget',
{targetId}
);
// Resize.
await browser._connection.send('Browser.setWindowBounds', {
bounds: {height, width},
windowId
});
}
resizeWindow(parseInt(req.body.evidenceWidth), 0); // Use 0 as a default height because it is required, but not relevant.
// Wait for page width to be actually changed
await page.mainFrame().waitForFunction(`window.innerWidth === ${parseInt(req.body.evidenceWidth)}`);
// Go to the page and wait for all the connection on the page to be resolved
await page.goto(`${req.body.url}`, {waitUntil: 'networkidle0'});
// Calculate real page height
const realPageHeight = await page.evaluate(() => {
const body = document.body,
html = document.documentElement;
const pageHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
return pageHeight;
});
// Convert size from pixel to inches to avoid rounding issues caused by Puppeteer
const convertPixelToInches = (value) => {
let inches = Math.ceil(value/ 96 * 1000) / 1000;
return `${parseFloat(inches).toFixed(3)}in`; // Calculate inches value and round it up.
}
const pageWidth = convertPixelToInches(req.body.evidenceWidth);
const pageHeight = convertPixelToInches(realPageHeight < req.body.evidenceHeight ? req.body.evidenceHeight : realPageHeight);
// Send the response
switch(req.body.format) {
case 'html':
const html = await page.content();
await fs.writeFile(join(__dirname, HTML_EVIDENCE_FD, `${uuid}.html`), html, (err) => {
if (err) {
console.error(`Evidence html could not be generated`, err);
} else {
res.status(200).sendFile(join(__dirname, HTML_EVIDENCE_FD, `${uuid}.html`));
}
});
break;
case 'pdf':
await page.pdf({
path: join(__dirname, PDF_EVIDENCE_FD, `${uuid}.pdf`),
height: pageHeight,
width: pageWidth,
printBackground: true,
});
res.status(200).sendFile(join(__dirname, PDF_EVIDENCE_FD, `${uuid}.pdf`));
break;
default:
res.status(501).send({ error: 'The format you chose is not supported'});
break;
}
await page.close();
await browser.close();
});
app.on("listening", function() {
console.log("Listening on port %d", app.port);
});
return app;
还!我注意到另一个问题,比如说我有一个750px的断点,并且我将800px传递给了Puppeteer,我希望这个断点不会在我的pdf文件中出现。但是在pdf中完成的呈现就像页面宽度在断点以下一样。在pdf生成期间是否添加了一些不可见的边距?
答案 0 :(得分:2)
因此,经过几天的搜索,我发现了问题所在: