FPDF utf-8编码(HOW-TO)


80

有人知道如何将FPDF软件包中的编码设置为utf-8吗?或至少是支持希腊字符的ISO-8859-7(希腊文)?

基本上我想创建一个包含希腊字符的pdf文件。

任何建议都会有所帮助。乔治


如果要使用更多语言,则需要UTF8,因此可以使用tFPDF。看一下composer软件包
robsch

Answers:


117

不要使用UTF-8编码。标准FPDF字体使用ISO-8859-1或Windows-1252。它可以执行转换为ISO-8859-1有utf8_decode()$str = utf8_decode($str); 但一些字符,如欧元将无法正确翻译。如果可以使用iconv扩展名,则正确的方法如下: $str = iconv('UTF-8', 'windows-1252', $str);


21
我认为这不会有所帮助。您的答案确实说明了如何使用ISO-8859-1或Windows-1252编码生成PDF,但是这些编码不适用于非拉丁语言。更不用说输出多语言(多脚本)文本了。
ТомицаКораћ

3
@Rafiq:请不要在我的答案中使用“旧的” FPDF,而要使用较新的UTF8版本tFPDF。
Tarsis 2015年

1
注意:使用ISO-8859-1时,€字符将不起作用(字符集中没有欧元符号,请改用ISO-8859-15)。
BurninLeo 2015年

1
@BurninLeo:ISO-8859-15并不是更好,所有这些编码都具有相同的字符限制,因此-15具有€,但是缺少´或½。唯一真正的解决方案是使用UTF-8而不是避免使用它-如我的回答所示。
Tarsis

3
tFPDF确实支持unicode,但是3年来一直没有更新,因为FPDF最近才更新,因此tFPDF已经过时了。使用tFPDF时请记住这一点。
Agilis

38

还有FPDF的正式UTF-8版本,称为tFPDF http://www.fpdf.org/en/script/script92.php

您可以轻松地从原始FPDF切换,只需确保还使用unicode字体(如上面链接中的示例所示)或我的代码即可:

<?php

//this is a UTF-8 file, we won't need any encode/decode/iconv workarounds

//define the path to the .ttf files you want to use
define('FPDF_FONTPATH',"../fonts/");
require('tfpdf.php');

$pdf = new tFPDF();
$pdf->AddPage();

// Add Unicode fonts (.ttf files)
$fontName = 'Helvetica';
$pdf->AddFont($fontName,'','HelveticaNeue LightCond.ttf',true);
$pdf->AddFont($fontName,'B','HelveticaNeue MediumCond.ttf',true);

//now use the Unicode font in bold
$pdf->SetFont($fontName,'B',12);

//anything else is identical to the old FPDF, just use Write(),Cell(),MultiCell()... 
//without any encoding trouble
$pdf->Cell(100,20, "Some UTF-8 String");

//...
?>

我认为使用此方法而不是在各处都散布utf8_decode()更为优雅,并且直接在AddFont()中使用.ttf文件的功能也是有好处的。

这里的任何其他答案只是避免或解决问题的一种方法,对于最新项目,避免UTF-8并不是真正的选择。

还有其他替代方案,例如基于FPDF的mPDF或TCPDF(及其他),但提供高级功能,具有UTF-8支持并可以解释HTML代码(当然,由于没有直接方法将HTML转换为PDF,因此存在局限性)。大多数FPDF代码都可以直接在这些库中使用,因此迁移代码非常容易。

https://github.com/mpdf/mpdf http://www.tcpdf.org/


1
iconv和解码解决方案都无法用于更特殊的字符(♠♥☺äκόσμος)。但是,如果仅用tpdf.php文件替换fpdf.php,则所有文件都将开始工作,并且文件会变小,这是额外的好处。伟大的修复。
塞巴斯蒂安

1
FPDF和tFPDF是独立的分支吗?有人知道tFPDF在FPDF页面上隐藏得如此之好的原因吗?有什么缺点,切换之前应该知道吗?
BurninLeo

1
我很确定为什么他们没有将其设置为默认的FPDF版本,但直接将其链接到fpdf.org主页上,并且如前所述,tFPDF的功能最初是为mPDF开发的。我在生产环境中将tFPDF用于许多PDF,我认为除了UTF-8和字体更改外,它都是100%相同。从来没有任何问题。
Tarsis

1
tFPDF是脚本或FPDF的扩展。它被认为已过时(3年前更新),因为FPDF已更新。tFPDF的作者未对其进行维护,并且未涉及与tFPDF相关的GitHub。参见:github.com/rev42/tfpdf
Agilis

只要您不需要更多功能,我就不会看到问题,因为最近一次(次要)更新是在4个月前-仍然比不支持UTF-8好。无论哪种方式,我都会使用TCPDF或mPDF,它们既基于FPDF,又提供高级功能,还支持HTML代码。
Tarsis

27

对于这个问题,有一个非常简单的解决方案。

在文件fpdf.php中,转到以下行:

if($txt!=='')
{

在我的fpdf版本中是648行。插入以下代码行:

$txt = iconv('utf-8', 'cp1252', $txt);

(在代码行上方)

if($align=='R')

这适用于所有德语特殊字符,也应适用于希腊特殊字符。否则,只需将cp1252替换为所需的相应字母即可。您可以在此处查看所有受支持的字符:http : //en.wikipedia.org/wiki/Windows-1252

我在这里看到了解决方案:http : //fudforum.org/forum/index.php?t=msg&goto=167345 请使用上面的示例代码,因为原始作者忘记在utf和8之间插入破折号。

希望以上内容对您有所帮助。

大安


完美,将FPDF更新到支持PHP7以正确显示特殊字符的版本后,这仍然有效或仍然需要。
阿伦

1
该命令对我有用,$ txt = iconv('utf-8','cp1252',$ txt); Thks
Patrick Arguello

只是惊人的simpel解决方案。
令人遗憾的

这改变了我的间距-现在有些线断了。但是至少它似乎有效-在土耳其语字母对我完全无效之前,现在至少我看到了一些东西。
Cold_Class

9

您需要首先生成一种字体。您必须使用MakeFontFPDF软件包中包含的实用程序。我在Linux上使用了演示中的一些扩展脚本:

<?php
// Generation of font definition file for tutorial 7
require('../makefont/makefont.php');

$dir = opendir('/usr/share/fonts/truetype/ttf-dejavu/');
while (($relativeName = readdir($dir)) !== false) {
    if ($relativeName == '..' || $relativeName == '.')
        continue;
    MakeFont("/usr/share/fonts/truetype/ttf-dejavu/$relativeName",'ISO-8859-2');
}
?>

然后,我将生成的文件复制到font我的网站目录中,并使用此文件:

$pdf->Cell(80,70, iconv('UTF-8', 'ISO-8859-2', 'Buňka jedna'),1);

(我在一张桌子上工作。)这对我的语言很有用(Buňkajedna代表Cell One的捷克语)。捷克语属于中欧语言,也属于ISO-8859-2。遗憾的是,FPDF的用户被迫失去UTF-8编码的优势。您无法在PDF中获得此文件:

Městečko Fruens Bøge

丹麦字母ø成为řISO-8859-2。

解决方案的建议:您需要获取希腊字体,使用正确的编码(ISO-8859-7)生成字体,并使用iconv与生成该字体相同的目标编码。





4

您可以制作一个类来扩展FPDF并添加以下内容:

class utfFPDF extends FPDF {

function Cell($w, $h=0, $txt="", $border=0, $ln=0, $align='', $fill=false, $link='')
{
    if (!empty($txt)){
        if (mb_detect_encoding($txt, 'UTF-8', false)){
            $txt = iconv('UTF-8', 'ISO-8859-5', $txt);

        }
    }
    parent::Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);

} 

}


4

我想为任何出于某种原因(框架集成等)而没有切换到TFPDF的人回答这个问题

转到:http : //www.fpdf.org/makefont/index.php

.ttf为您要使用的语言使用兼容的字体。确保选择适合您的语言的编码编号。下载文件并将其粘贴到当前的FPDF字体目录中。

使用它来激活新字体: $pdf->AddFont($font_name,'','Your_Font_Here.php');

然后就可以$pdf->SetFont正常使用了。

在字体本身上,使用iconv转换为UTF-8。因此,例如,如果您使用希伯来语,则可以这样做iconv('UTF-8', 'windows-1255', $first_name)

将Windows编码号替换为您的语言编码。

从右到左,快速修复方法是执行strrev(iconv('UTF-8', 'windows-1255', $first_name))


3

只需编辑fpdf.php文件中的函数单元格,查找如下所示的行

