dompdf 字符编码 UTF-8

问题描述 投票:0回答:12

我正在尝试使用正确的字符创建 pdf,但有“?”字符。 我创建了一个测试 php 文件,我试图在其中寻找最佳解决方案。如果我在浏览器中打开 html,我看起来没问题

UTF-8 --> UTF-8 : X Ponuka číslo € černý Češký 

但是当我查看 pdf 时,我看到了这个

UTF-8 --> UTF-8 : X Ponuka ?íslo € ?erný ?ešký 

这是我的所有代码:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>č s š Š</title>
</head>
<body>
<?php 

require_once("dompdf/dompdf_config.inc.php");
$tab = array("UTF-8", "ASCII", "Windows-1250", "ISO-8859-2", "ISO-8859-1", "ISO-8859-6", "CP1256"); 
$chain = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <style></style><title>č s š Š</title></head><body>';
foreach ($tab as $i) 
    { 
        foreach ($tab as $j) 
        { 
            $chain .= "<br> $i --> $j : ".iconv($i, $j, 'X Ponuka číslo € černý Češký <br>'); 
        } 
    } 
$chain .= '<p style="font-family: firefly, verdana, sans-serif;">??????X Ponuka číslo € černý Češký <br></p></body></html>';
echo $chain; 
echo 'X Ponuka číslo € černý Češký <br>'; 

$filename = 'pdf/_1.pdf';
$dompdf = new DOMPDF();
$dompdf->load_html($chain, 'UTF-8');
$dompdf->set_paper('a4', 'portrait'); // change these if you need to
$dompdf->render();
file_put_contents($filename, $dompdf->output());

?> 
</body>
</html>

