tFPDF 生成一个空的 pdf 文件
tFPDF generates an empty pdf file
我正在尝试使用 tFPDF 库在 PHP 中生成 PDF 文件。我从 FPDF 开始,它工作正常,只是 UTF-8 字符出现乱码。经过一番搜索,我发现可以实现 tFPDF 以在 PDF 文件中包含 UTF-8 字符。但是我所有的尝试都导致了一个无法打开的空文件--0 KB 文件写入我的硬盘驱动器,当我双击它时出现 "There's a problem with the file format" 消息。这是我的代码。我在错误日志中没有收到 PHP 错误,因此很难判断出了什么问题。
protected function getPDFFileData($diagnosis_id)
{
define('FPDF_FONTPATH', JPATH_COMPONENT.'/helpers/font/');
require_once JPATH_COMPONENT.'/helpers/tfpdf.php';
//require_once JPATH_COMPONENT.'/helpers/fpdf.php';
$item = $this->getItem($diagnosis_id);
$pdf = new tFPDF('P', 'mm', 'Letter');
//$pdf = new FPDF('P', 'mm', 'Letter');
$pdf->AddPage();
$fontname = "dejavusans";
$pdf->AddFont($fontname, '', 'DejaVuSans.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->SetFont($fontname, '', 10);
/* $fontname = "helvetica";
$pdf->AddFont($fontname, '', 'helvetica.php');
$pdf->AddFont($fontname, 'B', 'helveticab.php');
$pdf->AddFont($fontname, 'I', 'helveticai.php');
$pdf->SetFont($fontname, '', 10); */
$domain_header = "Domain".chr(160).($item->ordinal).".".chr(160).($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class".chr(160).($item->domain_class_ordinal).".".chr(160).($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 1, 'R');
$pdf->Ln();
$pdf->SetFont($fontname, '', 10);
$domain_class_info = "Domain".chr(160).($item->ordinal).chr(160).chr(183).chr(160)."Class".chr(160).($item->domain_class_ordinal).chr(160).chr(183).chr(160)."Diagnosis Code".chr(160).($item->diagnosis_code);
$pdf->Cell(40, 6, $domain_class_info);
$pdf->Ln();
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label);
$pdf->Ln();
// More code that generates more text . . .
return $pdf->Output('S');
}
添加新字体需要两个步骤:
- 生成字体定义文件
- 脚本中的字体声明
对于您的情况,我们需要生成字体定义文件。比如我们可以使用命令行:
~/w/t/fpdf181> php makefont/makefont.php font/dejavu-sans/DejaVuSans.ttf cp1252
Font file compressed: DejaVuSans.z
Font definition file generated: DejaVuSans.php
添加字体
$fontname = "DejaVuSans";
$pdf->AddFont($fontname, '', 'DejaVuSans.php', true);
http://www.fpdf.org/en/tutorial/tuto7.htm
[编辑]
根据您的评论,您使用了库 http://www.fpdf.org/en/script/script92.php
1) Dejavu 已添加到 tfpdf/font/unifont
文件夹。而且,名字应该是
$fontname = 'DejaVu';
2) 如果我们要添加自定义字体文件夹,我们需要重写_SYSTEM_TTFONTS
// Optionally define the filesystem path to your system fonts
// otherwise tFPDF will use [path to tFPDF]/font/unifont/ directory
// define("_SYSTEM_TTFONTS", "C:/Windows/Fonts/");
tfpdf/tfpdf.php
if (defined("_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS.$file ))
{
$ttffilename = _SYSTEM_TTFONTS . $file ;
}
else {
$ttffilename = $this->_getfontpath().'unifont/'.$file ;
}
我创建了一个示例测试:
<?php
// Optionally define the filesystem path to your system fonts
// otherwise tFPDF will use [path to tFPDF]/font/unifont/ directory
//define("_SYSTEM_TTFONTS", "font/dejavu-sans/");
require "tfpdf.php";
$pdf = new tFPDF('P', 'mm', 'Letter');
$pdf->AddPage();
//Example object data
/** @var StdClass $item */
$item = new StdClass();
$item->ordinal = 'Item Ordinal';
$item->domain_label = "Item Domain Label";
$item->domain_class_ordinal = "Item Domain Class Ordinal";
$item->class_label = 'Item Class Label';
$item->diagnosis_code = 'Item Diagnosis Code';
$item->diagnosis_label = 'Item Diagnosis Label';
// Add a Unicode font (uses UTF-8)
$fontname = 'DejaVu';
$pdf->AddFont($fontname,'','DejaVuSans.ttf',true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->SetFont('DejaVu','',14);
$domain_header = "Domain".chr(160).($item->ordinal).".".chr(160).($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class".chr(160).($item->domain_class_ordinal).".".chr(160).($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetFont($fontname, '', 10);
$domain_class_info = "Domain".chr(160).($item->ordinal).chr(160).chr(183).chr(160)."Class".chr(160).($item->domain_class_ordinal).chr(160).chr(183).chr(160)."Diagnosis Code".chr(160).($item->diagnosis_code);
$pdf->Cell(40, 6, $domain_class_info);
$pdf->Ln(10);
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label);
$pdf->Ln(10);
$pdf->Output('S');
这就是最终对我有用的东西。我不得不删除对 PHP 函数 chr() 的所有调用,并对 ASCII 集之外的字符使用特定的 UTF-8 语法(例如,'\u2022' 表示项目符号字符)。我相信我找到了在这些字符上使用 json_decode() 函数以在 Whosebug 上的某处呈现所需输出的技巧。我还发现我无法通过参数 'S' 到 return 字符串调用 Output() 函数得到结果,因此我使用文件名参数将输出写入服务器上的文件。这是修改后的功能。
protected function getPDFFileData($diagnosis_id, $output_file_name)
{
define('FPDF_FONTPATH', JPATH_COMPONENT.'/helpers/fpdf181/font/');
require_once JPATH_COMPONENT.'/helpers/fpdf181/tfpdf.php';
$item = $this->getItem($diagnosis_id);
$pdf = new tFPDF('P', 'mm', 'Letter');
$pdf->AddPage();
$fontname = "DejaVu";
$pdf->AddFont($fontname, '', 'DejaVuSans.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->SetFont($fontname, '', 10);
$bullet_char_uni = '\u2022';
$bullet_char = json_decode('"'.$bullet_char_uni.'"');
$domain_header = "Domain ".($item->ordinal).". ".($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class ".($item->domain_class_ordinal).". ".($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 0, 'R');
$pdf->Ln();
$pdf->SetFont($fontname, '', 10);
$diagnosis_code = "Domain ".($item->ordinal)." ".$bullet_char." Class ".($item->domain_class_ordinal)." ".$bullet_char." Diagnosis Code ".($item->diagnosis_code);
$pdf->Cell(40, 6, $diagnosis_code, 0, 1, 'L');
$pdf->Ln();
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label, 0, 1, 'L');
// More code that generates more text . . .
$output = $pdf->Output($output_file_name);
return $output;
}
我正在尝试使用 tFPDF 库在 PHP 中生成 PDF 文件。我从 FPDF 开始,它工作正常,只是 UTF-8 字符出现乱码。经过一番搜索,我发现可以实现 tFPDF 以在 PDF 文件中包含 UTF-8 字符。但是我所有的尝试都导致了一个无法打开的空文件--0 KB 文件写入我的硬盘驱动器,当我双击它时出现 "There's a problem with the file format" 消息。这是我的代码。我在错误日志中没有收到 PHP 错误,因此很难判断出了什么问题。
protected function getPDFFileData($diagnosis_id)
{
define('FPDF_FONTPATH', JPATH_COMPONENT.'/helpers/font/');
require_once JPATH_COMPONENT.'/helpers/tfpdf.php';
//require_once JPATH_COMPONENT.'/helpers/fpdf.php';
$item = $this->getItem($diagnosis_id);
$pdf = new tFPDF('P', 'mm', 'Letter');
//$pdf = new FPDF('P', 'mm', 'Letter');
$pdf->AddPage();
$fontname = "dejavusans";
$pdf->AddFont($fontname, '', 'DejaVuSans.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->SetFont($fontname, '', 10);
/* $fontname = "helvetica";
$pdf->AddFont($fontname, '', 'helvetica.php');
$pdf->AddFont($fontname, 'B', 'helveticab.php');
$pdf->AddFont($fontname, 'I', 'helveticai.php');
$pdf->SetFont($fontname, '', 10); */
$domain_header = "Domain".chr(160).($item->ordinal).".".chr(160).($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class".chr(160).($item->domain_class_ordinal).".".chr(160).($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 1, 'R');
$pdf->Ln();
$pdf->SetFont($fontname, '', 10);
$domain_class_info = "Domain".chr(160).($item->ordinal).chr(160).chr(183).chr(160)."Class".chr(160).($item->domain_class_ordinal).chr(160).chr(183).chr(160)."Diagnosis Code".chr(160).($item->diagnosis_code);
$pdf->Cell(40, 6, $domain_class_info);
$pdf->Ln();
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label);
$pdf->Ln();
// More code that generates more text . . .
return $pdf->Output('S');
}
添加新字体需要两个步骤:
- 生成字体定义文件
- 脚本中的字体声明
对于您的情况,我们需要生成字体定义文件。比如我们可以使用命令行:
~/w/t/fpdf181> php makefont/makefont.php font/dejavu-sans/DejaVuSans.ttf cp1252
Font file compressed: DejaVuSans.z
Font definition file generated: DejaVuSans.php
添加字体
$fontname = "DejaVuSans";
$pdf->AddFont($fontname, '', 'DejaVuSans.php', true);
http://www.fpdf.org/en/tutorial/tuto7.htm
[编辑]
根据您的评论,您使用了库 http://www.fpdf.org/en/script/script92.php
1) Dejavu 已添加到 tfpdf/font/unifont
文件夹。而且,名字应该是
$fontname = 'DejaVu';
2) 如果我们要添加自定义字体文件夹,我们需要重写_SYSTEM_TTFONTS
// Optionally define the filesystem path to your system fonts
// otherwise tFPDF will use [path to tFPDF]/font/unifont/ directory
// define("_SYSTEM_TTFONTS", "C:/Windows/Fonts/");
tfpdf/tfpdf.php
if (defined("_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS.$file ))
{
$ttffilename = _SYSTEM_TTFONTS . $file ;
}
else {
$ttffilename = $this->_getfontpath().'unifont/'.$file ;
}
我创建了一个示例测试:
<?php
// Optionally define the filesystem path to your system fonts
// otherwise tFPDF will use [path to tFPDF]/font/unifont/ directory
//define("_SYSTEM_TTFONTS", "font/dejavu-sans/");
require "tfpdf.php";
$pdf = new tFPDF('P', 'mm', 'Letter');
$pdf->AddPage();
//Example object data
/** @var StdClass $item */
$item = new StdClass();
$item->ordinal = 'Item Ordinal';
$item->domain_label = "Item Domain Label";
$item->domain_class_ordinal = "Item Domain Class Ordinal";
$item->class_label = 'Item Class Label';
$item->diagnosis_code = 'Item Diagnosis Code';
$item->diagnosis_label = 'Item Diagnosis Label';
// Add a Unicode font (uses UTF-8)
$fontname = 'DejaVu';
$pdf->AddFont($fontname,'','DejaVuSans.ttf',true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->SetFont('DejaVu','',14);
$domain_header = "Domain".chr(160).($item->ordinal).".".chr(160).($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class".chr(160).($item->domain_class_ordinal).".".chr(160).($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetFont($fontname, '', 10);
$domain_class_info = "Domain".chr(160).($item->ordinal).chr(160).chr(183).chr(160)."Class".chr(160).($item->domain_class_ordinal).chr(160).chr(183).chr(160)."Diagnosis Code".chr(160).($item->diagnosis_code);
$pdf->Cell(40, 6, $domain_class_info);
$pdf->Ln(10);
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label);
$pdf->Ln(10);
$pdf->Output('S');
这就是最终对我有用的东西。我不得不删除对 PHP 函数 chr() 的所有调用,并对 ASCII 集之外的字符使用特定的 UTF-8 语法(例如,'\u2022' 表示项目符号字符)。我相信我找到了在这些字符上使用 json_decode() 函数以在 Whosebug 上的某处呈现所需输出的技巧。我还发现我无法通过参数 'S' 到 return 字符串调用 Output() 函数得到结果,因此我使用文件名参数将输出写入服务器上的文件。这是修改后的功能。
protected function getPDFFileData($diagnosis_id, $output_file_name)
{
define('FPDF_FONTPATH', JPATH_COMPONENT.'/helpers/fpdf181/font/');
require_once JPATH_COMPONENT.'/helpers/fpdf181/tfpdf.php';
$item = $this->getItem($diagnosis_id);
$pdf = new tFPDF('P', 'mm', 'Letter');
$pdf->AddPage();
$fontname = "DejaVu";
$pdf->AddFont($fontname, '', 'DejaVuSans.ttf', true);
$pdf->AddFont($fontname, 'B', 'DejaVuSans-Bold.ttf', true);
$pdf->AddFont($fontname, 'I', 'DejaVuSans-Oblique.ttf', true);
$pdf->SetFont($fontname, '', 10);
$bullet_char_uni = '\u2022';
$bullet_char = json_decode('"'.$bullet_char_uni.'"');
$domain_header = "Domain ".($item->ordinal).". ".($item->domain_label);
$pdf->Cell(90, 6, $domain_header, 0, 0, 'L');
$class_header = "Class ".($item->domain_class_ordinal).". ".($item->class_label);
$pdf->Cell(90, 6, $class_header, 0, 0, 'R');
$pdf->Ln();
$pdf->SetFont($fontname, '', 10);
$diagnosis_code = "Domain ".($item->ordinal)." ".$bullet_char." Class ".($item->domain_class_ordinal)." ".$bullet_char." Diagnosis Code ".($item->diagnosis_code);
$pdf->Cell(40, 6, $diagnosis_code, 0, 1, 'L');
$pdf->Ln();
$pdf->SetFont($fontname, '', 14);
$pdf->Cell(40, 8, $item->diagnosis_label, 0, 1, 'L');
// More code that generates more text . . .
$output = $pdf->Output($output_file_name);
return $output;
}