+1

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

Viblo
Let's register a Viblo Account to get more interesting posts.