Проблема с Юникодом в WkHTMLtoPDF

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

Проблема

У меня есть PDF-файл, созданный WkHTMLtoPDF, который содержит символ юникода 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 отображает этот беспорядок символов вместо правильного глифа Unicode.

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

Я использую 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() в представлении, передаю его 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 абсолютную позицию над изображением.


person stevendesu    schedule 08.04.2018    source источник


Ответы (1)


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

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

Вместо этого я вижу несколько неправильных глифов вместо желаемого символа Юникода. Это указывает на проблему кодировки, а не шрифта. WkHTMLtoPDF интерпретирует 3-байтовый символ Юникода как 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" не работает для них, однако добавление метатега кодировки в HTML помогло:

<meta charset="utf-8">
person stevendesu    schedule 11.04.2018
comment
Я тоже это нашел! Добавление: <meta http-equiv="Content-type" content="text/html; charset=utf-8" /><meta charset="UTF-8" /> исправил проблему для меня - person Kerwin Sneijders; 30.10.2018