Created
October 24, 2012 17:23
-
-
Save calebhaye/3947475 to your computer and use it in GitHub Desktop.
Generating PDFs with wicked_pdf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module PdfHelper | |
| require 'wicked_pdf' | |
| def self.included(base) | |
| base.class_eval do | |
| alias_method_chain :render, :wicked_pdf | |
| end | |
| end | |
| def render_with_wicked_pdf(options = nil, *args, &block) | |
| if options.is_a?(Hash) && options.has_key?(:pdf) | |
| logger.info '*'*15 + 'WICKED' + '*'*15 | |
| make_and_send_pdf(options.delete(:pdf), (WICKED_PDF.blank? ? {} : WICKED_PDF).merge(options)) | |
| else | |
| render_without_wicked_pdf(options, *args, &block) | |
| end | |
| end | |
| def parse_options opts | |
| "#{parse_header_footer(:header => opts.delete(:header), :footer => opts.delete(:footer), :layout => opts[:layout])} " + \ | |
| "#{parse_toc(opts.delete(:toc))} #{parse_outline(opts.delete(:outline))} #{parse_margins(opts.delete(:margin))} #{parse_others(opts)} " | |
| end | |
| private | |
| def make_pdf(options = {}) | |
| html_string = render_to_string(:template => options[:template], :layout => options[:layout]) | |
| w = WickedPdf.new(options[:wkhtmltopdf]) | |
| w.pdf_from_string(html_string, parse_options(options)) | |
| end | |
| def make_and_send_pdf(pdf_name, options = {}) | |
| options[:wkhtmltopdf] ||= nil | |
| options[:layout] ||= false | |
| options[:template] ||= File.join(controller_path, action_name) | |
| if options[:show_as_html] | |
| render :text => render_to_string(:template => options[:template], :layout => options[:layout]) | |
| else | |
| send_data(make_pdf(options), :filename => pdf_name + '.pdf', :type => 'application/pdf') | |
| end | |
| end | |
| def make_option name, value, type=:string | |
| "--#{name.gsub('_', '-')} " + case type | |
| when :boolean: "" | |
| when :numeric: value.to_s | |
| else "'#{value}'" | |
| end + " " | |
| end | |
| def make_options opts, names, prefix="", type=:string | |
| names.collect {|o| make_option("#{prefix.blank? ? "" : prefix + "-"}#{o.to_s}", opts[o], type) unless opts[o].blank?}.join | |
| end | |
| def parse_header_footer opts | |
| r="" | |
| [:header, :footer].collect do |hf| | |
| unless opts[hf].blank? | |
| opt_hf = opts[hf] | |
| r += make_options(opt_hf, [:center, :font_name, :left, :right], "#{hf.to_s}") | |
| r += make_options(opt_hf, [:font_size, :spacing], "#{hf.to_s}", :numeric) | |
| r += make_options(opt_hf, [:line], "#{hf.to_s}", :boolean) | |
| unless opt_hf[:html].blank? | |
| r += make_option("#{hf.to_s}-html", opt_hf[:html][:url]) unless opt_hf[:html][:url].blank? | |
| WickedPdfTempfile.open("wicked_pdf.html") do |f| | |
| f << render_to_string(:template => opt_hf[:html][:template], :layout => opts[:layout]) | |
| r += make_option("#{hf.to_s}-html", "file://#{f.path}") | |
| end unless opt_hf[:html][:template].blank? | |
| end | |
| end | |
| end unless opts.blank? | |
| r | |
| end | |
| def parse_toc opts | |
| unless opts.blank? | |
| r = make_options(opts, [:font_name, :header_text], "toc") | |
| r += make_options(opts, [:depth, :header_fs, :l1_font_size, :l2_font_size, :l3_font_size, :l4_font_size, :l5_font_size, :l6_font_size, :l7_font_size, :l1_indentation, :l2_indentation, :l3_indentation, :l4_indentation, :l5_indentation, :l6_indentation, :l7_indentation], "toc", :numeric) | |
| r + make_options(opts, [:no_dots, :disable_links, :disable_back_links], "toc", :boolean) | |
| end | |
| end | |
| def parse_outline opts | |
| unless opts.blank? | |
| r = make_options(opts, [:outline], "", :boolean) | |
| r + make_options(opts, [:outline_depth], "", :numeric) | |
| end | |
| end | |
| def parse_margins opts | |
| make_options(opts, [:top, :bottom, :left, :right], "margin", :numeric) unless opts.blank? | |
| end | |
| def parse_others opts | |
| unless opts.blank? | |
| r = make_options(opts, [:orientation, :page_size, :proxy, :username, :password, :cover, :dpi, :encoding, :user_style_sheet]) | |
| r += make_options(opts, [:redirect_delay, :zoom, :page_offset], "", :numeric) | |
| r + make_options(opts, [:book, :default_header, :disable_javascript, :greyscale, :lowquality, :enable_plugins, :disable_internal_links, :disable_external_links, :print_media_type, :disable_smart_shrinking, :use_xserver, :no_background], "", :boolean) | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <h3>Samples</h3> | |
| <ul> | |
| <li> | |
| hello world (<%= link_to 'html', samples_path('hello_world') %> | | |
| <%= link_to 'pdf', samples_path('hello_world', 'pdf') %>) | |
| </li> | |
| <li> | |
| breakfast (<%= link_to 'html', samples_path('breakfast') %> | | |
| <%= link_to 'pdf', samples_path('breakfast', 'pdf') %>) | |
| </li> | |
| </ul> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'test_helper' | |
| WICKED_PDF = { :exe_path => '/usr/local/bin/wkhtmltopdf' } | |
| HTML_DOCUMENT = "<html><body>Hello World</body></html>" | |
| class WickedPdfTest < ActiveSupport::TestCase | |
| test "should generate PDF from html document" do | |
| wp = WickedPdf.new | |
| pdf = wp.pdf_from_string HTML_DOCUMENT | |
| assert pdf.start_with?("%PDF-1.4") | |
| assert pdf.rstrip.end_with?("%%EOF") | |
| assert pdf.length > 100 | |
| end | |
| test "should raise exception when no path to wkhtmltopdf" do | |
| assert_raise RuntimeError do | |
| WickedPdf.new " " | |
| end | |
| end | |
| test "should raise exception when wkhtmltopdf path is wrong" do | |
| assert_raise RuntimeError do | |
| WickedPdf.new "/i/do/not/exist/notwkhtmltopdf" | |
| end | |
| end | |
| test "should raise exception when wkhtmltopdf is not executable" do | |
| fp = File.expand_path(File.dirname(__FILE__)) + '/wkhtmltopdf' | |
| File.chmod 0000, fp | |
| assert_raise RuntimeError do | |
| WickedPdf.new fp | |
| end | |
| File.chmod 0755, fp | |
| end | |
| test "should raise exception when pdf generation fails" do | |
| fp = File.expand_path(File.dirname(__FILE__)) + '/wkhtmltopdf' | |
| File.chmod 0777, fp | |
| wp = WickedPdf.new fp | |
| assert_raise RuntimeError do | |
| wp.pdf_from_string HTML_DOCUMENT | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment