Szpadel / chrome-headless-render-pdf

223 stars 67 forks source link

Add support for custom page header and footer and page margins #71

Open zigm opened 3 years ago

zigm commented 3 years ago

I have attached enhanced chrome-headless-render-pdf to support custom page header and footer and page margins. I am one of the developers on the free Windows Mbox Mail Viewer project. The current Viewer relies on -print-to-pdf Chrome's command line option to print HTML mails to PDF without user interaction. However, Chrome browser lack's ability to customize header and footer requested by users. I found the chrome-headless-render-pdf project that leverages CDP protocol to connect to Chrome Browser and render PDF but lacks an option to customize the page header and footer. I enhanced the chrome-headless-render-pdf application to support customization and attached the enhanced code for use by interested users. However, it would be best if the official project is enhanced. Attached are also two helper scripts that I was using during the development:

  1. render-html-pdf.js This script creates various header and footer templates in HTML for the enhanced chrome-headless-render-pdf.js. These templates were eventually integrated into the chrome-headless-render-pdf.js.
  2. render-pdf.js The small script to exec the chrome-headless-render-pdf.js to render pdf with one of the predefined custom header and footer templates.

Below shows new options implemented by the enhanced chrome-headless-render-pdf to support custom page header and footer and to configure page margins. The zip file doesn't contain valid npm package so it should not be installed by the npm manager. Just unzip the file and use as is. Run "node render-html-pdf.js" "node render-pdf.js" or run directly the chrome-headless-render-pdf.js with proper command line arguments. Development and testing was done on Windows 10. I am new to javascript so emhancements may not be optimal.

NOTE that Chrome Browser may not paint header and footer correctly for some web pages. This seems to be due to the fact that painting of header and footer is not independent from painting web page content.

function printHelp() { console.log('chrome-headless-render-pdf [OPTIONS] --url=URL --pdf=OUTPUT-FILE [--url=URL2 --pdf=OUTPUT-FILE2] ...'); console.log(' Options:'); console.log(' --help this screen'); console.log(' --url url to load, for local files use: file:///path/to/file'); console.log(' --pdf output for generated file can be relative to current directory'); console.log(' --chrome-binary set chrome location (use this options when autodetection fail)'); console.log(' --chrome-option set chrome option, can be used multiple times, e.g. --chrome-option=--no-sandbox'); console.log(' --remote-host set chrome host (for remote process)'); console.log(' --remote-port set chrome port (for remote process)'); console.log(' --include-background include elements background'); console.log(' --landscape generate pdf in landscape orientation'); console.log(' --window-size specify window size, width(,x*)height (e.g. --window-size 1600,1200 or --window-size 1600x1200)'); console.log(' --paper-width specify page width in inches (defaults to 8.5 inches)'); console.log(' --paper-height specify page height in inches (defaults to 11.0 inches)'); console.log(' --margin-top page top margin (defaults to ~0.4inches i.e. 1 centimeter)'); console.log(' --margin-bottom page bottom margin (defaults to ~0.4inches i.e. 1 centimeter)'); console.log(' --margin-left page left margin (defaults to ~0.4inches i.e. 1 centimeter)'); console.log(' --margin-right page right margin (defaults to ~0.4inches i.e. 1 centimeter)'); console.log(' --page-ranges specify pages to render default all pages, e.g. 1-5, 8, 11-13'); console.log(' --scale specify scale of the webpage rendering (defaults to 1.0)'); console.log(' Header and Footer Options:'); console.log(' --url-alias replace url with url-alias in PDF page footer'); console.log(' --header-template custom HTML template for the page header. Takes precedence over --header-template-number'); console.log(' --footer-template custom HTML template for the page footer. Takes precedence over --footer-template-number'); console.log(' --header-template-number number assigned to preconfigured HTML template for the page header'); console.log(' 0=empty, 1=[date][title], 2==[title][date], 3=[title]'); console.log(' --footer-template-number number assigned to preconfigured HTML template for the page footer'); console.log(' 0=empty, 1=[url][page#], 2==[page#], 3=[date][url][page#], 4=[date][page#]'); console.log(' --header-footer-margin left and right margin size of page header and footer (defaults to 0.3inches)'); console.log(' --header-footer-font-size font size of page header and footer (defaults to 8px)'); console.log(' if you configure font size > 10, you will likely need to increase --margin-bottom and --margin-top'); console.log(' --page-numbering-style page numbering format in the page footer (defaults to 1)'); console.log(' 1=page# of total pages, 2=page#/total pages, 3=page#'); console.log(' --display-header-footer print page header and footer (defaults to false)'); console.log(' --display-header-footer-native let browser create and print page header and footer (defaults to false)'); console.log(''); console.log(' Example:'); console.log(' Render single pdf file'); console.log(' chrome-headless-render-pdf --url=http://google.com --pdf=test.pdf'); console.log(' Render pdf from local file'); console.log(' chrome-headless-render-pdf --url=file:///tmp/example.html --pdf=test.pdf'); console.log(' Render multiple pdf files'); console.log(' chrome-headless-render-pdf --url=http://google.com --pdf=test.pdf --url="file:///tmp/example.html" --pdf=test2.pdf'); console.log(''); console.log(' NOTE: To avoid surprises, place url, url-alias and pdf between double quotes, for example --url-alias="GOOGLE HOME PAGE"'); console.log(''); } chrome-headless-render-pdf-master.zip

zigm commented 3 years ago

I see that ability to customize header and footer was added in #41. Unfortunately options to configure page margins was not implemented at the same time. Hope these options will be added to support all options supported by Chrome. In addition, my prototype (attached) supports predefined footer and header layouts, similar to Windows Page Configuration dialog. These layouts work for most use cases but they can be considered nice too have.