function cell ($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = false, $link = '')
{ 

找到线之后

后写的{

$txt = utf8_decode($txt);

保存文件并准备就绪,口音和utf8编码将起作用:)


3

如何在FPDF中创建支持中文,日语,俄语等的PDF?

(下面正在使用的代码快照)

我想提供:问题摘要,解决方案,带有工作代码的github项目以及带有预期结果PDF的在线示例。

问题 :

  1. 如Tarsis所述,将FPDF交换为TFPDF。
  2. 实际上,您需要一种支持所用UTF-8字符的字体。

    IE,仅使用Helvetica并尝试显示日语将无法正常工作。如果使用Font Forge或其他字体工具,则可以滚动到该字体的中文字符,然后看它们为空白。

    Google的字体(Noto font)包含所有语言,它的大小为20mb,通常这是您的文本大小的几个因素。因此,您会看到为什么许多字体不能完全覆盖每种语言。

解决方案 :

我使用的是日语和汉语的rounded-mgenplus-20140828.ttf和ZCOOL_QingKe_HuangYou.ttf字体包,它们是开源的,可以在许多开源项目中找到。在tFPDF本身或它的新继承类中class HTMLtoPDF extends tFPDF {...},您将执行此操作...

$this->AddFont('japanese', '', 'rounded-mgenplus-20140828.ttf', true);
$this->SetFont('japanese', '', 14);
$this->Write(14, '日本語');

应该没什么了!

GitHub上的代码包:

https://github.com/HoldOffHunger/php-html-to-pdf

日语在线工作演示:

https://www.earthfluent.com/privacy.pdf?language=ja


1

对于后代。

我如何在Linux机器上将俄语添加到fpdf:

1)转到http://www.fpdf.org/makefont/,然后使用ISO-8859-5编码将ttf字体(例如,AerialRegular.ttf)转换为2个文件:AeroRegular.php和AeroRegular.z

2)将这两个文件放入fpdf / font目录

3)在您的代码中使用它:

$pdf = new \FPDI();
    $pdf->AddFont('ArialMT','','ArialRegular.php');
    $pdf->AddPage();
    $tplIdx = $pdf->importPage(1);
    $pdf->useTemplate($tplIdx, 0, 0, 211, 297); //width and height in mms
    $pdf->SetFont('ArialMT','',35);
    $pdf->SetTextColor(255,0,0);
    $fullName = iconv('UTF-8', 'ISO-8859-5', 'Алексей');
    $pdf->SetXY(60, 54);
    $pdf->Write(0, $fullName);



0

您可以在文本上应用此功能:

 $yourtext = iconv('UTF-8', 'windows-1252', $yourtext);

谢谢


0

我将FPDF用于ASP,并且iconv函数不可用。似乎很奇怪,我在AddPage()函数之后,通过在pdf中添加伪图像(1x1px jpeg)解决了UTF-8问题:

pdf.Image "images/fpdf.jpg",0,0,1

这样,重音字符已正确添加到我的pdf中,不要问我为什么,但是它可以工作。


0

不知道它是否适用于希腊文,但是对于巴西葡萄牙语字符我也遇到了同样的问题,我的解决方案是使用html实体。我基本上有两种情况:

  1. 字符串可能包含UTF-8字符。

对于这些,我首先使用将其编码为html实体,htmlentities()然后将其解码为iso-8859-1。例:

$s = html_entity_decode(htmlentities($my_variable_text), ENT_COMPAT | ENT_HTML401, 'iso-8859-1');
  1. 带有html实体的固定字符串:

对于这些,我只是忽略htmlentities()了。例:

$s = html_entity_decode("Treasurer/Tr&eacute;sorier", ENT_COMPAT | ENT_HTML401, 'iso-8859-1');

然后,我传递$s到FPDF,如以下示例所示:

$pdf->Cell(100, 20, $s, 0, 0, 'L');

注意:ENT_COMPAT | ENT_HTML401是参数2的标准值,如http://php.net/manual/en/function.html-entity-decode.php

希望能有所帮助。


0

我知道这个问题很旧,但是我认为我的回答会对没有其他答案的人有所帮助。因此,我的问题是我无法在PDF中显示克罗地亚字符。首先,我使用了FPDF,但我认为它不支持Unicode。最后,解决我问题的是tFPDF,它是支持Unicode的FPDF版本。这是为我工作的示例:

require('tFPDF/tfpdf.php');
$pdf = new tFPDF();
$pdf->AddPage();
$pdf->AddFont('DejaVu','','DejaVuSansCondensed.ttf',true);
$pdf->AddFont('DejaVu', 'B', 'DejaVuSansCondensed-Bold.ttf', true);

$pdf->SetFont('DejaVu','',14);

$txt = 'čćžšđČĆŽŠĐ';
$pdf->Write(8,$txt);

$pdf->Output();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.