не может отобразить символ в pdf [дубликат]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

10
задан Bruno Lowagie 29 October 2014 в 15:38
поделиться

1 ответ

ПРОБЛЕМА:

Прежде всего, вы, кажется, не говорите о кириллических персонажах, а о центральных и восточноевропейских языках, которые используют латинский алфавит. Взгляните на разницу между кодовой страницей стр. 1250 и код страницы 1251 , чтобы понять, что я имею в виду. [ПРИМЕЧАНИЕ. Я обновил вопрос, чтобы он говорил о чешских персонажах, а не кириллице.]

Второе наблюдение. Вы пишете код, содержащий специальные символы:

"Testing of letters Č,Ć,Š,Ž,Đ"

Это плохая практика. Файлы кода хранятся в виде обычного текста и могут быть сохранены с использованием разных кодировок. Случайный переход от кодирования (например: путем загрузки его в систему управления версиями, использующую другую кодировку) может серьезно повредить содержимое вашего файла.

Вы должны написать код, который не содержит специальных символов , но которые используют разные обозначения. Например:

"Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110"

Это также гарантирует, что контент не будет изменен при компиляции кода с использованием компилятора, который ожидает другую кодировку.

Ваша третья ошибка что вы предполагаете, что Helvetica - это шрифт, который знает, как рисовать эти глифы. Это ложное предположение. Вы должны использовать файл шрифта, такой как Arial.ttf (или выбрать любой другой шрифт, который знает, как рисовать эти глифы).

Ваша четвертая ошибка заключается в том, что вы не вставляете шрифт. Предположим, что вы используете шрифт, который у вас есть на вашей локальной машине, и который может нарисовать специальные глифы, тогда вы сможете прочитать текст на своем локальном компьютере. Тем не менее, кто-то, кто получает ваш файл, но не имеет шрифта, который вы использовали на его локальной машине, возможно, не сможет правильно прочитать документ.

Ваша пятая ошибка заключается в том, что вы не определили кодировку

РЕШЕНИЕ:

Я написал небольшой пример, названный CzechExample что приводит к следующему PDF: czech.pdf

enter image description here [/g8]

Я добавил тот же текст дважды, но используя другой encoding:

public static final String FONT = "resources/fonts/FreeSans.ttf";
public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream(DEST));
    document.open();
    Font f1 = FontFactory.getFont(FONT, "Cp1250", true);
    Paragraph p1 = new Paragraph("Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110", f1);
    document.add(p1);
    Font f2 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, true);
    Paragraph p2 = new Paragraph("Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110", f2);
    document.add(p2);
    document.close();
}

Чтобы избежать вашей третьей ошибки, я использовал шрифт FreeSans.ttf вместо Helvetica. Вы можете выбрать любой другой шрифт, если он поддерживает символы, которые вы хотите использовать. Чтобы избежать вашей четвертой ошибки, я установил параметр embedded в true.

Что касается вашей пятой ошибки, я ввел два разных подхода.

В первом случае, Я сказал iText использовать кодовую страницу 1250.

Font f1 = FontFactory.getFont(FONT, "Cp1250", true);

Это вложит шрифт в качестве простого шрифта в PDF, что означает, что каждый символ в вашем String будет представленный с использованием одного байта . Преимущество такого подхода заключается в простоте; недостатком является то, что вы не должны начинать смешивать кодовые страницы. Например: это не будет работать для кириллических символов.

Во втором случае я сказал iText использовать Unicode для горизонтальной записи:

Font f2 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, true);

Это вложит шрифт как композитный шрифт в PDF, что означает, что каждый символ в вашем String будет представлен с использованием более одного байта . Преимущество такого подхода заключается в том, что это рекомендуемый подход в новых стандартах PDF (например, PDF / A, PDF / UA) и что вы можете смешивать кириллицу с латинским, китайским и японским и т. Д. Недостатком является то, что вы создайте больше байтов, но этот эффект ограничен тем, что потоки контента все равно сжаты.

Когда я распаковываю поток контента для текста в примере PDF, я вижу следующий синтаксис PDF:

enter image description here [/g9]

Как я уже говорил, для хранения текста первой строки используются одиночные байты. Двойные байты используются для хранения текста второй строки.

Вы можете быть удивлены, что эти символы выглядят ОК снаружи (при просмотре текста в Adobe Reader), но не соответствуют тому, что вы видите внутри (при просмотре второго снимка экрана), но вот как это работает.

ЗАКЛЮЧЕНИЕ:

Многие думают, что создание PDF тривиально, и что инструменты для создание PDF должно быть товаром. На самом деле это не всегда так просто: -)

22
ответ дан Bruno Lowagie 19 August 2018 в 08:49
поделиться
  • 1
    Я собираюсь добавить этот ответ в качестве дубликата для each & quot; Почему бы мне не получить символы ... в моем PDF & quot ;! – usr2564301 29 October 2014 в 22:41
  • 2
    @ Jongware У меня было ощущение, что я переусердствовал ;-) – Bruno Lowagie 30 October 2014 в 09:31
Другие вопросы по тегам:

Похожие вопросы: