如何在无头 Chrome 中更改纸张尺寸 --print-to-pdf
Posted
技术标签:
【中文标题】如何在无头 Chrome 中更改纸张尺寸 --print-to-pdf【英文标题】:How can I change paper size in headless Chrome --print-to-pdf 【发布时间】:2017-12-11 17:06:24 【问题描述】:我正在使用无头 Chrome 将 html 文档导出为 pdf
google-chrome --headless --disable-gpu --print-to-pdf='output_path' 'url'
如何更改生成的 pdf 中的纸张大小?
我可以控制 Chrome 参数和 html。
我总是收到美国信函。
没有记录在案的命令行选项。
我尝试设置 CSS:@page size: A4;
。在无头模式下无效,但在正常模式下按 Ctrl+P 时有效(为Save as pdf
选择纸张大小的选项消失,导出的 pdf 具有 A4 页面大小) .
我已在 Ubuntu 16.04 上的 Chrome 版本 59、60 和 61 上尝试过此操作。
【问题讨论】:
我已经检查了 Chromium 源代码。据我了解,也没有未记录的命令行选项。所以目前可能一些 CSS(或其他)黑客是唯一的方法。 【参考方案1】:你可以run headless chrome from Node环境。
然后您就可以将其他参数传递给printToPdf
function,包括pageWidth
和pageHeight
。
【讨论】:
谢谢迪米特里。我知道这个选项,但它会导致其他问题: 1. Chrome 实例只接受一个调试连接。我必须为我的服务的每个实例在多个端口上生成多个实例。不是很酷。 2. 与事件(onLoad 等)同步是额外的复杂层。基本上我需要编写一个运行一个 Chrome 实例的包装程序,该程序将抽象页面加载、打印等。也不那么酷。这就是为什么我想在每个作业中使用单个 Chrome 实例,完成后自动关闭,无需远程调试。更简单【参考方案2】:前段时间创建了一个补丁,可以启用页面大小配置https://codereview.chromium.org/2829973002/
它现在已经关闭并且在不稳定版本的chrome中可用,所以你可以按照你的建议使用它@page size: A4
。
我测试过,它适用于我安装的不稳定版本 (Google Chrome 61.0.3141.7 dev
)。不过,我不确定如何检查它何时在稳定版本中可用...
【讨论】:
那行不通。我已经安装了 Chrome 61.0.3153.4 并在 css 中设置了@page size: A4
。这没什么区别。您是否能够通过这种方式获得不同尺寸的纸张?无论如何,您链接的更改与此问题并没有真正的联系。看这里:codereview.chromium.org/2829973002/patch/1/10010,使用 shell --print-to-pdf
选项时,参数被残酷地硬编码。它与@Dimitry Leonov 的回答更相关,因为它可以让您在使用调试 api 时进行控制。
哦,奇怪,它似乎在我的机器上工作。这是我刚刚用无头镀铬制作的 2 代不同的产品。第一个是@page size: A4;
,第二个是A3
。输出和你看到的imgur.com/QaQQQ8Rimgur.com/CYpMopU不一样。也就是说,红色部分的大小应该是210mm / 297mm
,所以我不确定为什么侧面有额外的边距......
关于我发给你的补丁链接,当我询问无头 chrome bugs.chromium.org/p/chromium/issues/detail?id=603559#c30 的页面大小配置时,Chromium 团队的某个人给我发了这个链接。所以我虽然这也与你有关,但不幸的是我不得不承认我真的无法理解这个补丁中发生了什么:/
你是对的,输出可能不一样。案例是:有 3 种不同的大小:paper
、page
和 body
。您已更改page
的大小,而paper
和body
保持不变。 Chrome 将更大的page
压缩到相同的paper
大小,因此您的body
在视觉上变得更小。它看起来类似于在较大的纸张尺寸上打印,但您可以检查 pdf 属性,您会发现它保持不变(至少在我的情况下)
我不太了解这三种不同的尺寸。您似乎比我对 PDF 了解更多,所以我想我无法帮助您,抱歉:/ BTW 我向您展示的结果与您的预期有何不同?这是否意味着我需要以某种方式查看生成的 PDF 的元数据?【参考方案3】:
注意:在通过 atomrc 的答案中的 cmets 之后,我考虑将其添加为更清晰的答案。
除非使用 devtools 协议,否则您现在无法更改页面大小。
这是a bug in headless Chrome。 @page size
CSS 规则在无头模式下无法正确理解,as this user describes it well on the chromium bug tracker:
Desktop Chrome 确实支持@page at-rules 的大小和边距,并且会根据 size 属性设置工作表尺寸。
Headless Chrome 似乎在某种程度上也解析了@page,但其行为与桌面版本不同:如果您指定@page size,headless 似乎会改变页面框的尺寸(本质上,打印区域),而不是始终保持美国信函大小的工作表。但是,如果您指定 size: Landscape,它会旋转工作表。
【讨论】:
【参考方案4】:现在显然可以“几乎”精确控制页面大小,而无需使用调试界面。
以下是使用 headless chrome 创建其内容尺寸几乎完全相同的 PDF 的方法。
<head>
<style>
html, body
width: fit-content;
height: fit-content;
margin: 0px;
padding: 0px;
</style>
<style id=page_style>
@page size: 100px 100px ; margin : 0px
</style>
</head>
这准备使 pdf 适合页面,但不正确,因为页面大小已设置为 100x100 的任意值。
文档渲染完成后,使用以下方法在页面底部正确设置页面大小:
<script>
window.onload(fixpage);
function fixpage()
renderBlock = document.getElementsByTagName("html")[0];
renderBlockInfo = window.getComputedStyle(renderBlock)
// fix chrome page bug
fixHeight = parseInt(renderBlockInfo.height) + 1 + "px"
pageCss = `@page size: \$renderBlockInfo.width \$fixHeight ; margin:0;`
document.getElementById("page_style").innerHTML = pageCss
</script>
这种方法消除了页眉/页脚,并处理了像素转换为 pdf 的数字问题。
还有一件事
Chrome 目前在使用 CSS 时计算 div 的绝对高度存在错误
line-height: normal;
这会使页面计算过短并导致生成额外的 pdf 页面。您可以使用以下方法解决此问题:
line-height: unset;
贯穿您的 CSS。没有它,您将无法获得准确的高度!
【讨论】:
【参考方案5】:页面大小可以以英寸/毫米为单位设置。我还没有测试过像素大小。这是一组对我有用的 CSS 规则:
@page
margin: 0;
padding: 0;
size: 5in 6.5in;
我的确切情况是渲染 svg-to-pdf,而不是 html;对于 svg,您可能还需要将 width
和 height
属性添加到 <svg>
标签:
<svg ...>
就是这样!输出 PDF 不会有边距,并且会保留所需的大小 - 在我的情况下为 5"x6.5"。
【讨论】:
我只是将样式标签放入我的 HTML 的头部(没有 CData),以 mm 为单位设置大小,它就可以工作了。 是的,对于 HTML 来说确实如此 - 只需在 中添加一个样式标签。我的情况是用于 svg 渲染,所以我需要 CDATA。我应该在回答中更清楚地说明。以上是关于如何在无头 Chrome 中更改纸张尺寸 --print-to-pdf的主要内容,如果未能解决你的问题,请参考以下文章