BookStack PDF 导出中文乱码解决

BookStack 存在一个 Bug,即导出中文 PDF 文件乱码。

相关源码如下:

protected function htmlToPdf($html)
{
    $containedHtml = $this->containHtml($html);
    $useWKHTML = config('snappy.pdf.binary') !== false;
    if ($useWKHTML) {
        $pdf = \SnappyPDF::loadHTML($containedHtml);
        $pdf->setOption('print-media-type', true);
    } else {
        $pdf = \DomPDF::loadHTML($containedHtml);
    }
    return $pdf->output();
}

可见 snappy 权重较高 ,不过根据 snappy.pdff.binary 配置信息:

return [
    'pdf' => [
        'enabled' => true,
        'binary'  => file_exists(base_path('wkhtmltopdf')) ? base_path('wkhtmltopdf') : env('WKHTMLTOPDF', false),
        'timeout' => false,
        'options' => [],
        'env'     => [],
    ],
    'image' => [
        'enabled' => false,
        'binary'  => '/usr/local/bin/wkhtmltoimage',
        'timeout' => false,
        'options' => [],
        'env'     => [],
    ],
];

从 Env 中加载 WKHTMLTOPDF 变量,不过在 docker-entrypoint.yml 文件中 并没有配置相关的环境变量

所以默认就是 DomPDF 导出,然而 DomPDF 解决中文乱码比较麻烦,所以这里的解决方案是添加 wkhtmltopdf 依赖 使用 snappyPDF 导出。

因为 BookStack base 镜像中并没有安装中文字体,所以在添加 wkhtmltopdf 之前先安装中文字体的支持:

RUN apt-get update && apt-get install -y --force-yes git zlib1g-dev libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libpng-dev wget libldap2-dev libtidy-dev libfontconfig1 libxrender1 fontconfig fonts-droid-fallback fonts-noto-cjk

这里是修改好的 docker-bookstack 项目,clone 下来就可使用: https://github.com/justpsvm/docker-bookstack

相关项目

https://github.com/BookStackApp/BookStack
https://github.com/barryvdh/laravel-snappy
https://wkhtmltopdf.org/