12/08/2018, 13:27

Sử dụng Wicked PDF để generate file pdf

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, ...

  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 :
        gem "wicked_pdf"
- Sau đó tạo `initializer`
     $ rails generate wicked_pdf
- Cũng có thể cần thêm
     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.
    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:
    WickedPdf.config = {
        exe_path: "usr/local/bin/wkhtmltopdf"
    }
  1. Cách sử dụng cơ bản
        class OrdersController < ApplicationController
          def show
            respond_to do |format|
              format.html
              format.pdf do
                render pdf: "show"
              end
            end
          end
        end
  1. Đ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ụng layout thông thường sẽ không thể hoạt động. Nếu bạn muốn sử dụng CSS, Javascript 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
    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
        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:
    config.assets.precompile += ["pdf.css", "pdf.js", ...etc...]
  1. Cách sử dụng nâng cao với tất cả các tùy chọn có sẵn
       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_awidth:                     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
  1. 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
        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
            pdf = WickedPdf.new.pdf_from_html_file("your_path")
    + Tạo file PDF từ đường dẫn có sẵn
            pdf = WickedPdf.new.pdf_from_url("url)
    + Tạo file PDF từ string sử dụng `template`, `layouts` và nội dung tùy chọn (`header`, `footer`)
          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
        File.open(save_path, "wb") do file|
          file << pdf
        end
0