我做错了什么?我尝试了很多我发现的选项:(有什么想法吗?

php utf-8 character-encoding dompdf
12个回答
54
投票

您应该再次阅读Unicode How-to。主要问题是您没有指定支持您的字符的字体。您似乎已经阅读了操作方法,因为您正在使用该文档中的字体示例。然而,该示例并不意味着全局适用于任何文档,dompdf 默认情况下不包含 firefly(一种汉字字体)或 Verdana。

如果您没有指定字体,那么 dompdf 将回退到仅支持 Windows ANSI 编码的核心字体之一(Helvetica、Times Roman、Courier)。因此,请务必使用支持 Unicode 编码并具有您需要显示的字符的字体来设置文本样式。

在 dompdf 0.6.0 中,您可以使用附带的 Deja Vu 字体。所以以下应该可以工作(只是 HTML):

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style>
  body { font-family: DejaVu Sans, sans-serif; }
</style>
<title>č s š Š</title>
</head>
<body>
  <p>??????X Ponuka číslo € černý Češký <br></p>
</body>
</html>

43
投票

我使用此组合得到了 UTF-8 字符。 在将 html 传递给 DOMpdf 之前,请使用以下命令隐藏编码:

$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');

在你的CSS中使用DejaVu字体

*{ font-family: DejaVu Sans; font-size: 12px;}

确保您已在 HTML

<head>
标签中设置 utf-8 编码

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

现在所有特殊字符都可以使用“ľ š č ť ž ý á í é”


27
投票

仅添加

  <style>
    *{ font-family: DejaVu Sans !important;}
  </style>

之前

</head>
它对我有用。


3
投票

Dompdf 不支持后备字体,因此如果您喜欢的字体不支持您的字符,您就无法使用它,并且您也无法将其他字体设置为像

droid sans fallback
这样的字符的后备字体。

您可以做的是利用正则表达式 unicode 脚本范围:https://www.regular-expressions.info/unicode.html将这些文本块包装到跨度中并为它们提供后备字体。

示例:

$body = 'test 简化字 彝語/彝语 test číslo € černý Češký';

$cjk_scripts = 'Bopomofo|Han|Hiragana|Katakana';
$cjk_scripts = preg_replace('/[a-zA-Z_]+/', '\\p{$0}', $cjk_scripts);

// wrap the CJK characters into a span with it's own font
$body = preg_replace("/($cjk_scripts)+/isu", '<span class="cjk">$0</span>', $body);

// a font that supports CJK characters
$cjk_font_path = APP_PATH.'/fonts/DroidSansFallbackFull.ttf';

$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style type="text/css">
@font-face {
    font-family: 'DroidSansFallbackFull';
    font-style: normal;
    font-weight: 400;
    src: url('$cjk_font_path') format('truetype');
}
body {
    font-family: DejaVu Sans, sans-serif;;
}
.cjk {
    font-family: DroidSansFallbackFull, sans-serif;
}
</style>
</head>
<body>$body</body>
</html>
HTML;

$dompdf = new \DOMPDF();
$dompdf->set_paper('A4');
$dompdf->load_html($html);
$dompdf->render();

$dompdf->stream('test.pdf', ['Attachment'=>0]);

相关:https://github.com/dompdf/dompdf/issues/1508


2
投票

utf8_decode() 为我解决了一些德语翻译问题,比如 ä 和 ü。

echo utf8_decode('X Ponuka číslo € černý Češký <br>');

1
投票

上述答案对我没有任何帮助。经过几个小时的努力,我切换到 niklasravnsborg/laravel-pdf 具有几乎完全相同的语法和用法,并且一切正常。


1
投票

如果您不介意只有一种字符集,您可以更改

dompdf_font_family_cache.dist.php

中的每个字符集

就像

一样
<?php
$distFontDir = $rootDir . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR;
return array(
    'sans-serif' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'times' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'times-roman' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'courier' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'helvetica' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'zapfdingbats' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'symbol' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'serif' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'monospace' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'fixed' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'dejavu sans' =>
    array(
        'bold' => $distFontDir . 'DejaVuSans-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSans-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSans-Oblique',
        'normal' => $distFontDir . 'DejaVuSans'
    ),
    'dejavu sans mono' =>
    array(
        'bold' => $distFontDir . 'DejaVuSansMono-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSansMono-BoldOblique',
        'italic' => $distFontDir . 'DejaVuSansMono-Oblique',
        'normal' => $distFontDir . 'DejaVuSansMono'
    ),
    'dejavu serif' =>
    array(
        'bold' => $distFontDir . 'DejaVuSerif-Bold',
        'bold_italic' => $distFontDir . 'DejaVuSerif-BoldItalic',
        'italic' => $distFontDir . 'DejaVuSerif-Italic',
        'normal' => $distFontDir . 'DejaVuSerif'
    )
)
?>

我知道这不是最好的方法,但它节省了很多时间


1
投票

中文字符有时会引起问题。 重要的是要有好的字体这里是您可以下载的列表。

我选择了第一个名为“Kai Bold Font”的字体,这是一个下载页面

然后将其放在托管服务的公共文件夹中。我把它放进去

http://192.168.10.10/fonts/pdf/wts11.ttf

这是我的 html 示例

$html = <<<EOT
<!DOCTYPE html>
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <style>
    @font-face {
      font-family: chinese;
        src: url('http://192.168.10.10/fonts/pdf/wts11.ttf') format('truetype');
    }
    .chineseLanguage { font-family: chinese; }
      body {font-family: DejaVu Sans, sans-serif;}
   </style>
</head>
<body>
    Chinese
    <div class='chineseLanguage'>
        忠烈祠
        中文 - 这工作<br> 
    </div>
    hello world <br> 
    Russian - русский текст <br>
    Greek - α,β,γ,δ,ε <br>
    chars - !@#$%^&* -=- €   <br><br>
    <br>
    Hebrew (iw)<br><br>
    דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה<br>
    <br>    
</body>
</html>
EOT;

PS。您很有可能需要这套:

ini_set("allow_url_fopen", true);

0
投票

我遇到了类似的问题,最终使用了tcpdf。希望这会有所帮助。 http://www.tcpdf.org/
问题是我使用的字体。我能够使用此字体“freeserif”获得正确的输出。我想使用此字体与 dompdf 可能会获得相同的输出。

$pdf->SetFont('freeserif', '', 12);

这是我使用过的示例。 tcpdf utf-8 示例

<?php
header('Content-type: text/html; charset=UTF-8') ;//chrome
require_once('tcpdf_include.php');

// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

$pdf->setFontSubsetting(true);

$pdf->SetFont('freeserif', '', 12);

$pdf->AddPage();

$utf8text = '
<html><head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>
<b>Ponuka číslo € černý Češký </b></br>
සිංහල  </br>
<u>தேமல </u> </br>
</body></html>';

$pdf->SetTextColor(0, 63, 127);

$pdf->writeHTML($utf8text, true, 0, true, true);

$pdf->Output('example_008.pdf', 'I');

?>

0
投票

我也遇到了同样的问题,而且解决得很简单。 只需在生成 HTML 时使用的 CSS 文件中导入具有所需语言子集的 google 字体即可。在 HTML 文件中指定 utf-8 并且它正在工作...

@import url('https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin-ext');
body {font-family: 'Roboto', sans-serif;}

0
投票

这里有很多答案,很难找到可靠的跨语言支持。我相信对于我们这些制作分布式软件的人来说,还有一些服务器设置块可以阻止某些功能,例如 pdfdom 中的

@import
src:url()
自动嵌入字体。

以下解决方案已在许多服务器和本地托管站点上运行,并且不需要命令行访问:

  1. 检索您想要用作 .ttf 的字体(对于语言支持,包括西里尔文、希腊语、梵文、拉丁语和越南语,我们使用 Noto Sans 并选中所有可选语言)
  2. 运行/内置以下脚本并仅触发 PDFBuilder_install_font_family() 一次(单个安装)

PDFBuilder_install_font_family()
的要点:https://gist.github.com/woodyhayday/f8dc36cc7ec922bc1894f33eb2b0e928


0
投票

您可以使用选项:

use Dompdf\Dompdf;
use Dompdf\Options;

    $options = new Options();
    $options->set('isHtml5ParserEnabled', true);
    $options->set('isPhpEnabled', true);
    $options->set('isPhpEnabled', true);
    $options->set('isHtml5ParserEnabled', true);
    $options->set('isPhpEnabled', true);


    $dompdf = new Dompdf($options);
    $dompdf->set_option('isHtml5ParserEnabled', true);
    $dompdf->set_option('isPhpEnabled', true);
    $dompdf->set_option('isHtml5ParserEnabled', true);
    $dompdf->set_option('isPhpEnabled', true);

    $dompdf->loadHtml($message);
    $dompdf->setHttpContext('utf8');
© www.soinside.com 2019 - 2024. All rights reserved.