Export PDF in Rails 7 running on Docker OS Alpine 3.18
Task tiếp theo mình được giao là export file PDF trong Rails 7, mô tả project của mình:
- Rails 7 chạy trên Docker OS Alpine 3.18
- Sử dụng Wicked-PDF để export file PDF
- Ngôn ngữ hiển thị Japanese
- Frontend type slim file Ok, vào việc thôi
Sử dụng wicked-pdf
Mình follow theo hướng dẫn của wicked_pdf và tutorial từ [blog] (https://blog.corsego.com/gem-wicked-pdf). Cài gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
Rồi chạy trong terminal các lệnh
docker compose exec app rails bundle install
docker compose exec app rails g wicked_pdf
File wicked_pdf.rb sẽ xuất hiện trong thư mục config/initializers.
Config file wicked_pdf.rb
WickedPdf.config = {
exe_path: '/usr/local/bundle/bin/wkhtmltopdf',
enable_local_file_access: true,
}
Như vầy hén, nhưng mà chứ ý cái đường dẫn exe_path thì kiểm tra trong docker thử cái wkhtmltopdf nó nằm đâu
# open terminal app in docker
which wkhtmltopdf
Xuất PDF
Trong controller,
def download_pdf
respond_to do |format|
format.html
format.pdf do
render pdf: 'pdf-sample2',
template: 'quotes/quote_pdf',
formats: [:html],
encoding: 'UTF-8',
layout: 'layouts/pdf',
locals: {quote: @quote},
disposition: 'attachment'
end
end
end
Explain một xíu ở chỗ này
- pdf: 'Tên file'
- ở Rails 7 thì trong template sẽ không chỉ rõ đuôi file, (file của mình quote_pdf.slim), nếu ghi rõ ra sẽ bị lỗi (khác với Rails 6), Bug
- locals: là nơi khai báo biến local để sử dụng cho phần view (file quote_pdf.slim)
- layout: giống như phần bọc ngoài chung cho các file pdf, ở đây mình định nghĩa một file pdf.slim trong folder quotes, phần này giống như trong tutorial
- disposition: 'attachment' -> tải xuống file PDF, default của nó là 'inline' thì sẽ được mở qua 1 tab khác
Việc còn lại là viết file view quote_pdf.slim.
Fix bug
Tưởng đâu mọi thứ oke, sẽ work ngon lành, ai mà có dè, hông được gì hết trơn. Mình bị dính lỗi Invalid platform. Lỗi này xuất phát từ việc OS đang sử dụng là Alpine3.18, mà anh này ko có sẵn package cho wkhtmltopdf-binary nên wkhtmlpdf không có work được. Thế nào cần phải manual install trong Dockerfile, install alpine-wkhtmltopdf
Rồi tiếp theo fixbug cho tiếng Nhật, thì cần phải install font tiếng Nhật trên docker, mình cũng install manual luôn
- Tải font mình cần từ Google Font, mình xài [Noto Sans Font], cho nó vào folder vendor
- thêm lệnh trong Dockerfile
RUN mkdir -p /usr/share/fonts/truetype/google-fonts
RUN find $PWD/vendor/fonts/Noto_Sans_JP/ -name "*.ttf" -exec install -m644 {} /usr/share/fonts/truetype/google-fonts/ \; || return 1
Lệnh này nó sẽ copy font trong vendor cho vào docker container của mình. Oke, giờ mọi thứ chạy ổn thỏa rồi. Well done ♥️!!
All rights reserved