Международный текст iTextSharp
У меня есть таблица на странице asp.net, и я пытаюсь экспортировать ее как файл PDF, у меня есть несколько международных символов, которые не отображаются в сгенерированном PDF файле, любые предложения,
Заранее спасибо
Ответы
Ответ 1
Ключ для правильного отображения наборов альтернативных символов (русский, китайский, японский и т.д.) заключается в использовании кодировки IDENTITY_H при создании BaseFont.
Dim bfR As iTextSharp.text.pdf.BaseFont
bfR = iTextSharp.text.pdf.BaseFont.CreateFont("MyFavoriteFont.ttf", iTextSharp.text.pdf.BaseFont.IDENTITY_H, iTextSharp.text.pdf.BaseFont.EMBEDDED)
IDENTITY_H обеспечивает поддержку юникода для выбранного шрифта, поэтому вы должны иметь возможность отображать практически любой символ. Я использовал его для русского, греческого и всех разных букв на европейском языке.
EDIT - 2013-May-28
Это также работает для версии 5.0 iTextSharp.
EDIT - 2015-июнь-23
Ниже приведен полный образец кода (в С#):
private void CreatePdf()
{
string testText = "đĔĐěÇøç";
string tmpFile = @"C:\test.pdf";
string myFont = @"C:\<<valid path to the font you want>>\verdana.ttf";
iTextSharp.text.Rectangle pgeSize = new iTextSharp.text.Rectangle(595, 792);
iTextSharp.text.Document doc = new iTextSharp.text.Document(pgeSize, 10, 10, 10, 10);
iTextSharp.text.pdf.PdfWriter wrtr;
wrtr = iTextSharp.text.pdf.PdfWriter.GetInstance(doc,
new System.IO.FileStream(tmpFile, System.IO.FileMode.Create));
doc.Open();
doc.NewPage();
iTextSharp.text.pdf.BaseFont bfR;
bfR = iTextSharp.text.pdf.BaseFont.CreateFont(myFont,
iTextSharp.text.pdf.BaseFont.IDENTITY_H,
iTextSharp.text.pdf.BaseFont.EMBEDDED);
iTextSharp.text.BaseColor clrBlack =
new iTextSharp.text.BaseColor(0, 0, 0);
iTextSharp.text.Font fntHead =
new iTextSharp.text.Font(bfR, 12, iTextSharp.text.Font.NORMAL, clrBlack);
iTextSharp.text.Paragraph pgr =
new iTextSharp.text.Paragraph(testText, fntHead);
doc.Add(pgr);
doc.Close();
}
Это скриншот создаваемого pdf файла:
![sample pdf]()
Важно помнить, что если выбранный вами шрифт не поддерживает символы, которые вы пытаетесь отправить в файл pdf, в iTextSharp ничего не изменится. Verdana красиво отображает персонажей из всех европейских шрифтов, о которых я знаю.
Другие шрифты могут не отображать столько символов.
Ответ 2
Есть две потенциальные причины, по которым символы не отображаются:
- Кодирование. Как отметил Stewbob, Identity-H - отличный способ избежать проблемы полностью, хотя для этого требуется встроить подмножество шрифта. Это имеет два последствия.
- Он увеличивает размер файла немного по невмешаемым шрифтам.
- Шрифт должен быть лицензирован для встроенных подмножеств. Большинство из них, некоторые нет.
- Шрифт должен содержать этот символ. Если вы попросите некоторые арабские лигатуры из кириллического (русского) шрифта, вероятность того, что он будет там, нехорошо. Есть очень мало шрифтов, которые охватывают различные языки, и они, как правило, ОГРОМНЫ. Самый большой/самый полный шрифт, с которым я столкнулся, был "Arial Unicode MS". Более 23 мегабайт.
Это еще одна веская причина требовать внедрения SUBSETS. Захват нескольких мегабайт, потому что вы хотели добавить пару китайских глифов, это немного круто.
Если вы чувствуете себя параноидальным, вы можете проверить свои строки против данного экземпляра BaseFont (который, как я полагаю, также учитывает кодировку) с помощью myBaseFont.charExists(someChar)
. Если у вас есть шрифт, в котором вы уверены, я бы не стал беспокоиться.
PS: Еще одна веская причина, по которой Identity-H требует встроенного подмножества. Identity-H считывает байты из потока контента в виде индексов Glyph. Порядок глифов может сильно отличаться от одного шрифта к другому или даже между версиями одного и того же шрифта. Опираясь на систему зрителей, чтобы ТОЧНЫЙ такой же шрифт был плохой идеей, поэтому его незаконный... особенно когда Acrobat/Reader начинает заменять шрифты, потому что он не смог найти точный шрифт, который вы просили, и вы его не вставляли.
Ответ 3
Вы можете попробовать установить кодировку шрифта, который вы используете. В Java будет что-то вроде этого:
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);
где BaseFont.CP1252 является кодировкой. Попробуйте выполнить поиск нужной кодировки для символов, которые будут отображаться.
Ответ 4
Он вызван по умолчанию шрифтом iTextSharp - Helvetica - который не поддерживает других, кроме базовых символов (или не поддерживает все остальные символы.
На самом деле есть 2 варианта:
- Один из них - это переписать содержимое таблицы вручную в код. Этот подход может выглядеть быстрее для вас, но для его повторения в коде также требуется любое изменение исходной таблицы (нарушение принципа DRY). В этом случае вы можете легко настроить шрифт по своему усмотрению.
- Другое - извлечь PDF из HTML, извлеченного из HtmlEngine. Это может звучать немного сложнее и сложнее (и это так), однако рабочее решение гораздо более гибкое и универсальное. Я немного пережил борьбу со специальными персонажами и решил опубликовать несколько полных решений в рамках другого подобного решения здесь, в stackoverflow: fooobar.com/info/397365/...