为了实现 HTML 页面打印成 PDF 的功能,在后端使用 Playwright
调用浏览器进行打印,在开发中发现,不论怎么修改 margin
参数,页面始终没有变化。
经过一翻排查,发现是 @page css 规则限制了的原因。
正文
后端通过 python 微服务调用 playwright 打印模块,实现将 html 转换成
pdf,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | async def print_html_to_pdf_bytes(html_content, print_options: dict = {}) -> bytes:     """     将 HTML 内容渲染并返回 PDF 的二进制数据。     pdf_options 常用选项,参考 page.pdf 的参数     注意:page.pdf 仅在 Chromium 可用。     """     async with await allocate_page() as page:         await page.set_content(html_content, wait_until="load")
          try:                          pdf_bytes = await page.pdf(                 **{                     **{                         "format": "A4",                         "print_background": True,                         "display_header_footer": True,                       },                     **print_options,                 }             )         except Exception as e:                          raise RuntimeError(                 "生成 PDF 时出错(注意:page.pdf 仅在 Chromium 中受支持)。原始错误: "                 + str(e)             )         finally:             pass
          return pdf_bytes
  | 
 
其中,print_options 的值为:
1 2 3 4 5 6 7 8
   | {   "margin":{     "top": "20mm",     "right": "10mm",     "bottom": "10mm",     "left": "10mm"   } }
  | 
 
这段代码在打印某个 html 页面时,始终无法修改打印后的边距,在网上搜索
playwright margin 相关的问题,github 上 issues 中显示这个 bug
早已经修复了。
最后,猜测可能是 html 本身有问题,打开 html 文件查看,发现 css
中存在以下内容:
1 2 3 4 5 6 7 8 9
   | @page {       size: A4 portrait;       margin-left: 20mm;       margin-right: 10mm;       margin-top: 10mm;       margin-bottom: 10mm;       -webkit-print-color-adjust: exact;       print-color-adjust: exact;     }
  | 
 
原因终于明了了,@page 规则是一种 CSS
规则,用于修改打印页面的不同方面。它的目标是修改页面的尺寸、方向和页边距。
它的存在,会覆盖浏览器本身的 margin 打印设置,因此一直无法生效。
参考
[BUG]
Controlling margins when making a PDF using Playwright - Margins don't
respect CSS · Issue #3434 · microsoft/playwright
 
@page - CSS:层叠样式表 |
MDN