Itextsharp: Экспорт греческих букв в PDF? [Дубликат]

Вопрос был:

Как вернуть ответ от асинхронного вызова?

, который может быть интерпретирован как:

Как сделать синхронный асинхронный код синхронным?

Решение будет состоять в том, чтобы избежать обратных вызовов и использовать комбинацию Promises и async / await.

Я хотел бы привести пример для запроса Ajax.

(Хотя он может быть записан в Javascript, я предпочитаю писать его на Python и компилировать его в Javascript, используя Transcrypt . Это будет достаточно ясно.)

Позволяет сначала включить использование JQuery, чтобы $ был доступен как S:

__pragma__ ('alias', 'S', '$')

Определить функцию, которая возвращает Promise, в этом случае вызов Ajax:

def read(url: str):
    deferred = S.Deferred()
    S.ajax({'type': "POST", 'url': url, 'data': { },
        'success': lambda d: deferred.resolve(d),
        'error': lambda e: deferred.reject(e)
    })
    return deferred.promise()

Использовать асинхронный код, как если бы он был синхронным:

async def readALot():
    try:
        result1 = await read("url_1")
        result2 = await read("url_2")
    except Exception:
        console.warn("Reading a lot failed")

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 23 August 2018 в 20:06
поделиться
Другие вопросы по тегам:

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