解决laravel-dompdf中文字体乱码显示问题

2,256 阅读4分钟

1、安装laravel-dompdf依赖。

Packagistpackagist.org/packages/ba…

composer require barryvdh/laravel-dompdf

2、配置config/app.php

// add the ServiceProvider to the providers array in config/app.php
// 添加到providers数组下
Barryvdh\DomPDF\ServiceProvider::class,
// Add this to your facades // 添加到aliases数组下
'PDF' => Barryvdh\DomPDF\Facade\Pdf::class,

3、创建view

  下载中文字体,这里我使用了msyh.ttf(微软雅黑)。

      在public目录下创建fonts目录并把下载好的字体复制到该目录下。

image.png

创建view:

<!DOCTYPE html>
<html>
    <head>
        <title>测试pdf</title>

        <style> 
            @font-face {
                font-family: 'msyh';
                font-style: normal;
                font-weight: normal;
                src: url({{ asset('fonts/msyh.ttf') }}) format('truetype');
             } 
            body {  font-family: 'msyh'  ;   }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="content">
                <div class="title">xiao{{$name}}</div>
            </div>
        </div>
    </body>
</html>

注意:引入字体,使用 @font-face,并通过【font-family: 'msyh';】应用到这个body上。

@font-face {
                font-family: 'msyh';
                font-style: normal;
                font-weight: normal;
                src: url(http://www.testpdf.com/fonts/msyh.ttf) format('truetype');
            }

 

4、创建controller

<?php

namespace AppHttpControllersApi;

use IlluminateHttpRequest;

use AppHttpRequests;
use AppHttpControllersController;

use PDF;

class PdfController extends Controller
{
    /**
     * 测试下载pdf,使用loadView()方法
     * @return mixed
     */
    public function testDownloadPdf()
    {
        $data = array('name'=>'宝bao');
        $pdf = PDF::loadView('invoice', $data);
        return $pdf->download('invoice.pdf');
    }

    /**
     * 测试web页面展示pdf,使用loadHTML()方法加载
     * @return mixed
     */
    public function testStreamPdf()
    {
        $html = '<html><head><title>Laravel</title><meta http-equiv='Content-Type' content='text/html; charset=utf-8'/><style>body{  font-family: 'msyh';  }  @font-face {  font-family: 'msyh';  font-style: normal;  font-weight: normal;  src: url(http://www.testenv.com/fonts/msyh.ttf) format('truetype');  }</style></head><body><div class='container'><div class='content'><p style='font-family: msyh, DejaVu Sans,sans-serif;'>献给母亲的爱</p><div style='font-family: msyh, DejaVu Sans,sans-serif;' class='title'>Laravel 5中文测试</div><div  class='title'>测试三</div></div></div></body></html>';
        $pdf = PDF::loadHTML($html);
         return $pdf->stream();
    }
    
}

 

问题1:

ErrorException in AdobeFontMetrics.php line 45:
fopen(D:workspacephptestpdfstoragefonts/b0a260823b52b90d6a99ba3a53e67e9f.ufm): failed to open stream: No such file or directory

解决方法:在storage下创建fonts文件夹

 

问题2:

FatalThrowableError in TableCell.php line 31:
Call to a member function get_cellmap() on null

解决方法:

更多解释请查看:github.com/barryvdh/la…

// 注释掉view中的这一行代码
display: table-cell;

 

参考资料github.com/dompdf/domp…

**
**

在 DOMPDF 中启用 Unicode 支持的指南(使用 CPDF 后端)

为了确保最大的兼容性,您应该遵循以下所有步骤。点击查看更多详细信息。

详细说明:

安装 dompdf 0.8.0 或更高版本

您需要 dompdf 0.8.0 或更高版本。在版本页面上查找最新版本的 dompdf 。

将支持您的字符的字体加载到 DOMPDF 中

为了正确显示文本,PDF 需要访问支持文档中使用的字符的字体。dompdf 包括 DejaVu 字体,它支持多种字符。如果 DejaVu 字体不支持文档中的字符,则任何 TrueType 字体都可以使用。

注意:dompdf 目前仅支持TrueType 字体。因此,在寻找字体时,请确保它采用 TrueType 格式。

目前有两种方法可以加载字体:

  • 使用 DOMPDF 中包含的 load_font.php 脚本
  • 使用 CSS @font-face 规则在运行时加载字体

使用 load_font.php 脚本

注意:load_font.php 脚本作为 dompdf-utils 项目的一部分进行维护。

load_font.php 依赖php-font-lib 来提取 dompdf 使用字体所需的信息。如果您按照 dompdf 安装说明进行操作,您应该已经拥有此库。

load_font.php 是一个命令行脚本,它不能通过您的网络服务器运行。该脚本接受以下参数:

  1. 字体的名称
  2. 正常变体 TTF 文件的路径
  3. 斜体变体 TTF 文件的路径
  4. 粗体变体 TTF 文件的路径
  5. 粗斜体变体 TTF 文件的路径

运行不带任何参数的 load_font.php 以查看帮助文本。

 > php load_font.php

Usage: load_font.php font_family [n_file [b_file] [i_file] [bi_file]]

... 

**
**

成功安装字体所需的只是正常变体。

举个例子,假设我们有一个名为 Firefly 的字体,位于 /home/fonts。要安装此字体,您需要进入 dompdf 安装目录并输入以下命令:

 > php load_font.php Firefly /home/fonts/firefly.ttf 

**
**

这将产生以下输出:

Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/fonts/firefly.ttf to /home/dompdf/lib/fonts/firefly.ttf...
Generating .afm for /home/dompdf/fonts/firefly.ttf...
?
Finished - font files created 

**
**

使用 CSS @font-face 规则在运行时加载字体

只要 dompdf 可以访问您要加载的字体,您就可以通过 CSS 轻松加载它。

 @font-face {
  font-family: 'Firefly'
  font-style: normal
  font-weight: normal;
  src: url(http://example.com/fonts/firefly.ttf) format('truetype');
} 

**
**

创建兼容的 HTML 文档

为了让 dompdf 正确解析您的文档,您必须让它知道使用的编码。为此,请在文档的头部放置一个指定编码的元标记。我们建议将文档编码为 UTF-8,以获得最大的兼容性。但是,只要安装 dompdf 的计算机支持指定的编码,您就应该能够使用其他编码。

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 

**
**

您还应该确保您的 html 编辑器使用您指定的编码。例如,如果您指定文档使用 UTF-8,但编辑器实际上使用 iso-8859-5 对文档进行编码,则文档的文本有可能会被破坏。此规则的一个例外是,无论文档编码如何,都应准确解析实体编码的字符。

在前面的示例中,我们将 Firefly 字体加载到 DOMPDF 安装中。这是使用该字体的示例文档:

 <html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
    <p style="font-family: firefly, DejaVu Sans, sans-serif;">献给母亲的爱</p>
</body>
</html> 

**
**

或者,如果您尚未加载字体,您可以将该@font-face 规则集成到 CSS 中:

 <html>
<head>
    <style>
        @font-face {
            font-family: 'Firefly';
            font-style: normal;
            font-weight: normal;
            src: url(http://example.com/fonts/firefly.ttf) format('truetype');
        }
    </style>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
    <p style="font-family: firefly, DejaVu Sans, sans-serif;">献给母亲的爱</p>
</body>
</html> 

**
**

当您设置要使用特定字体显示的文本块的样式时,该字体 必须支持该块中的所有字符。任何不受支持的字符通常会显示为未填充的方块。DOMPDF 不会尝试为不支持的字符查找替换字体。

**
**