From dc99ae38d99e2cc5683a540adcb3d7f28cc2c919 Mon Sep 17 00:00:00 2001 From: Erik Axel Nielsen Date: Thu, 6 Sep 2018 20:52:43 +0200 Subject: [PATCH] Support for using headless chrome instead of wkhtmltopdf. --- lib/wicked_pdf.rb | 21 ++++++++---- lib/wicked_pdf/pdf.js | 78 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 lib/wicked_pdf/pdf.js diff --git a/lib/wicked_pdf.rb b/lib/wicked_pdf.rb index e1ead7d2..f0d9b7af 100644 --- a/lib/wicked_pdf.rb +++ b/lib/wicked_pdf.rb @@ -37,11 +37,12 @@ class WickedPdf attr_accessor :binary_version def initialize(wkhtmltopdf_binary_path = nil) - @exe_path = wkhtmltopdf_binary_path || find_wkhtmltopdf_binary_path - raise "Location of #{EXE_NAME} unknown" if @exe_path.empty? - raise "Bad #{EXE_NAME}'s path: #{@exe_path}" unless File.exist?(@exe_path) - raise "#{EXE_NAME} is not executable" unless File.executable?(@exe_path) - + unless WickedPdf.config[:use_puppeteer] + @exe_path = wkhtmltopdf_binary_path || find_wkhtmltopdf_binary_path + raise "Location of #{EXE_NAME} unknown" if @exe_path.empty? + raise "Bad #{EXE_NAME}'s path: #{@exe_path}" unless File.exist?(@exe_path) + raise "#{EXE_NAME} is not executable" unless File.executable?(@exe_path) + end retrieve_binary_version end @@ -67,8 +68,14 @@ def pdf_from_url(url, options = {}) # merge in global config options options.merge!(WickedPdf.config) { |_key, option, _config| option } generated_pdf_file = WickedPdfTempfile.new('wicked_pdf_generated_file.pdf', options[:temp_path]) - command = [@exe_path] - command << '-q' unless on_windows? # suppress errors on stdout + if WickedPdf.config[:use_puppeteer] + spec = Gem::Specification.find_by_name('wicked_pdf') + node_modules_path = "#{Rails.root.to_s}/node_modules" + command = ['node', File.join(spec.gem_dir, 'lib', 'wicked_pdf', 'pdf.js'), node_modules_path] + else + command = [@exe_path] + command << '-q' unless on_windows? # suppress errors on stdout + end command += parse_options(options) command << url command << generated_pdf_file.path.to_s diff --git a/lib/wicked_pdf/pdf.js b/lib/wicked_pdf/pdf.js new file mode 100644 index 00000000..49cf8ea9 --- /dev/null +++ b/lib/wicked_pdf/pdf.js @@ -0,0 +1,78 @@ +"use strict"; +const puppeteer = require(`${process.argv[2]}/puppeteer`); +const createPdf = async options => { + let browser; + try { + browser = await puppeteer.launch({ + args: ["--no-sandbox", "--disable-setuid-sandbox"] + }); + const page = await browser.newPage(); + await page.goto(options.input, { waitUntil: "networkidle2" }); + delete options.input; + await page.pdf(options); + } catch (err) { + console.log(err.message); + } finally { + if (browser) { + browser.close(); + } + process.exit(); + } +}; +const parseCmd = () => { + let options = { + margin: { + top: "10mm", + bottom: "10mm", + left: "10mm", + right: "10mm" + }, + landscape: false, + format: "A4", // Format takes precedence over width and height if set + height: "297", // A4 + width: "210", // A4 + path: process.argv[process.argv.length - 1], + input: process.argv[process.argv.length - 2], + scale: 1.0, + displayHeaderFooter: false, + printBackground: true + }; + for (let i = 3; i < process.argv.length - 2; i += 2) { + const value = process.argv[i + 1]; + switch (process.argv[i]) { + case "--page-size": + options.format = value; + break; + case "--orientation": + options.landscape = value === "Landscape"; + break; + case "--zoom": + options.scale = parseFloat(value); + break; + case "--width": + delete options.format; + options.width = value; + break; + case "--height": + delete options.format; + options.height = value; + break; + case "--margin-top": + options.margin.top = value; + break; + case "--margin-bottom": + options.margin.bottom = value; + break; + case "--margin-left": + options.margin.left = value; + break; + case "--margin-right": + options.margin.right = value; + break; + default: + console.log("Unknown argument: " + value); + } + } + return options; +}; +createPdf(parseCmd());