Export file pdf trong Rails
This post hasn't been updated for 3 years
Cũng khá lâu trước đây mình có bài viết về việc sử dụng gem RubyXL để export file excel, hôm nay mình xin giới thiệu đến các bạn cách sử dụng gem Wicked_pdf để export ra file pdf (ngoài ra thì bạn có thể tìm hiểu thêm một gem khác cũng khá hay trong trường hợp này là PDFKkit)
Phần 1. Giới thiệu
Đơn giản, bạn có thể hiểu wicked_pfd là một gem sử dụng wkhtmltopdf để xuất nội dung ra một file pdf
từ HTML
Gem wicked_pfd tương thích với
- Ruby phiên bản
1.8.7
đến2.3
. - Rails
2
đến5.0
.
Phần 2. Cài đặt
Vì wicked_pfd được đóng gói cho wkhtmltopdf
, nên trước tiên chúng ta cần phải cài đặt wkhtmltopdf
cho hệ thống. Nếu dùng Ubuntu thì bạn có thể tiến hành cài đặt theo hướng dẫn ở đây
Thêm gem vào Gemfile và tiến hành bundle install
gem "wicked_pdf"
gem "wkhtmltopdf-binary"
Generate wicked_pdf
rails generate wicked_pdf
Câu lệnh trên sẽ tự động sinh ra cho bạn file cấu hình : config/initializers/wicked_pdf.rb
. Và nếu việc thực thi wkhtmltopdf
không nằm trên đường dẫn server của bạn thì bạn sẽ phải cấu hình thêm cho file này như sau
WickedPdf.config = {
exe_path: "/usr/local/bin/wkhtmltopdf"
}
Với một số phiên bản Rails cũ thì cần phải cấu hình thêm trong file config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
Nếu như bạn vẫn cấu hình như trên với những phiên bản Rails mới thì hệ thống của bạn vẫn có thể chạy thông mà không bị chết. Tuy nhiên sẽ có một số warning
của hệ thống tương tự như sau
warning: already initialized constant PDF
warning: previous definition of PDF was here
Để sử dụng wicked_pdf
cho cả dự án của mình thì bạn cần khai báo trong file application.rb
(với Rails 3) hoặc environment.rb
(với Rails 2)
require 'wicked_pdf'
config.middleware.use WickedPdf::Middleware
Phần 3. Sử dụng
Vì wkhtmltopdf-binary
được chạy bên ngoài ứng dụng Rails, nên chúng ta cần phải chỉnh sửa lại layout
để cung cấp cho hệ thống đường dẫn tuyệt đối đến các file javascript, css hoặc là file ảnh cần thiết. Có 2 cách để làm việc này
Nếu dùng các helpers có sẵn thì ta có layout
tương tự như sau
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
<%= wicked_pdf_stylesheet_link_tag "pdf" -%>
<%= wicked_pdf_javascript_include_tag "number_pages" %>
</head>
<body onload='number_pages'>
<div id="header">
<%= wicked_pdf_image_tag "mysite.jpg" %>
</div>
<div id="content">
<%= yield %>
</div>
</body>
</html>
Sử dụng helper như trên với asset pipeline sẽ gây ra lỗi và bạn sẽ không thể nạp các CSS
, JS
từ bên ngoài. Cho nên có thể bạn sẽ phải sử dụng wicked_pdf_asset_base64
ở đây. Điều này tùy thuộc vào hề thống của bạn. Code cũng tương tự như trên, chỉ khác ở các helper
stylesheet_link_tag wicked_pdf_asset_base64("pdf")
javascript_include_tag wicked_pdf_asset_base64("number_pages")
image_tag wicked_pdf_asset_base64("mysite.jpg")
Khi khai báo layout thế này thì wicked_pdf sẽ thấy file assets/stylesheets/pdf.css
, assets/javascripts/number_pages.js
,... trong hệ thống của bạn để nạp vào các hàm JS
hay là style cho trang pdf
Hoặc là bạn có thể đi thẳng đến một CDN (Content Delivery Network) cho những thư viện phổ biến
<!doctype html>
<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" %>
Nếu bạn tiến hành deploy code lên một số server như Heroku thì bạn sẽ cần config thêm trong config/initializes/assets.rb
để hệ thống có thể tìm thấy file CSS
và JS
config.assets.precompile += ['pdf.css', 'pdf.js', ...etc...]
Định dạng cho file pdf của chúng ta
respond_to do |format|
format.html
format.pdf do
render
# define options here
end
end
Có rất nhiều thuộc tính bạn có thể thiết lập cho file. Xin liệt kê ra một số thuộc tính mình cho rằng là cơ bản nhất
pdf
: Tên file xuất ra.type
("application/pdf") vàdisposition
("attachment") : Cho hệ thống biết là ta sẽ tải xuống một file (không có thì nó sẽ chỉ view ngay trên browser như một web bình thường).layout
: Chỉ ra file layout (dẫn đến chính cái layout đã định nghĩa ở trên).template
: Chỉ ra file template - nơi ta quy định tất cả nội dung của file tải xuống. Bạn code template giống hoàn toàn với việc code view.locals
: Là một hash chứa những variable cần thiết bạn muốn cho vào nội dung file.
Ngoài ra bạn cũng có thể khai báo các thuộc tính như header
, footer
; nhưng mình thích để phần này trong layout hơn
Để xuống trang, bạn có thể sử dụng một trong các cách dưới đâu ở bất kỳ chỗ nào trong file của bạn
<p style="page-break-before:always;"></p>
<p style="page-break-after:always;"></p>
<p style="page-break-inside: avoid;"></p>
Để đánh số trang thì đơn giản bạn chỉ cần thêm thuộc tính header
hoặc footer
(với các vị trí left
, center
, right
)
footer: { center: '[page]' }
Xong, như vậy là bạn đã có đầy đủ những kiến thức cơ bản nhất về wicked_pdf
cũng như cách sử dụng gem này để xuất nội dung ra file pdf. Mình sẽ sớm làm một demo đơn giản cho bài viết này
Cám ơn các bạn đã theo dõi bài viết.
Tham khảo
All Rights Reserved