contoweb/laravel-pdflib

Laravel 的 PDFLib 封装库,使创建 PDF 变得简单

v3.0.0 2024-05-23 12:53 UTC

This package is auto-updated.

Last update: 2024-09-23 13:37:57 UTC


README

Run tests StyleCI Latest Stable Version License

此包是 Laravel 对 PDFlib 的封装。它使得使用 PDFlib 生成高质量的(打印)PDF变得简单。PDFlib 是生成和操作 PDF 文件的领先开发工具箱。

PDFlib 本身仅限于演示目的免费使用。如果您想将其用于生产,则需要 PDFlib 许可证。

文档

需求

由于 PDFlib 比其他任何 PDF 生成器都强大得多,因此其 PHP 扩展需要注册。您可以直接从 PDFlib 下载 页面下载扩展文件。

如果您需要进一步安装 PDFlib 的帮助,请参阅 安装指南

您还需要

  • PHP: ^8.0
  • Laravel: ^9.0

请注意,只有受支持的 Laravel 版本才在测试工作流程中得到覆盖!

安装

使用 composer 安装此包。

composer require contoweb/laravel-pdflib

所有基本配置都在 pdf.php 配置文件中完成。要发布配置,运行供应商发布命令

php artisan vendor:publish --provider="Contoweb\Pdflib\PdflibServiceProvider"

然后您可以配置路径、测量单位等...

Laravel 5.5+

Laravel 5.5 使用包自动发现,因此不需要您手动添加 ServiceProvider。如果您不使用自动发现,请将 ServiceProvider 添加到 config/app.php 中的 providers 数组中。自 Laravel 11 以来,提供者的文件已更改为 bootstrap/providers.php。

Contoweb\Pdflib\PdflibServiceProvider::class,

如果您想使用 PDF 门面,请将其添加到 app.php 中的门面中

'Pdf' => Contoweb\Pdflib\Facades\Pdf::class,

使用

要创建新文档,可以使用 make:document 命令

php artisan make:document MarketingDocument

新文档文件可以在 app/Documents 目录中找到。

app\Documents\MarketingDocument

最后一步,生成 PDF 简单如

use App\Documents\MarketingDocument;
use Contoweb\Pdflib\Facades\Pdf;
use App\Http\Controllers\Controller;

class MarketingController extends Controller 
{
    public function storeDocument() 
    {
        return Pdf::store(new MarketingDocument, 'marketing.pdf');
    }
}

您可以在配置的导出路径中找到您的文档!但是首先,让我们看看如何编写简单的 PDF。

快速开始

在您的文档文件中,有一个样板方法 draw()

public function draw(Writer $writer)
{
    $writer->newPage();
    $writer->useFont('Arial', 12);
    $writer->writeText('Start something great...');
}

在这里您实际上编写文档的内容。如您所见,一个小示例已经是样板了

  1. 在文档中创建新页面。
  2. 使用从 fonts() 方法可用的字体。
  3. 编写文本。

创建页面

要创建新页面,您可以使用

$writer->newPage();

您可以通过传递参数来定义文档的宽度和高度。

$writer->newPage(210, 297); // A4 portrait format 

使用模板

在大多数情况下,您想在已设计的 PDF 上编写动态内容。要使用 PDF 模板,请使用 FromTemplate 关注并定义新的 template() 函数中的模板 PDF

namespace App\Documents;

use Contoweb\Pdflib\Concerns\FromTemplate;
use Contoweb\Pdflib\Concerns\WithDraw;
use Contoweb\Pdflib\Writers\PdfWriter as Writer;

class MarketingDocument implements FromTemplate, WithDraw
{
    public function template(): string {
        return 'template.pdf';
    }
    
    // ...

    public function draw(Writer $writer)
    {
        $writer->newPage()->fromTemplatePage(1);
    }
}

现在,您的第一页使用的是 template.pdf 的第 1 页。如您所见,您不需要定义页面大小,因为它使用的是模板的大小。不要忘记在配置文件中配置模板的位置。

预览和打印 PDF

如果您了解(专业)打印就绪的 PDF,您可能知道您的打印 PDF 与用户最终看到的不一样。

pdf-bleed

存在出血框、裁剪标记等。对于这种情况,您可以使用结合了 WithPreviewFromTemplate 的功能。虽然您的原始模板包含了所有框和标记,但您的预览PDF是最终文档的预览。

这需要您添加 previewTemplate()offset() 方法。

namespace App\Documents;

use Contoweb\Pdflib\Concerns\FromTemplate;
use Contoweb\Pdflib\Concerns\WithDraw;
use Contoweb\Pdflib\Concerns\WithPreview;
use Contoweb\Pdflib\Writers\PdfWriter as Writer;

class MarketingDocument implements FromTemplate, WithDraw, WithPreview
{
    public function template(): string {
        return 'print.pdf';
    }

    public function previewTemplate(): string
    {
        return 'preview.pdf';
    }

    public function offset(): array
    {
        return [
            'x' => 20,
            'y' => 20,
        ];
    }
    
    //
}

offset() 方法定义了从打印PDF到预览PDF的偏移量(见上图)。

现在您可以使用以下方法生成预览PDF:

