lmoreli/laravel-pdf
Composer 安装命令:
composer require lmoreli/laravel-pdf
包简介
Modern PDF generation library for Laravel with multiple digital signatures support. Built on top of TCPDF with a fluent PHP 8.3+ API.
README 文档
README
Modern PDF generation library for Laravel with multiple digital signatures support. Built on PHP 8.3+ with a fluent API on top of TCPDF.
✨ Features
- 🎯 Fluent PHP 8.3+ API — Typed properties, enums, readonly classes, named arguments
- ✍️ Multiple Digital Signatures — Sign PDFs with two or more certificates (certification + approval)
- 📄 Full PDF Generation — Text, tables, images, HTML, barcodes, QR codes
- 🎨 HTML to PDF — Convert HTML/CSS content including tables and styles
- 🔧 Laravel Integration — Service Provider, Facade, config, Blade views
- 📊 Barcodes — QR Code, Code 128, EAN-13, DataMatrix, PDF417
- 🔒 Document Security — Encryption, password protection, permissions
- 🌐 Unicode — Full Unicode support (UTF-8, RTL, CJK)
- 📝 Certificate Support — PFX/P12, PEM, and file-based certificates
📦 Installation
composer require lmoreli/laravel-pdf
Laravel Auto-Discovery
The service provider and facade are auto-registered via Laravel's package discovery.
Publish Config (Optional)
php artisan vendor:publish --tag=laravelpdf-config
🚀 Quick Start
Basic PDF
use LMoreli\LaravelPDF\PDFDocument; $pdf = PDFDocument::create() ->setTitle('My Document') ->addPage() ->setFont('helvetica', 'B', 16) ->cell(0, 10, 'Hello World!', 0, 1, 'C') ->lineBreak(10) ->setFont('helvetica', '', 12) ->multiCell(0, 0, 'This is a paragraph of text.', align: 'J') ->save('/path/to/output.pdf');
From HTML
$pdf = PDFDocument::fromHTML('<h1>Hello</h1><p>World!</p>') ->save('/path/to/output.pdf');
Using Laravel Facade
use LMoreli\LaravelPDF\Facades\PDF; // In a controller: public function downloadReport() { $pdf = PDF::fromView('pdfs.report', ['data' => $reportData]); return $pdf->response('report.pdf'); }
From Blade View
$pdf = PDFDocument::fromView('pdfs.invoice', [ 'invoice' => $invoice, 'items' => $items, ]); return $pdf->response('invoice.pdf', inline: false); // Force download
✍️ Digital Signatures
Single Signature
use LMoreli\LaravelPDF\Support\Certificate; use LMoreli\LaravelPDF\Signature\SignatureAppearance; $certificate = Certificate::fromPFX('/path/to/certificate.pfx', 'password'); $pdf = PDFDocument::create() ->addPage() ->writeHTML('<h1>Signed Document</h1>') ->addCertificationSignature( certificate: $certificate, appearance: SignatureAppearance::at(x: 15, y: 250, width: 80, height: 20, page: 1), info: [ 'Name' => 'John Doe', 'Reason' => 'Document certification', 'Location' => 'São Paulo, Brazil', ], ) ->save('/path/to/signed.pdf');
Dual Signatures (Key Feature! 🔑)
use LMoreli\LaravelPDF\Support\Certificate; use LMoreli\LaravelPDF\Signature\SignatureAppearance; use LMoreli\LaravelPDF\Enums\CertificatePermission; // Load two different certificates $cert1 = Certificate::fromPFX('/path/to/cert1.pfx', 'pass1'); $cert2 = Certificate::fromPFX('/path/to/cert2.pfx', 'pass2'); $pdf = PDFDocument::create() ->addPage() ->writeHTML($contractHTML) ->addDualSignatures( firstCertificate: $cert1, secondCertificate: $cert2, firstAppearance: SignatureAppearance::at( x: 15, y: 250, width: 80, height: 20, page: 1, name: 'Signature - Company', ), secondAppearance: SignatureAppearance::at( x: 105, y: 250, width: 80, height: 20, page: 1, name: 'Signature - Director', ), firstInfo: [ 'Name' => 'Company ABC', 'Reason' => 'Contract certification', ], secondInfo: [ 'Name' => 'John Director', 'Reason' => 'Contract approval', ], ) ->save('/path/to/dual-signed.pdf');
Signatures with Config Profiles
In config/laravelpdf.php:
'signatures' => [ 'certificates' => [ 'company' => [ 'type' => 'pfx', 'path' => storage_path('certs/company.pfx'), 'password' => env('PDF_CERT_COMPANY_PASSWORD'), ], 'director' => [ 'type' => 'pfx', 'path' => storage_path('certs/director.pfx'), 'password' => env('PDF_CERT_DIRECTOR_PASSWORD'), ], ], ],
Usage:
$certManager = app('laravelpdf.certificates'); $companyCert = $certManager->get('company'); $directorCert = $certManager->get('director'); $pdf->addDualSignatures($companyCert, $directorCert);
📊 Barcodes & QR Codes
// QR Code $pdf->qrCode('https://example.com', x: 10, y: 50, size: 40); // Code 128 $pdf->code128('ABC-12345', x: 10, y: 100, w: 60, h: 15); // EAN-13 $pdf->ean13('7891234567890', x: 10, y: 130); // DataMatrix $pdf->dataMatrix('Hello World', x: 10, y: 160, size: 30); // PDF417 $pdf->pdf417('Large data content...', x: 10, y: 200);
📋 Tables
Programmatic Table
$pdf->table( headers: ['Name', 'Email', 'Role'], rows: [ ['Alice', 'alice@example.com', 'Admin'], ['Bob', 'bob@example.com', 'User'], ['Carol', 'carol@example.com', 'Editor'], ], widths: [50, 80, 50], options: [ 'headerBg' => [41, 86, 219], 'headerColor' => [255, 255, 255], 'altRowBg' => [240, 245, 255], ], );
HTML Table
$pdf->htmlTable(' <table border="1" cellpadding="4"> <tr><th>Col 1</th><th>Col 2</th></tr> <tr><td>A</td><td>B</td></tr> </table> ');
🎨 Drawing & Graphics
// Lines $pdf->line(10, 50, 200, 50); // Rectangles $pdf->rect(10, 60, 50, 30, 'DF'); // Draw + Fill // Rounded rectangles $pdf->roundedRect(10, 100, 80, 40, 5); // Circles $pdf->circle(50, 160, 20); // Transparency $pdf->setAlpha(0.5);
📄 Headers & Footers
Callback-Based
$pdf->setHeaderCallback(function ($pdf) { $pdf->setFont('helvetica', 'B', 10) ->setTextColorHex('#666666') ->cell(0, 10, 'My Company - Confidential', 'B', 1, 'C'); }); $pdf->setFooterCallback(function ($pdf) { $pdf->setFont('helvetica', 'I', 8) ->cell(0, 10, 'Page ' . $pdf->getPage(), 'T', 0, 'C'); });
Simple Header
$pdf->setSimpleHeader('Company Name', 'Document Title', '/path/to/logo.png', 30);
🔒 Document Protection
$pdf->setProtection( permissions: ['print', 'copy'], userPass: 'user123', ownerPass: 'owner456', mode: 2, // AES-128 );
🔧 Configuration
Certificate Types
// From PFX/P12 file $cert = Certificate::fromPFX('/path/to/cert.pfx', 'password'); // From PEM files $cert = Certificate::fromFiles( certPath: '/path/to/cert.pem', keyPath: '/path/to/key.pem', password: 'key-password', ); // From PEM strings $cert = Certificate::fromPEM($certPEM, $keyPEM, $password); // Validate $cert->validate(); // Throws on invalid echo $cert->getSubjectName(); echo $cert->isValid() ? 'Valid' : 'Expired';
Output Options
// Save to file $pdf->save('/path/to/output.pdf'); // Get as string $content = $pdf->toString(); // Get as base64 $base64 = $pdf->toBase64(); // Stream inline to browser $pdf->stream('document.pdf'); // Force download $pdf->download('document.pdf'); // Laravel HTTP response return $pdf->response('document.pdf', inline: true);
📁 Project Structure
LaravelPDF/
├── composer.json
├── config/
│ └── laravelpdf.php # Laravel config
├── src/
│ ├── PDFDocument.php # Main class (fluent API)
│ ├── LaravelPDFServiceProvider.php
│ ├── Enums/
│ │ ├── CertificatePermission.php
│ │ ├── OutputDestination.php
│ │ ├── PageFormat.php
│ │ ├── PageOrientation.php
│ │ ├── SignatureType.php
│ │ └── Unit.php
│ ├── Exceptions/
│ │ ├── PDFException.php
│ │ └── SignatureException.php
│ ├── Facades/
│ │ └── PDF.php
│ ├── Signature/
│ │ ├── DigitalSignature.php # Signature config DTO
│ │ ├── IncrementalPDFSigner.php # Core signing engine
│ │ ├── MultiSignatureManager.php # Multi-sig orchestrator
│ │ └── SignatureAppearance.php # Visual positioning
│ ├── Support/
│ │ ├── Certificate.php # Certificate wrapper
│ │ ├── CertificateManager.php # Config-based profiles
│ │ ├── ExtendedTCPDF.php # TCPDF bridge
│ │ └── TimestampAuthority.php # RFC 3161 TSA
│ └── Traits/
│ ├── ManagesBarcodes.php
│ ├── ManagesContent.php
│ ├── ManagesFonts.php
│ ├── ManagesHeaders.php
│ ├── ManagesHTML.php
│ ├── ManagesImages.php
│ ├── ManagesMetadata.php
│ ├── ManagesPages.php
│ ├── ManagesSignatures.php
│ └── ManagesTables.php
├── examples/
│ ├── 01_basic.php
│ ├── 02_html_to_pdf.php
│ ├── 03_dual_signatures.php
│ └── 04_laravel_controller.php
└── tests/
🔬 How Multi-Signature Works
LaravelPDF implements multiple digital signatures using PDF Incremental Updates, the standard mechanism defined in the PDF specification (ISO 32000):
-
First Signature (Certification): The initial PDF is generated and signed normally using PKCS#7 detached signatures. This sets the DocMDP permissions.
-
Second Signature (Approval): The already-signed PDF is appended with an incremental update containing:
- A new signature field (widget annotation)
- A new signature dictionary with ByteRange placeholder
- Updated AcroForm fields array
- Updated page annotations
- New xref table and trailer pointing to the previous one
-
Integrity: Each signature covers all bytes of the PDF up to that point (except its own signature placeholder), so previous signatures remain valid.
┌────────────────────────┐
│ Original PDF Content │ ← Signed by Certificate 1
│ %%EOF │
├────────────────────────┤
│ Incremental Update │ ← Signed by Certificate 2
│ (new sig field, xref) │
│ %%EOF │
└────────────────────────┘
📋 Requirements
- PHP 8.3 or higher
- OpenSSL extension
- Laravel 10, 11, or 12 (for Laravel integration)
📄 License
MIT License. See LICENSE for details.
🤝 Credits
- Built on top of TCPDF
- Created by Lucas Moreli
lmoreli/laravel-pdf 适用场景与选型建议
lmoreli/laravel-pdf 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「pdf」 「TCPDF」 「laravel」 「certificate」 「pkcs7」 「digital-signature」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 lmoreli/laravel-pdf 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 lmoreli/laravel-pdf 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 lmoreli/laravel-pdf 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
TCPDF is a PHP class for generating PDF documents and barcodes.
TCPDI is a PHP class for importing PDF to use with TCPDF
TCPDI is a PHP class for importing PDF to use with TCPDF
Modified version of TCPDF that includes option for setting barcode's bar width
Provides TCPDF integration for Symfony
Alfabank REST API integration
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 34
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-05