使用 Node.js 将 HTML 转换为 PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14552112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:01:36  来源:igfitidea点击:

HTML to PDF with Node.js

node.jsexpresspdf-generation

提问by Michael

I'm looking to create a printable pdfversion of my website webpages. Something like express.render()only render the page as pdf

我希望创建pdf我的网站网页的可打印版本。像express.render()只将页面呈现为pdf

Does anyone know a node module that does that ?

有谁知道这样做的节点模块吗?

If not, how would you go about implementing one ? I've seen some methods talk about using headless browser like phantom.js, but not sure whats the flow.

如果没有,您将如何实施一个?我已经看到一些方法谈论使用无头浏览器phantom.js,但不确定流程是什么。

回答by Jozzhart

Extending upon Mustafa's answer.

扩展穆斯塔法的回答。

A) Install http://phantomjs.org/and then

A) 安装http://phantomjs.org/然后

B) install the phantom node module https://github.com/amir20/phantomjs-node

B) 安装幻影节点模块https://github.com/amir20/phantomjs-node

enter image description here

在此处输入图片说明

C) Here is an example of rendering a pdf

C) 这是一个渲染 pdf 的例子

var phantom = require('phantom');   

phantom.create().then(function(ph) {
    ph.createPage().then(function(page) {
        page.open("http://www.google.com").then(function(status) {
            page.render('google.pdf').then(function() {
                console.log('Page Rendered');
                ph.exit();
            });
        });
    });
});

Output of the PDF:

PDF的输出:

enter image description here

在此处输入图片说明

EDIT:Silent printing that PDF

编辑:无声打印该 PDF

java -jar pdfbox-app-2.0.2.jar PrintPDF -silentPrint C:\print_mypdf.pdf

java -jar pdfbox-app-2.0.2.jar PrintPDF -silentPrint C:\print_mypdf.pdf

回答by Mustafa

Phantom.jsis an headless webkit server and it will load any web page and render it in memory, although you might not be able to see it, there is a Screen Capture feature, in which you can export the current view as PNG, PDF, JPEG and GIF. Have a look at this example from phantom.js documentation

Phantom.js是一个无头 webkit 服务器,它将加载任何网页并将其呈现在内存中,尽管您可能看不到它,但有一个屏幕捕获功能,您可以在其中将当前视图导出为 PNG、PDF 、JPEG 和 GIF。从 phantom.js 文档中查看此示例

回答by Mustafa

If you want to export HTML to PDF. You have many options. without node even

如果要将 HTML 导出为 PDF。你有很多选择。甚至没有节点

Option 1: Have a button on your html page that calls window.print() function. use the browsers native html to pdf. use media queries to make your html page look good on a pdf. and you also have the print before and after events that you can use to make changes to your page before print.

选项 1:在您的 html 页面上有一个调用 window.print() 函数的按钮。使用浏览器原生 html 到 pdf。使用媒体查询使您的 html 页面在 pdf 上看起来不错。并且您还可以在事件之前和之后打印,可用于在打印前更改页面。

Option 2. htmltocanvasor rasterizeHTML. convert your html to canvas , then call toDataURL() on the canvas object to get the image . and use a JavaScript library like jsPDFto add that image to a PDF file. Disadvantage of this approach is that the pdf doesnt become editable. If you want data extracted from PDF, there is different ways for that.

选项 2. htmltocanvasrasterizeHTML。将您的 html 转换为 canvas ,然后在 canvas 对象上调用 toDataURL() 以获取图像。并使用像jsPDF这样的 JavaScript 库将该图像添加到 PDF 文件中。这种方法的缺点是 pdf 不可编辑。如果您想从 PDF 中提取数据,则有不同的方法。

Option 3. @Jozzhard answer

选项 3.@Jozzhard 回答

回答by Thermech

The best solution I found is html-pdf. It's simple and work with big html.

我找到的最佳解决方案是 html-pdf。它很简单,可以使用大 html。

https://www.npmjs.com/package/html-pdf

https://www.npmjs.com/package/html-pdf

Its as simple as that:

就这么简单:

    pdf.create(htm, options).toFile('./pdfname.pdf', function(err, res) {
        if (err) {
          console.log(err);
        }
    });

回答by Chuong Tran

Try to use Puppeteer to create PDF from HTML

尝试使用 Puppeteer 从 HTML 创建 PDF

Example from here https://github.com/chuongtrh/html_to_pdf

这里的示例https://github.com/chuongtrh/html_to_pdf

Or https://github.com/GoogleChrome/puppeteer

https://github.com/GoogleChrome/puppeteer

回答by TetraDev

Create PDF from External URL

从外部 URL 创建 PDF

Here's an adaptation of the previous answers which utilizes html-pdf, but also combines it with requestifyso it works with an external URL:

这是对先前答案的改编,它使用html-pdf,但也将其与 结合使用,requestify因此它可以与外部 URL 一起使用:

Install your dependencies

安装你的依赖

npm i -S html-pdf requestify

Then, create the script:

然后,创建脚本:

//MakePDF.js

var pdf = require('html-pdf');
var requestify = require('requestify');
var externalURL= 'http://www.google.com';

requestify.get(externalURL).then(function (response) {
   // Get the raw HTML response body
   var html = response.body; 
   var config = {format: 'A4'}; // or format: 'letter' - see https://github.com/marcbachmann/node-html-pdf#options

// Create the PDF
   pdf.create(html, config).toFile('pathtooutput/generated.pdf', function (err, res) {
      if (err) return console.log(err);
      console.log(res); // { filename: '/pathtooutput/generated.pdf' }
   });
});

Then you just run from the command line:

然后你只需从命令行运行:

node MakePDF.js

Watch your beautify pixel perfect PDF be created for you (for free!)

观看为您创建的美化像素完美 PDF(免费!)

回答by Alexander

Package

包裹

I used html-pdf

我使用了html-pdf

Easy to use and allows not only to save pdf as file, but also pipe pdf content to a WriteStream (so I could stream it directly to Google Storage to save there my reports).

易于使用,不仅允许将 pdf 保存为文件,还允许将 pdf 内容通过管道传输到 WriteStream(因此我可以将其直接流式传输到 Google Storage 以保存我的报告)。

Using css + images

使用 css + 图片

It takes css into account. The only problem I faced - it ignored my images. The solution I found was to replace url in srcattrribute value by base64, e.g.

它考虑了css。我面临的唯一问题 - 它忽略了我的图像。我找到的解决方案是src用base64替换属性值中的url ,例如

<img src="data:image/png;base64,iVBOR...kSuQmCC">

<img src="data:image/png;base64,iVBOR...kSuQmCC">

You can do it with your code or to use one of online converters, e.g. https://www.base64-image.de/

您可以使用您的代码或使用在线转换器之一来完成,例如https://www.base64-image.de/

Compile valid html code from html fragment + css

从 html 片段 + css 编译有效的 html 代码

  1. I had to get a fragment of my htmldocument (I just appiled .html() method on jQuery selector).
  2. Then I've read the content of the relevant cssfile.
  1. 我必须得到我的html文档的一个片段(我只是在 jQuery 选择器上应用了 .html() 方法)。
  2. 然后我阅读了相关css文件的内容。

Using this two values (stored in variables htmland cssaccordingly) I've compiled a valid html code using Template string

使用这两个值(存储在变量中htmlcss相应地)我已经使用模板字符串编译了一个有效的 html 代码

var htmlContent = `
<!DOCTYPE html>
<html>
  <head>
    <style>
      ${css}
    </style>
  </head>
  <body id=direct-sellers-bill>
    ${html}
  </body>
</html>`

and passed it to createmethod of html-pdf.

并将其传递给html-pdf 的create方法。

回答by Cyril N.

For those who don't want to install PhantomJS along with an instance of Chrome/Firefox on their server - or because the PhantomJS project is currentlysuspended, here's an alternative.

对于那些不想在他们的服务器上安装 PhantomJS 和 Chrome/Firefox 实例的人 - 或者因为PhantomJS 项目目前已暂停,这里有一个替代方案。

You can externalize the conversions to APIs to do the job. Many exists and varies but what you'll get is a reliable service with up-to-date features (I'm thinking CSS3, Web fonts, SVG, Canvas compatible).

您可以将转换外部化为 API 来完成这项工作。许多存在且各不相同,但您将获得具有最新功能的可靠服务(我认为 CSS3、Web 字体、SVG、Canvas 兼容)。

For instance, with PDFShift(disclaimer, I'm the founder), you can do this simply by using the requestpackage:

例如,使用PDFShift(免责声明,我是创始人),您只需使用以下request软件包即可完成此操作:

const request = require('request')
request.post(
    'https://api.pdfshift.io/v2/convert/',
    {
        'auth': {'user': 'your_api_key'},
        'json': {'source': 'https://www.google.com'},
        'encoding': null
    },
    (error, response, body) => {
        if (response === undefined) {
            return reject({'message': 'Invalid response from the server.', 'code': 0, 'response': response})
        }
        if (response.statusCode == 200) {
            // Do what you want with `body`, that contains the binary PDF
            // Like returning it to the client - or saving it as a file locally or on AWS S3
            return True
        }

        // Handle any errors that might have occured
    }
);

回答by Krishan

Use html-pdf

使用html-pdf

var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };

pdf.create(html, options).toFile('./businesscard.pdf', function(err, res) {
  if (err) return console.log(err);
  console.log(res); // { filename: '/app/businesscard.pdf' } 
});

回答by Todderz

In case you arrive here looking for a way to make PDF from view templates in Express, a colleague and I made express-template-to-pdf

如果您来到这里寻找一种从 Express 中的视图模板制作 PDF 的方法,我和一位同事制作了express-template-to-pdf

which allows you to generate PDF from whatever templates you're using in Express - Pug, Nunjucks, whatever.

它允许您从您在 Express 中使用的任何模板生成 PDF - Pug、Nunjucks 等等。

It depends on html-pdf and is written to use in your routes just like you use res.render:

它取决于 html-pdf 并且被编写为在您的路线中使用,就像您使用 res.render 一样:

const pdfRenderer = require('@ministryofjustice/express-template-to-pdf')

app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')

app.use(pdfRenderer())

If you've used res.render then using it should look obvious:

如果你使用过 res.render 那么使用它应该很明显:

app.use('/pdf', (req, res) => {
    res.renderPDF('helloWorld', { message: 'Hello World!' });
})

You can pass options through to html-pdf to control the PDF document page size etc

您可以将选项传递给 html-pdf 以控制 PDF 文档页面大小等

Merely building on the excellent work of others.

仅仅建立在他人的出色工作上。