background

The project team has a function similar to a rich text editor, which needs to support printing in Internet Explorer. To solve the problem of printing compatibility, you need a service that outputs PDFS based on Html.

Server expired, see the effect, you can directly clone to the local run up to see alexwjj/html-to-PDF 😎😎😎

research

HTML to PDF scheme has many, how to choose also see your specific situation

1. Built-in Chrome browser

Disadvantages:

  • The user has to click on it
  • Users need to use a supported browser such as Chrome
  • Print is global by default

Advertising: For partial printing, see my plugin 😝😝😝: vue-iframe-print

NPM install vue-iframe-print Add v-print to the DOM that needs to be printed

Html2canvas + jsPdf

Javascript to convert HTML to PDF, download, support for multiple pages oh (HTML2Canvas and jsPDF)

Disadvantages:

  • The HTML2Canvas plugin is incompatible with IE
  • Clarity problem
  • Paging problem
  • Text picture truncation problem

3. Node server conversion

  • Wkthtmltopdf pit more
  • Phantomjs is a headless browser based on WebKit, which is not used much in the community. It has not been updated for a long time, so you can learn more about it
  • The Puppeteer + Headless Chrome community is also using this solution

Choose Egg + Puppeteer πŸ˜‰πŸ˜‰πŸ˜‰

If you want to build from scratch yourself, check out Puppeteer to generate PDF and absolutely address your needs

Deployment (knock on the blackboard) ❗❗❗

When you have completed the basic functions, you happily think that only the last step is left, then the pit comes ~

1. Use Puppeteer in Docker

The official documentation notes that “using Headless Chrome in Docker and getting it up and running can be tricky”. The official documentation has a troubleshooter section where you can find all the necessary information about installing Puppeteer with Docker.

If you’re installing Puppeteer on Alpine image, be sure to scroll down a bit more when you see this part of the page. Otherwise you may miss the fact that you cannot run the latest Puppeteer version, and you also need to disable SHM with a tag

const browser = await puppeteer.launch({
 headless: true,
 args: ['--disable-dev-shm-usage']
});
Copy the code

Otherwise, the Puppeteer child process may run out of memory before it starts properly.

2. Deploy it in the centOS

Step 1: Install Chrome

Since the Puppeteer package is used directly and depends on the Chrome kernel, you will always be stuck in the node install.js when you start the project NPM install. Due to the network problems in China and the large size of Chrome, it is difficult for you to directly deploy the Puppeteer package on the server successfully.

Puppeteer supports local Chrome installation links, so you can specify them manually

NPM install puppeteer –ignore-scripts

Chrome installation details can be referred to: Ali Cloud Server (centos7) use (7) a Puppeteer export PDF deployment and use

Crater infested, warning~

const browser = await puppeteer.launch({ args: ['--disable-dev-shm-usage', '--no-sandbox'], headless:true, / / Linux chrome executablePath default installation path: '/ opt/Google/chrome/chrome'});Copy the code

The executablePath for puppeteer is the same as that for Chrome on Linux. If you want to install puppeteer on your Linux OS, you can do the same thing on your Linux OS

Carlo: a new Electron?

'use strict'; const puppeteer = require('puppeteer'); const findChrome = require('.. /.. /node_modules/carlo/lib/find_chrome'); let browser = null; module.exports = async () => { if (! browser) { const findChromePath = await findChrome({}); // browser = await puppeteer.launch(); Browser = await puppeteer.launch({headless: true, // Chrome's default installation path is executablePath: findChromePath.executablePath, args: [ '--disable-gpu', '--disable-dev-shm-usage', '--disable-setuid-sandbox', '--no-first-run', '--no-sandbox', '--no-zygote', '--single-process', ], }); } return browser; };Copy the code

Step 2: Deploy the script

Although egg has its own process management, pm2 is recommended here, in the project root directory

A new deploy. Sh

Type node NPM install puppeteer --ignore-scripts NPM install pm2 Spawning PM2 daemon with pm2_home sleep 2 pm2 start pm2.config.jsonCopy the code

New pm2. Config. Json

{
  "apps": [
    {
      "name": "html-to-pdf",
      "script": "npm",
      "args": "run start",
      "log_date_format": "YYYY-MM-DD HH:mm:ss",
      "exec_mode": "fork",
      "max_memory_restart": "500M"
    }
  ]
}
Copy the code

All set, go!!

Run the sh deploy.sh command in the server project and pm2 is successfully started

At this time, the service is no problem, but other problems, because the server is not Chinese font library ~, so the generated PDF, Chinese fonts are all garbled

Step 3: Install fonts

Install fontconfig yum -y install fontconfig after this command is executed, you can see fontconfig and fontconfig in /usr/share folder

  • From the window of theC:\Windows\FontsMake a copy of the font inside, or just select what you need
  • The CentOS/usr/share/fontsCreate a new folder called Chinese
  • Then put the font that you just copied into CentOS/usr/share/fonts/chineseinside
  • Change the permission of the Chinese directory.chmod -R 775 /usr/share/fonts/chinese
  • Next you need to installttmkfdirTo search for all font information in the directory and summarize it to generate a fonts.scale file, enter the commandyum -y install ttmkfdir
  • Run the ttmkfdir command.ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
  • Open the font profile,vi /etc/fonts/fonts.conf, and add the following paragraph
<! -- Font directory list --> <dir>/usr/share/fonts</dir> <dir>/usr/share/X11/fonts/Type1</dir> <dir>/usr/share/X11/fonts/TTF</dir> <dir>/usr/local/share/fonts</dir> <dir>/usr/local/share/fonts/chinese</dir> <dir>~/.fonts</dir>Copy the code
  • Refresh the font cache in memory, FC-cache
  • Now you can see that you have the font you just added on your machine. fc-list :lang=zh

You’re done

At this time, there is no problem, and the subsequent problems will be updated

Finally: IE loads the PDF

You need to install Adobe Reader

reference

  • Javascript to convert HTML to PDF, download, support multiple pages oh (HTML2Canvas and jsPDF)
  • HTML to PDF file, the perfect solution – jsPDF htmltocanvas, pdfmake, wkhtmltopdf, TuesPechkin, snappy
  • Puppeteer and egg.js are used to realize HTML2PDF and HTML2PNG.
  • page.pdf([options])