PHPackages                             lmoreli/laravel-pdf - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. lmoreli/laravel-pdf

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

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.

01↓50%PHP

Since Mar 4Pushed 2mo agoCompare

[ Source](https://github.com/llm1998/PDFMake)[ Packagist](https://packagist.org/packages/lmoreli/laravel-pdf)[ RSS](/packages/lmoreli-laravel-pdf/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)DependenciesVersions (1)Used By (0)

LaravelPDF
==========

[](#laravelpdf)

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
----------

[](#-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
--------------

[](#-installation)

```
composer require lmoreli/laravel-pdf
```

### Laravel Auto-Discovery

[](#laravel-auto-discovery)

The service provider and facade are auto-registered via Laravel's package discovery.

### Publish Config (Optional)

[](#publish-config-optional)

```
php artisan vendor:publish --tag=laravelpdf-config
```

🚀 Quick Start
-------------

[](#-quick-start)

### Basic PDF

[](#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

[](#from-html)

```
$pdf = PDFDocument::fromHTML('HelloWorld!')
    ->save('/path/to/output.pdf');
```

### Using Laravel Facade

[](#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

[](#from-blade-view)

```
$pdf = PDFDocument::fromView('pdfs.invoice', [
    'invoice' => $invoice,
    'items' => $items,
]);

return $pdf->response('invoice.pdf', inline: false); // Force download
```

✍️ Digital Signatures
---------------------

[](#️-digital-signatures)

### Single Signature

[](#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('Signed Document')
    ->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! 🔑)

[](#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

[](#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 &amp; QR Codes
-------------------------

[](#-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
--------

[](#-tables)

### Programmatic Table

[](#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

[](#html-table)

```
$pdf->htmlTable('

        Col 1Col 2
        AB

');
```

🎨 Drawing &amp; Graphics
------------------------

[](#-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 &amp; Footers
-----------------------

[](#-headers--footers)

### Callback-Based

[](#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

[](#simple-header)

```
$pdf->setSimpleHeader('Company Name', 'Document Title', '/path/to/logo.png', 30);
```

🔒 Document Protection
---------------------

[](#-document-protection)

```
$pdf->setProtection(
    permissions: ['print', 'copy'],
    userPass: 'user123',
    ownerPass: 'owner456',
    mode: 2,  // AES-128
);
```

🔧 Configuration
---------------

[](#-configuration)

### Certificate Types

[](#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

[](#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
-------------------

[](#-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
---------------------------

[](#-how-multi-signature-works)

LaravelPDF implements multiple digital signatures using **PDF Incremental Updates**, the standard mechanism defined in the PDF specification (ISO 32000):

1. **First Signature (Certification):** The initial PDF is generated and signed normally using PKCS#7 detached signatures. This sets the DocMDP permissions.
2. **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
3. **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
--------------

[](#-requirements)

- PHP 8.3 or higher
- OpenSSL extension
- Laravel 10, 11, or 12 (for Laravel integration)

📄 License
---------

[](#-license)

MIT License. See [LICENSE](LICENSE) for details.

🤝 Credits
---------

[](#-credits)

- Built on top of [TCPDF](https://github.com/tecnickcom/TCPDF)
- Created by Lucas Moreli

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance57

Moderate activity, may be stable

Popularity1

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1e322c4f91e376945df5a2144698b5acb7729f96de209b520fbaf5a0cccc7863?d=identicon)[llm1998](/maintainers/llm1998)

### Embed Badge

![Health badge](/badges/lmoreli-laravel-pdf/health.svg)

```
[![Health](https://phpackages.com/badges/lmoreli-laravel-pdf/health.svg)](https://phpackages.com/packages/lmoreli-laravel-pdf)
```

###  Alternatives

[phpoffice/phpspreadsheet

PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine

13.9k293.5M1.3k](/packages/phpoffice-phpspreadsheet)[spatie/browsershot

Convert a webpage to an image or pdf using headless Chrome

5.2k32.1M102](/packages/spatie-browsershot)[smalot/pdfparser

Pdf parser library. Can read and extract information from pdf file.

2.7k34.5M216](/packages/smalot-pdfparser)[barryvdh/laravel-snappy

Snappy PDF/Image for Laravel

2.8k24.8M48](/packages/barryvdh-laravel-snappy)[openspout/openspout

PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way

1.1k57.6M131](/packages/openspout-openspout)[keboola/csv

Keboola CSV reader and writer

1451.8M21](/packages/keboola-csv)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
