Xuất Ra File PDF với gem Wicked - Ruby on Rails


  1. Giới thiệu
    • Wicked PDF sử dụng các tiện ích wkhtmltopdf để tạo file PDF cho người dùng từ HTML. Nói cách khác, bạn chỉ cần viết một 1 page HTML như bạn sẽ bình thường, sau đó để cho Wicked PDF sẽ sử dụng đó để tạo ra pdf cho bạn.
    • Wicked PDF làm việc trên các version Ruby từ 1.8.7 -> 2.1, Rails từ 2 -> 4.1
  2. Cách cài đặt
    • Add wicked_pdf vào Gemfile và chạy bundle install :
      Ruby
      
      gem "wicked_pdf"
    • Sau đó tạo initializer
      SH
      
      $ rails generate wicked_pdf
    • Cũng có thể cần thêm
      Ruby
      
      Mime::Type.register "application/pdf", :pdf
      vào config/initializers/mime_types.rb với những versions cũ của Rails.
    • Ta cũng phải cài đặt wkhtmltopdf, bởi vì wicked_pdf là wrapper cho wkhtmltopdf
    • Cách đơn giản nhất để cài đặt tất cả các tập tin nhị phân (Linux, OSX, Windows) là thông qua gem wkhtmltopdf-binary. Để cài đặt đó, ta thêm wkhtmltopdf-binary vào trong Gemfile.
      Ruby
      
      gem "wkhtmltopdf-binary"
    • Nếu thực thi wkhtmltopdf của bạn không phải là trên webserver của bạn, bạn có thể cấu hình nó trong initializer:
      Ruby
      
      WickedPdf.config = {
      exe_path: "usr/local/bin/wkhtmltopdf"
      }
  3. Cách sử dụng cơ bản
    Ruby
    
        class OrdersController < ApplicationController
          def show
            respond_to do |format|
              format.html
              format.pdf do
                render pdf: "show"
              end
            end
          end
        end
  4. Điều kiện sử dụng
    • Các nhị phân wkhtmltopdf đang chạy bên ngoài của ứng dụng Rails của bạn, do đó khi sử dụnglayout thông thường sẽ không thể hoạt động. Nếu bạn muốn sử dụng CSSJavascript hay hiển thị hình ảnh thì bạn phải thay đổi các tham chiếu tuyệt đối đến các tập tin. Cách tốt nhất để Rails không sử dụng asset pipeline là sử dụng wicked_pdf_stylesheet_link_tag,wicked_pdf_javascript_include_tag và wicked_pdf_image_tag hoặc trỏ thẳng đến một CDN cho các thư việc của jquery
      Ruby
      
      html
      head
      = wicked_pdf_stylesheet_link_tag "pdf"
      = wicked_pdf_javascript_include_tag "pdf"
      title
      = full_title(yield(:title))
      body
      = wicked_pdf_image_tag "logo.png"
      = yield
    • CDN reference
      Ruby
      
      html
        head
          = javascript_include_tag "http://code.jquery.com/jquery-1.10.0.min.js"
          = javascript_include_tag "http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"
    • Sử dụng Asset pipeline Cách xử lý này cho asset pipeline trên Heroku là bao gồm các tập tin trong danh sách asset precompile của bạn, như sau:
      Ruby
      
      config.assets.precompile += ["pdf.css", "pdf.js", ...etc...]
  5. Cách sử dụng nâng cao với tất cả các tùy chọn có sẵn
    Ruby
    
       def show
          respond_to do |format|
            format.html
            format.pdf do
              render pdf:                            "file_name",
                     disposition:                    "attachment",
                     template:                       "things/show.pdf.erb",
                     file:                           "#{Rails.root}/files/foo.erb"
                     layout:                         "pdf.html",
                     wkhtmltopdf:                    "/usr/local/bin/wkhtmltopdf",
                     show_as_html:                   params.key?("debug"),
                     orientation:                    "Landscape",
                     page_size:                      "A4, Letter, ...",
                     page_height:                    NUMBER,
                     page_width:                     NUMBER,
                     save_to_file:                   Rails.root.join("pdfs", "#{filename}.pdf"),
                     save_only:                      false,
                     proxy:                          "TEXT",
                     basic_auth:                     false
                     username:                       "TEXT",
                     password:                       "TEXT",
                     title:                          "Alternate Title",
                     cover:                          "URL, Pathname, or raw HTML string",
                     dpi:                            "dpi",
                     encoding:                       "TEXT",
                     user_style_sheet:               "URL",
                     cookie:                         ["_session_id SESSION_ID"],
                     post:                           ["query QUERY_PARAM"],
                     redirect_delay:                 NUMBER,
                     javascript_delay:               NUMBER,
                     window_status:                  "TEXT",
                     image_quality:                  NUMBER,
                     no_pdf_compression:             true,
                     zoom:                           FLOAT,
                     page_offset:                    NUMBER,
                     book:                           true,
                     default_header:                 true,
                     disable_javascript:             false,
                     grayscale:                      true,
                     lowquality:                     true,
                     enable_plugins:                 true,
                     disable_internal_links:         true,
                     disable_external_links:         true,
                     print_media_type:               true,
                     disable_smart_shrinking:        true,
                     use_xserver:                    true,
                     background:                     false,
                     no_background:                  true,
                     viewport_size:                  "TEXT",
                     extra:                          "",
                     outline: {   outline:           true,
                                  outline_depth:     LEVEL },
                     margin:  {   top:               SIZE,
                                  bottom:            SIZE,
                                  left:              SIZE,
                                  right:             SIZE },
                     header:  {   html: {            template: "users/header.pdf.erb",
                                                     layout:   "pdf_plain.html",
                                                     url:      "www.example.com",
                                                     locals:   { foo: @bar }},
                                  center:            "TEXT",
                                  font_name:         "NAME",
                                  font_size:         SIZE,
                                  left:              "TEXT",
                                  right:             "TEXT",
                                  spacing:           REAL,
                                  line:              true,
                                  content:           "HTML CONTENT ALREADY RENDERED"},
                     footer:  {   html: {   template:"shared/footer.pdf.erb",
                                            layout:  "pdf_plain.html",
                                            url:     "www.example.com",
                                            locals:  { foo: @bar }},
                                  center:            "TEXT",
                                  font_name:         "NAME",
                                  font_size:         SIZE,
                                  left:              "TEXT",
                                  right:             "TEXT",
                                  spacing:           REAL,
                                  line:              true,
                                  content:           "HTML CONTENT ALREADY RENDERED"},
                     toc:     {   font_name:         "NAME",
                                  depth:             LEVEL,
                                  header_text:       "TEXT",
                                  header_fs:         SIZE,
                                  text_size_shrink:  0.8,
                                  l1_font_size:      SIZE,
                                  l2_font_size:      SIZE,
                                  l3_font_size:      SIZE,
                                  l4_font_size:      SIZE,
                                  l5_font_size:      SIZE,
                                  l6_font_size:      SIZE,
                                  l7_font_size:      SIZE,
                                  level_indentation: NUM,
                                  l1_indentation:    NUM,
                                  l2_indentation:    NUM,
                                  l3_indentation:    NUM,
                                  l4_indentation:    NUM,
                                  l5_indentation:    NUM,
                                  l6_indentation:    NUM,
                                  l7_indentation:    NUM,
                                  no_dots:           true,
                                  disable_dotted_lines:  true,
                                  disable_links:     true,
                                  disable_toc_links: true,
                                  disable_back_links:true,
                                  xsl_style_sheet:   "file.xsl"}
            end
          end
        end
  6. Cách sử dụng nâng cao
    • Nếu bạn cần phải chỉ cần tạo ra một pdf và không hiển thị nó:
      • Tạo pdf từ string
        Ruby
        
        pdf = WickedPdf.new.pdf_from_string("ceate a pdf from a string")
      • Tạo ra một tập tin PDF từ một file html mà không cần chuyển đổi nó thành string.
      • Đường dẫn là đường dẫ n tuyệt đối
        Ruby
        
        pdf = WickedPdf.new.pdf_from_html_file("your_path")
      • Tạo file PDF từ đường dẫn có sẵn
        Ruby
        
        pdf = WickedPdf.new.pdf_from_url("url)
      • Tạo file PDF từ string sử dụng templatelayouts và nội dung tùy chọn (headerfooter)
        Ruby
        
        string = ApplicationController.new.render_to_string(
        template: "pc/orders/details.pdf.slim",
        layout: "pc/layouts/pdf.slim",
        locals: {:@order => order}
        )
        pdf = WickedPdf.new.pdf_from_string string, encoding: "UTF-8"
      • Lưu file pdf
        Ruby
        
        File.open(save_path, "wb") do file|
        file << pdf
        end
  7. Tài liệu tham khảo

Comments