diff --git a/lib/wicked_pdf.rb b/lib/wicked_pdf.rb index 27f43e35..766e3bdb 100644 --- a/lib/wicked_pdf.rb +++ b/lib/wicked_pdf.rb @@ -25,11 +25,17 @@ class WickedPdf include Progress def initialize(wkhtmltopdf_binary_path = nil) - @binary = Binary.new(wkhtmltopdf_binary_path, DEFAULT_BINARY_VERSION) + unless WickedPdf.config[:use_puppeteer] + @binary = Binary.new(wkhtmltopdf_binary_path, DEFAULT_BINARY_VERSION) + end end def binary_version - @binary.version + if WickedPdf.config[:use_puppeteer] + WickedPdf::DEFAULT_BINARY_VERSION + else + @binary.version + end end def pdf_from_html_file(filepath, options = {}) @@ -50,12 +56,7 @@ def pdf_from_url(url, options = {}) # merge in global config options options.merge!(WickedPdf.config) { |_key, option, _config| option } generated_pdf_file = WickedPdf::Tempfile.new('wicked_pdf_generated_file.pdf', options[:temp_path]) - command = [@binary.path] - command.unshift(@binary.xvfb_run_path) if options[:use_xvfb] - command += parse_options(options) - command << url - command << generated_pdf_file.path.to_s - + command = create_command(url, generated_pdf_file, options) print_command(command.inspect) if in_development_mode? if track_progress?(options) @@ -84,6 +85,20 @@ def pdf_from_url(url, options = {}) private + def create_command(url, generated_pdf_file, options) + if WickedPdf.config[:use_puppeteer] + spec = Gem::Specification.find_by_name('wicked_pdf') + node_modules_path = "#{Rails.root}/node_modules" + command = ['node', File.join(spec.gem_dir, 'lib', 'wicked_pdf', 'pdf.js'), node_modules_path] + else + command = [@binary.path] + command.unshift(@binary.xvfb_run_path) if options[:use_xvfb] + end + command += parse_options(options) + command << url + command << generated_pdf_file.path.to_s + end + def in_development_mode? return Rails.env == 'development' if defined?(Rails.env) 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());