return Pdf::inPreviewMode()->store(new MarketingDocument, 'marketing.pdf');

您还可以一步生成打印和预览PDF。

return Pdf::store(new MarketingDocument, 'marketing.pdf')->withPreview();

预览PDF将被自动命名为 <<name>>_preview.pdf。您可以通过传递名称在 ->withPreview('othername.pdf') 中覆盖此名称。

在页面上导航

为了告诉PDFlib您的元素应该放置在哪里,您必须设置“光标”的 XY 位置。

$writer->setPosition(10, 100);

// only X axis
$writer->setXPosition(10);

//only Y axis
$writer->setYPosition(100);

在配置文件中,您可以定义用于定位的度量单位。您可以选择 mmpt

注意:一开始可能会有些混乱,但PDFlib的Y轴是从底部测量的。所以位置0 0位于左下角,而不是左上角。

写入文本

要写入文本,您可以使用

$writer->writeTextLine('your text');

// or

$writer->writeText('your text');

别忘了设置光标位置并在写入文本之前使用正确的字体。由于该包扩展了PDFlib,您还可以将PDFlib选项作为第二个参数传递。

您只需在放置两个相邻文本块时使用 writeText。幕后,writeText() 使用PDFlib的 show() 方法,而 writeTextLine() 使用最常用的PDFlib方法 fit_text_line()

如果您想要转到下一行,而不是每次都重新定位光标,您可以使用

$writer->nextLine();

要使用1.0以外的自定义行间距,只需将其作为参数传递或使用以下方法设置行间距:

$writer->setLineSpacing(2.0);

字体

样板文档加载 Arial 作为示例字体,但我们没有在字体文件夹中提供字体文件。在这种情况下,PDFlib会尝试从您的宿主字体中加载它。您可能想使用自定义字体并确保您的服务器能够加载它。因此,强烈建议将字体文件(目前支持 .ttf 和 .otf)放置在您配置的字体位置(见 pdf.php 配置)中。

作为下一步,您必须使字体在您的文档中可用。对于TrueType字体,只需使用不带扩展名的文件名来自动加载字体

public function fonts(): array 
{
    return ['OpenSans-Regular'];
}

OpenSans-Regular.ttf 这样的基础字体文件必须存在于您的字体位置。

现在您可以通过其名称在文档中使用该字体

public function draw(Writer $writer)
{
    $writer->newPage();
    $writer->useFont('OpenSans-Regular', 12)
           ->writeText('This text is written with Open Sans font...');
}

您还可以覆盖默认字体编码和选项列表

public function fonts(): array
    {
        return [
            'OpenSans-Regular' => [
                'encoding' => 'ansi',
                'optlist' => ''
            ],
        ];
    }

颜色

如果您需要为文本着色,可以使用 WithColor 关注。这需要您定义自定义颜色

public function colors(): array
{
    return [
        'orange-rgb' => ['rgb', 255, 165, 0],
        'blue-cmyk' => ['cmyk', 100, 100, 0, 0],
    ];
}

您可以使用颜色

$writer->useColor('orange-rgb');

或者在使用字体时作为参数

$writer->useFont('OpenSans-Regular', 12, 'blue-cmyk');

表格

要编写表格,您可以遵循以下示例

$items = [
	['first_name' => 'John', 'last_name' => 'Doe'],
	['first_name' => 'Jane','last_name' => 'Doe'],
];

$table = $writer
	->setPosition(10, 150)
	->newTable($items);

$table
	->addColumn(50)
	->addColumn(50)
	->withHeader(['First name', 'Last name'])
	->place("stroke={ {line=horother linewidth=0}}")
;

图片

您可以使用以下方法放置图像

$writer->drawImage('/path/to/the/image.jpeg', 150, 100);

这将放置一个图像并将其调整大小为150x100。

由于在PDFlib中加载圆角图像只是一个痛苦的过程,您可以使用此方法

$writer->circleImage('/path/to/the/image.jpeg', 100);

PDFlib 函数

由于此包扩展了PDFlib,因此您可以使用整个PDFlib工具集。PDFlib 食谱 非常有帮助,甚至有助于理解此包。

扩展

此包只是包装PDFlib的基本起点。由于PDFlib提供了许多更多功能,我们不得不在开始时将重点放在最常用的函数上。

欢迎您提出PR想法!

自定义

如果您想在一个特定文档中使用除配置文件以外的文件系统磁盘/路径,可以使用以下关注点

  • Contoweb\Pdflib\Concerns\DifferentExportLocation:自定义导出位置
  • Contoweb\Pdflib\Concerns\DifferentFontsLocation:自定义字体位置
  • Contoweb\Pdflib\Concerns\DifferentTemplateLocation: 自定义模板位置

存储和路径的定义与配置文件中的方式相同

public function exportLocation(): array
{
	return [
		'disk' => 'other',
		'path' => null,
	];
}

public function fontsLocation(): array
{
	return [
		'disk' => 'other',
		'path' => 'custom-font-directory',
	];
}

public function templateLocation(): array
{
	return [
		'disk' => 'other',
		'path' => 'custom-template-directory',
	];
}

许可证

MIT许可(MIT)。更多详细信息请参阅许可文件