Skip to content

Instantly share code, notes, and snippets.

@hendricius
Created January 20, 2015 17:25
Show Gist options
  • Save hendricius/cb12d9e0623061190a66 to your computer and use it in GitHub Desktop.
Save hendricius/cb12d9e0623061190a66 to your computer and use it in GitHub Desktop.
A service that makes printing a PDF with pdfkit easier.
# Convert html to a PDF file.
class PdfPrinter
include Virtus.model
attribute :html, String
attribute :file_name, String, default: ->(printer, attribute) { "#{SecureRandom.hex(20)}-#{DateTime.now.to_i}.pdf"}
attribute :store_location, String, default: "/tmp"
attribute :temp_css_location, String, default: "/tmp"
attribute :wkhtmltopdf_parameters, Hash, default: {
"--footer-right" => "[page]/[toPage]",
"--footer-font-size" => 8
}
attribute :html_header, String, default: nil
attribute :html_header_file_name, Object, default: ->(printer, attribute) { "#{SecureRandom.hex(20)}-#{DateTime.now.to_i}.html"}
attribute :orientation, String, default: 'portrait'
attribute :footer_center_text, String, default: ->(printer, attribute) { "Report - #{DateTime.now.strftime('%F')}"}
def setup
create_html_header_file if html_header.present?
end
def generate
stylesheet = temp_stylesheet
raise StandardError, "Not all parameters provided" unless html && stylesheet
pdf = PDFKit.new html
# Add all stylesheets
pdf.stylesheets << stylesheet
# Pass parameters to pdf engine
wkhtmltopdf_parameters.each do |key, value|
pdf.options[key] = value
end
pdf.options["--footer-center"] = footer_center_text
if html_header_file_name.present?
pdf.options["--header-html"] = full_html_header_location
pdf.options["--margin-top"] = 30
pdf.options["--margin-bottom"] = 26
pdf.options["--header-spacing"] = 5
pdf.options["--footer-spacing"] = 5
end
pdf.options["--orientation"] = orientation
# Save PDF
begin
pdf.to_file full_file_location
rescue => e
end
full_file_location
end
def full_file_location
"#{store_location}/#{file_name}"
end
def full_html_header_location
"#{store_location}/#{html_header_file_name}"
end
def css_file_name
file_name.gsub(".pdf", ".css")
end
# To get stylesheets to work properly.
def temp_stylesheet
css = Rails.application.assets.find_asset('application_print.css').body
temp_css_file = "#{temp_css_location}/#{css_file_name}"
File.open(temp_css_file, 'w') { |file| file.write(css) }
temp_css_file
end
def create_html_header_file
File.open(full_html_header_location, "w") do |f|
f.write html_header
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment