web-dev-qa-db-ja.com

Prawn :: Errors :: IncompatibleStringEncoding:ドキュメントにWindows-1252文字セットと互換性のないテキストが含まれています

以下は、エビPDF PDF-

def initialize(opportunity_application)
  pdf = Prawn::Document.new(:page_size => [1536, 2048], :page_layout => :landscape)
  cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('iso-8859-1').encode('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: "app/assets/fonts/opensans.ttf")

  t = pdf.make_table [[cell_1]]
  t.draw
  pdf.render_file "tmp/mos_certificates/application_test.pdf"
end

トルコ語のEylülÇamcıという名前をレンダリングすると、次のエラーが発生します-

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

その名前の文字をサポートするTTFフォントを既に使用していますが、名前を正しく印刷するにはどうすればよいですか?

24
Michael Victor

iso-8859-1 にトルコ語が含まれていないようです。

一方、 iso-8859-9 は動作するはずです。

したがって、次のようにコードを変更してみてください(変更したISO番号を確認してください)。

_...
cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('iso-8859-9').encode('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: "app/assets/fonts/opensans.ttf")
...
_

そして 楽しいリンク は、文字セットだけでなく、トルコの他の内部化の違いにも関連しています。


編集1:基本的なチェックを行いましたが、テキストはすでにUTF-8であるようです。では、なぜiso-8859に変更してUTF-8に戻す必要があるのでしょうか。

"Eylül Çamcı".force_encoding('utf-8')だけを試していただけますか?

_irb(main):013:0> "Eylül Çamcı".encoding
=> #<Encoding:UTF-8>
irb(main):014:0> "Eylül Çamcı".force_encoding('UTF-8')
=> "Eylül Çamcı"
irb(main):015:0>
_

編集2:フォントパスを確認できますか?両方のフォントが存在し、パスは適切ですか?

_#Rails.root.join('app/assets/fonts/opensans.ttf')
cell_1 = pdf.make_cell(content: "Eylül Çamcı".force_encoding('utf-8'), borders: [], size: 66, :text_color => "000000", padding: [0,0,0,700], font: Rails.root.join('app/assets/fonts/opensans.ttf'))
_
10
Mehmet Kaplan

エビがどのように機能するか覚えていないのですが、PDFファイルはUTF-8をサポートしていません。これは、StringオブジェクトのデフォルトのRubyエンコーディングです。

実際、PDFファイルのみサポートASCII内部フォントを使用したエンコーディング-他のエンコーディングでは、独自のフォントを使用する必要があります(移植性のためにも推奨されます)。

回避策は、文字マップ(CMaps)を使用することです-カスタムCMapまたは事前定義されたもの(BYOフォント)。

通常、PDFファイルには、埋め込みフォント(またはフォントのサブセット)、およびCMapが含まれており、バイトの値(またはバイト数)を目的のフォントグリフにマッピングします。つまり、指定されたフォントを使用するときに、ASCIIでは「a」である97をåグリフにマッピングします。

前回エビを使用したときは、TTFフォントをサポートし、テキスト入力にUTF-8文字列を使用して自動的にフォントマップを作成したと思いますが、適切なフォントをエビにロードして使用することを忘れないでくださいit!。

例は this answer で確認できます。

幸運を!

[〜#〜]編集[〜#〜]

@mklのコメントを反映するように回答を更新しました。

@mklは、事前定義されたいくつかのマルチバイトエンコーディング(事前定義されたCMapを使用)を含む、他のエンコーディングがサポートされている、または可能であること(BYOフォント)を指摘しました。

4
Myst

このアンサーから 任意のエンコーディングから文字列をUTF-8に強制する

エンコーディングの「強制」は簡単ですが、文字を変換するのではなく、エンコーディングを変更するだけです。

str = str.force_encoding("UTF-8")
str.encoding.name # => 'UTF-8'

変換を実行する場合は、encodeを使用します

実際、@ MehmetKaplanが言ったように:

Iso-8859-1でトルコ語が欠けているように見えます。

一方、iso-8859-9は動作するはずです。

したがって、 force_encoding もう少しだけ encode

[37] pry(main)> "Eylül Çamcı".encode('iso-8859-1')
Encoding::UndefinedConversionError: U+0131 from UTF-8 to ISO-8859-1
from (pry):39:in `encode'
[38] pry(main)> "Eylül Çamcı".encode('iso-8859-9')
=> "Eyl\xFCl \xC7amc\xFD"

つまり、コード内でUTF-8を完全に削除する必要があります。

content: "Eylül Çamcı".encode('iso-8859-9'),
2
Kruupös