How do I change font in Prawn

2019-06-17 03:39发布

问题:

What I'm trying to do is generate a PDF using Prawn, while having some language specific characters.

And as a result I'm getting the following error:

raise Prawn::Errors::IncompatibleStringEncoding,
   "Your document includes text that's not compatible with the  Windows-1252 character set.\n" \
   "If you need full UTF-8 support, use TTF fonts instead of PDF's built-in fonts\n."

So I tried changing the font by doing this:

# app/models/prawn/change_font_decorator.rb

Prawn::Document.generate("output.pdf") do
  font_families.update("Arial" => {
    :normal => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold_italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  })
  font "Arial"
end

Yet, I'm getting the same error when trying to generate a PDF file.

Any ideas on how to solve this?

回答1:

The prawn manual is an excellent reference, and includes sections on font usage. The "External Fonts" section is particularly relevant to your issue.

Here's a basic case that should work, although it doesn't support bold and italic:

Prawn::Document.generate("output.pdf") do
  font Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  text "Euro €"
end

To also use bold and italic, it's best to register a font family that doesn't conflict with one of the standard PDF fonts:

Prawn::Document.generate("output.pdf") do
  font_families.update("OpenSans" => {
    :normal => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold_italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  })
  font "OpenSans"
  text "Euro €"
end


回答2:

If you're building your PDF using initialize, you can simply update your font families in the initialize method and then set the desired font.

class InvoicePdf < Prawn::Document

  def initialize()
    super()
    self.font_families.update("DejaVuSans" => {:normal => "#{Rails.root}/public/DejaVuSans.ttf"})
    font "DejaVuSans"
    business_logo
    invoice_items
    footer
  end

  def business_logo
    ##stuff here
  end

end