ren1244 / pdfwriter
可扩展的PHP PDF库
Requires
- php: ^7.1.0
This package is auto-updated.
Last update: 2024-09-06 12:48:05 UTC
README
这是一个于2020年底新开发的PHP PDF库
*注意:这是一个预览版本,非正式发布,有些东西可能还会变动*
项目方向
- 支持全范围Unicode(现在很多PHP PDF函数库只支持到基本多文种平面)
- 至少支持TTF与OTF字体,或是更多种。
- 当字体缺字时,自动切换为候选字体。这可以达到英数与中文字采用不同字型的效果。
- 提供扩展的接口,让其他开发者根据需求扩展自己需要的模块。
安装
composer require ren1244/pdfwriter:dev-main
使用
以下是最简单的代码,只生成一个空白页面
$pdf = new PDFWriter; //建立 PDFWriter 物件 $pdf->addPage('A4'); //添加空白頁面 $pdf->output();
通过调用addPage方法可以不断地增加新的页面
※以下均以 $pdf
代表建立好的PDFWriter对象
新增页面
指定新增的页面大小,可以直接给予长宽
//新增寬 20 cm 高 15 cm 的頁面 $pdf->addPage(200, 150);
或是输入预先设定的纸张种类,目前可设定的值有:
- A 系列:
"A0"
到"A10"
- B 系列:
"B0"
到"B10"
- C 系列:
"C0"
到"C10"
- JIS-B 系列:
"JIS-B0"
到"JIS-B10"
//新增一張 A4 大小的頁面,預設是直向 $pdf->addPage('A4');
如果希望纸张是横向的,可以在预定的纸张种类后面加上 "L"
或 "H"
,意思分别是Landscape 与 Horizontal
//新增一張 A4 大小的頁面,橫向 $pdf->addPage('A4H');
输出PDF
默认是把pdf直接返回给用户,如果想先存储在服务器内的文件,可以在输出时指定一个file pointer resource
$fp = fopen('output.pdf', 'wb'); $pdf->output($fp); fclose($fp);
单位
当涉及到长度的参数时,若没有特别提及,都是指「目前选用的单位」(后面以「目前单位」简称)
默认状态下,「目前单位」被设置为 "mm"
,可以设置 PageMetrics::$unit
来改变它
允许设定的值有 "cm"
, "mm"
, "pt"
,设置其他值的的话都会视为 "pt"
// 把「目前單位」設定為 "cm" PageMetrics::$unit = "cm";
如果临时要把 pt 转换为「目前单位」
// 把 0.5 pt 轉換為「目前單位」 PageMetrics::getUnit(0.5);
如果临时要把「目前单位」转换为 pt
// 把 0.25 「目前單位」轉換 pt PageMetrics::getPt(0.25);
文字
$pdf = new PDFWriter; $pdf->addPage('A4'); // 添加字型(此時會自動設定目前字型為 Times-Roman 12pt) $pdf->font->addFont('Times-Roman'); // 設定字型(Times-Roman 14pt) $pdf->font->setFont('Times-Roman', 14); // 設定要寫入的矩形區域: left, top, width, height (單位是「目前單位」,此時是 mm) $pdf->text->setRect(10, 10, 100, 100); //寫入文字 $pdf->text->addText('Hello'); $pdf->output();
内置字体
上面的示例中的 $pdf->font->addFont('Times-Roman');
就是使用内置字体。
目前内置的字型有,包含一般的英数字元
Times-Roman
,Times-Bold
,Times-Italic
,Times-BoldItalic
Helvetica
,Helvetica-Bold
,Helvetica-Oblique
,Helvetica-BoldOblique
Courier
,Courier-Bold
,Courier-Oblique
,Courier-BoldOblique
自定义字体
通过script/addFont.php添加字体(产生的结果放在font文件夹)
php script/addFont.php {filename} [{outname}]
filename
: 字体文件outname
: 提供addFont
与setFont
使用的名称,若省略会自动根据字体文件产生
字体替代
这个功能是在字体缺字的情况下,允许自动切换替代的字型。
通过这个功能,可以让我们在英数字自动使用 Times-Roman
,而遇到中文自动使用 Noto-Sans
。
示例如下
$pdf->font->setFont([ 'Times-Roman' => 12, // 優先使用 Times-Roman 12pt 'Noto-Sans' => 14, // 如果缺字,用 Noto-Sans 14pt 替代 ]);
文字的排版
- 文字必须在由
setRect
指定的文字框内,如果空间不够会截断 - 目前不支持跨页,也就是每页的状态是独立的
addText
的第二个参数是一个可选参数,为一个关联数组,可以有以下选项
直书
此功能开发中,目前处理英文、数字与中文,其他语言会当作中文处理。
用 addTextV
写入直书文字
$pdf = new PDFWriter; $pdf->addPage('A4'); // 這邊用到自訂字型,請參考前面的說明 // 第二個參數設為 true 開啟直書功能 $pdf->font->addFont('SourceHanSansTC-Regular', true); // 設定字型(Times-Roman 14pt) $pdf->font->setFont('SourceHanSansTC-Regular', 14); // 設定要寫入的矩形區域: left, top, width, height (單位是「目前單位」,此時是 mm) $pdf->text->setRect(10, 10, 100, 100); // 用 addTextV 寫入直書文字 $pdf->text->addTextV("關關雎鳩,在河之洲。\n窈窕淑女,君子好逑。"); $pdf->output();
addTextV
的第二个参数是一个可选参数,为一个关联数组,可以有以下选项
图形
向量图(线条)
目前只能用postScript语言来画线条(跟svg有点像)
/** * 畫一條從 (10, 10) 到 (20, 30) 的直線,線寬是 1 pt * 這邊單位都是「目前單位」,所以指定線寬時使用 PageMetrics::getUnit */ $pdf->postscriptGragh->addPath('10 10 m 20 30 l S', PageMetrics::getUnit(1));
点阵图
目前支持的格式有 png
跟 jpeg
,其他格式要先转换一下
// 把 jpg 圖片畫在 ($x, $y) 的位置,長寬依照原本的尺寸 $pdf->image->addImage("example.jpg", $x, $y); // 把 png 圖片畫在 ($x, $y) 的位置,並指定長寬 $pdf->image->addImage("example.png", $x, $y, $width, $height); /** * 把 png 圖片畫在 ($x, $y) 的位置 * 當長寬只指定一個的時候,另一個請設定為 false,此時會等比例縮放 */ $pdf->image->addImage("example.png", $x, $y, false, $height);
若是已经取得图文件内容,可以使用 addImageRaw
方法,使用方法与 addImage
相同。
$imageContent = file_get_contents("example.png"); $pdf->image->addImageRaw($imageContent, $x, $y, $width, $height);
书签
简易书签
// 建立一個書籤,當點擊時會跳到第 2 頁,從頂部往下算 10 unit 的位置 $pdf->addOutline("第一章", 2, 10); /** * 建立一個書籤,當點擊時會跳到第 3 頁,從頂部往下算 10 unit 的位置 * 樣式被設定為「斜體 + 粗體」,顏色為紅色(#FF0000) */ $pdf->addOutline("第二章", 3, 10, Outline::ITALIC | Outline::BOLD, "FF0000");
多层级书签
// 紀錄 addOutline 回傳的值,這是一個 Outline 物件 $chapter1 = $pdf->addOutline("第一章", 2, 10); // Outline 物件本身也可以建立書籤,參數最多可以有 5 個,說明參考「簡易書籤」的部分 $chapter1->addOutline("第一節", 2, 15); // 若不指定第幾頁,則點擊後無任何效果,可以單純作為資料夾 $other = $pdf->addOutline("其他"); $other->addOutline("參考文件", 10, 10);
加密
目前支持 Aes256、Aes128、Rc4_128 三种加密,可参考 examples/ex3_encryption.php
扩展功能
在架构上,PDFWriter 分为三层:
- PDFWriter 核心:管理字体、页面等,并把字体和页面提供给 Cntent Module 开发使用。
- Cntent Module:通过 PDFWriter 提供的对象,负责产生页面的内容。
- 一般使用者:使用 PDFWriter + Cntent Module(s) 产生 PDF
关于如何建立 Cntent Module 可以参考:如何加入新的模块。
这边的只介绍自带的基本功能:字体、文字、线条、内嵌点阵图 如果只是产生报表应该还堪用
PS. 文字、线条的功能都是由 Cntent Module 实现,现阶段不会太深入高级功能的开发,而是通过提供接口给增加功能的灵活性。所以只提供最基础的功能。