如何使用浏览器的 (chrome/firefox) HTML/CSS/JS 渲染引擎生成 PDF?

Posted

技术标签:

【中文标题】如何使用浏览器的 (chrome/firefox) HTML/CSS/JS 渲染引擎生成 PDF?【英文标题】:How to use the browser's (chrome/firefox) HTML/CSS/JS rendering engine to produce PDF? 【发布时间】:2014-10-23 19:23:46 【问题描述】:

有一些不错的项目可以从 html/css/js 文件生成 pdf

    http://wkhtmltopdf.org/(开源) https://code.google.com/p/flying-saucer/(开源) http://cssbox.sourceforge.net/(不一定是直接生成pdf) http://phantomjs.org/(开源允许pdf输出) http://www.princexml.com/(商业,但最好的一个) https://thepdfapi.com/ chrome 修改从 html 中吐出 pdf 来自

我想以编程方式控制 chrome 或 firefox 浏览器(因为它们都是跨平台的)以使它们加载网页、运行脚本和设置页面样式并生成用于打印的 pdf 文件。

但是我如何开始以自动方式控制浏览器,以便我可以做类似的事情

render-to-pdf file-to-render.html out.pdf

我可以通过浏览页面然后将其打印为 pdf 轻松地手动完成这项工作,并且我在 pdf 文件上获得了一个准确的、100% 符合规范的呈现 html/css/js 页面。通过浏览器中的配置选项,甚至可以在 pdf 中省略 url 标头。但同样,我该如何开始尝试自动化这个过程呢?

我想在服务器端自动化,打开浏览器,导航到一个页面,并使用浏览器呈现的页面生成 pdf。

我做了很多研究,只是不知道如何提出正确的问题。我想以编程方式控制浏览器,可能就像 selenium 一样,但是我将网页导出为 PDF(因此使用浏览器的渲染功能来生成好的 pdf)

【问题讨论】:

你看过ChromeDriver吗? 您可以结合使用Chromium command line args --kiosk --kiosk-printing 以及在prefs capability 中传递默认的PDF 打印机。我从未尝试过,但这就是我要开始的地方。 我认为你需要做一些真正的研究。恕我直言,浏览器不打算这样做,你有许多你没有想到的障碍需要克服(比如可能运行页眉/页脚、在分页符处保持内容在一起、分页符处不同的表头、字体处理/特殊字符处理和嵌入,了解浏览器尺寸是 96/英寸的像素,而许多其他的东西不是 ...我可以继续,但这对你来说是一个开始。 @ChrisHaas, $ chrome --kiosk --kiosk-printing file.html,在 html 里面我做 window.print();它确实是我想要的,只是它仍然需要我按回车键来保存文件......太伤心了......谢谢 我认为 wkhtmltopdf 最接近你想要的。它是专为 PDF 生成而构建的 WebKit 的分叉版本。或者,如果您喜欢 Prince,docraptor.com 是由 Prince 引擎驱动的商业 saas API。 【参考方案1】:

我不是专家,但 PhamtomJS 似乎是适合这项工作的工具。我不确定它在下面使用什么无头浏览器(我猜它是 chrome/chromium)

var page = require('webpage').create();
page.open('http://github.com/', function() 
     var s = page.evaluate(function() 
         var body = document.body,
             html = document.documentElement;

        var height = Math.max( body.scrollHeight, body.offsetHeight, 
            html.clientHeight, html.scrollHeight, html.offsetHeight );
        var width = Math.max( body.scrollWidth, body.offsetWidth, 
            html.clientWidth, html.scrollWidth, html.offsetWidth );
        return width: width, height: height
    );

    console.log(JSON.stringify(s));

    // so it fit ins a single page
    page.paperSize = 
        width: "1980px",
        height: s.height + "px",
        margin: 
            top: '50px',
            left: '20px'
        
    ;

    page.render('github.pdf');
    phantom.exit();
);

希望对你有帮助。

【讨论】:

CSS 允许在打印时调整页面大小。因此,在代码示例中设置纸张大小没有帮助。此外,css打印中也有分页符。话虽如此,我看到 PhantomJS 使用 webkit 渲染引擎,它没有使用受支持的浏览器,而是 webkit 的一个分支(这对于这个任务来说无论如何都可以)。但是要让它像princexml一样工作还需要做很多工作。我想现在这就是它们不便宜的原因【参考方案2】:

Firefox 有一个 API 方法:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/saveAsPDF

browser.tabs.saveAsPDF()
  .then((status) => 
    console.log('PDF file status: ' + status);
  );

但是,它似乎只适用于Browser Extensions,不能从网页调用。

我仍在为此寻找公共 API...

【讨论】:

以上是关于如何使用浏览器的 (chrome/firefox) HTML/CSS/JS 渲染引擎生成 PDF?的主要内容,如果未能解决你的问题,请参考以下文章

如何在电子应用程序中使用外部浏览器(chrome、firefox 等)实现 auth0 身份验证

如何在我的 Chrome / Firefox 浏览器中查看 SQLite 数据库?

适用于 chrome、firefox 和 safari 浏览器的 Azure 浏览器推送通知

我如何只能在任何现代浏览器(如 chrome、firefox、safari、opera、IE 以及任何版本的通用 javascript [重复])中关闭当前选项卡

程序员如何制作优美的免费PDF简历 30分钟 教你(程序员)使用 "五百丁" 制作简历免费下载为PDF(需要掌握常用chrome,firefox等的调试工具)

强制浏览器在 chrome、firefox 上打印背景图像