WkHTMLtoPDF Unicode Issue

Я уже прочитал несколько похожих сообщений в Stackru, и ни одна из них не смогла решить мою проблему.

Проблема

У меня есть PDF, который генерируется WkHTMLtoPDF, который содержит Unicode RIGHT SINGLE QUOTATION MARK (U + 2019 или ) персонаж. Вывод в браузере, вывод выглядит следующим образом:

рабочее изображение - в браузере

Когда я запускаю это через WkHTMLtoPDF, я получаю следующее:

неудачное изображение - в wkhtmltopdf

Код

Я использую следующее для моего CSS:

@font-face {
    font-family: localGeorgia;
    src: url("file:///usr/share/fonts/truetype/georgia/GEORGIA.TTF");
}

body {
    overflow: visible !important;
    font-family: localGeorgia, Georgia, Times, "Times New Roman", serif;
    font-size: 12px;
}

Я также скопировал шрифт Georgia со своего локального компьютера на сервер (в /usr/share/fonts/truetype/georgia/ каталог) и я побежал fc-cache -fv очистить кэш шрифтов и запустить fc-list чтобы проверить это Georgia был правильно установлен. localGeorgia Семейство шрифтов было добавлено в качестве формальности, потому что я все еще не получал рабочий дисплей

Через онлайн-документы и карту символов моей операционной системы я подтвердил, что шрифт Georgia поддерживает RIGHT SINGLE QUOTATION MARK (см. ниже), хотя я не знаю, как окончательно доказать, что этот глиф находится в файле TrueType (я не знаком с открытием или анализом файлов TrueType)

Карта символов Windows для шрифта Georgia

На данный момент мне неясно, почему WkHTMLtoPDF отображает этот беспорядок символов вместо правильного символа Юникода

Дополнительные детали (среда и т. Д.)

Я использую Ubuntu 16.04

Laravel версия 5.3

Я использую Laravel-Snappy версии 0.3.3 (которая использует KNP-Snappy версии 0.4.3)

Мой конфиг для Snappy довольно прост:

<?php
return array(
    'pdf' => array(
        'enabled' => true,
        'binary'  => base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'),
        'timeout' => false,
        'options' => array(),
        'env'     => array(),
    ),
    'image' => array(
        'enabled' => false,
        'binary'  => '/usr/local/bin/wkhtmltoimage',
        'timeout' => false,
        'options' => array(),
        'env'     => array(),
    ),
);

Установленная версия wkhtmltopdf - 0.12.3 (с исправленным qt).

Для создания PDF я звоню ->render() на View, передавая это PDF::loadHTMLпотом звоню ->inline() на результат и возвращая ответ. Вот минимальный пример того, как я генерирую PDF:

$property = Property::find(1);
$view = View::make("pdf.flier")->with(["property" => $property]);
$pdf = PDF::loadHTML($view->render())->inline();
return response($pdf)->header("application/pdf")->header("Content-Disposition", "attachment; filename=flier.pdf");

HTML невероятно прост:

<html>
<head>
    <base href="{{ url("/") }}" />
    <link rel="stylesheet" type="text/css" href="css/flier.css" />
</head>
<body>
    <img src="{{ $property->image }}" />
    <h1>{{ $property->title }}</h1>
</body>
</html>

CSS дает h1 абсолютная позиция над изображением

1 ответ

Решение

Через пару дней я наконец понял это

Вопрос не в шрифте. Если бы это произошло, я бы увидел, что глиф не загружается (например, вместо символа Юникод появится поле или знак вопроса)

Вместо этого я вижу, что вместо нужного символа юникода появляются несколько неправильных символов. Это указывает на проблему с кодировкой, а не на проблему со шрифтом. WkHTMLtoPDF интерпретирует 3-байтовый символ Unicode как 3 отдельных 1-байтовых символа ASCII

Проблема в том, что мой браузер имеет кодировку по умолчанию UTF-8, а WkHTMLtoPDF - нет (по крайней мере, в версии 0.12.3). Исправление было простым: обновить мой конфигурационный файл

<?php
return array(
    'pdf' => array(
        'enabled' => true,
        'binary'  => base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'),
        'timeout' => false,
        'options' => array(
            'encoding' => 'utf-8'
        ),
        'env'     => array(),
    ),
    'image' => array(
        'enabled' => false,
        'binary'  => '/usr/local/bin/wkhtmltoimage',
        'timeout' => false,
        'options' => array(
            'encoding' => 'utf-8'
        ),
        'env'     => array(),
    ),
);

Примечание. В своем исследовании я обнаружил, что некоторые люди, утверждающие, что опция "--encoding" не работает для них, однако добавление тега meta charset в HTML сработало:

<meta charset="utf-8">
Другие вопросы по тегам