Prawn:: Errors:: IncompatibleStringEncoding: ваш документ содержит текст, который несовместим с набором символов Windows-1252
Ниже мой PDF файл Prawn для создания имени в 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 not compatible with the Windows-1252 character set.
If you need full UTF-8 support, use TTF fonts instead of PDF built-in fonts.
Я уже использую шрифт TTF, который поддерживает символы в этом имени, что я могу сделать, чтобы правильно напечатать имя?
Ответы
Ответ 1
Это швы Турецкий отсутствует в 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")
...
И fun link, которая связана не только с набором символов, но и с другими различиями в интернализации для Турции.
Изменить 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'))
Ответ 2
Из этого anwser о Принудительные строки к UTF-8 из любой кодировки:
"Форсировать" кодировку легко, однако она не преобразует символы просто измените кодировку:
str = str.force_encoding("UTF-8")
str.encoding.name # => 'UTF-8'
Если вы хотите выполнить преобразование, использовать кодировку
В самом деле, как сказал @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'),
Ответ 3
Я не уверен, что помню, как работает Креветка, но файлы PDF не поддерживают UTF-8, которая по умолчанию является строкой Ruby для объектов String.
Фактически, файлы PDF поддерживают только кодировку ASCII с использованием внутренних шрифтов - для любой другой кодировки требуется, чтобы вы принесли свой собственный шрифт (который также рекомендуется для переносимости).
Обходным путем является либо использование карт символов (CMaps) - либо пользовательских CMaps, либо заранее определенных (шрифт BYO).
Как правило, файлы PDF включают встроенный шрифт (или подмножество шрифта) и CMap, отображающий значение байта (или нескольких байтов) в желаемый глиф шрифта. то есть отображение 97, которое является "а" в ASCII, к значению глифа при использовании указанного шрифта.
В прошлый раз, когда я использовал Prawn, я думаю, что он поддерживал шрифты TTF и автоматически создавал карты шрифтов, используя строки UTF-8 для ввода текста, но вам нужно загрузить соответствующий шрифт в креветку и не забудьте использовать его!.
Вы можете увидеть пример в этом ответе.
Удачи!
ИЗМЕНИТЬ
Я обновил ответ, чтобы отразить комментарии @mkl.
@mkl указал, что другие кодировки поддерживаются или возможны (шрифт BYO), включая предопределенную некоторую многобайтовую кодировку (в которой используются предопределенные CMaps).