Papercut
Guide
Laravel
Reference
Examples
Changelog
GitHub
Guide
Laravel
Reference
Examples
Changelog
GitHub
  • Start

    • Introduction
    • Installation
    • Your first document
  • Building documents

    • Layout
    • Text
    • Tables
    • Pages and pagination
    • Images, SVG, links and QR codes
    • Decorators
  • Look and output

    • Styles and themes
    • Fonts
    • Rich text
    • HTML export
    • Fonts in HTML
    • Word export
    • Passwords, signatures and merging

Your first document

Every document has the same basic shape: a document, one or more pages, and some content on each page. Here's the same PDF built both ways:

Blade
{{-- resources/views/pdf/hello.blade.php --}}
<x-doc::document title="Hello">
  <x-doc::page size="a4" margin="20mm">
    <x-doc::column gap="8pt">
      <x-doc::h1>Hello, {{ $name }}</x-doc::h1>
      <x-doc::p>A column of text. Inter is bundled, so this embeds a real font.</x-doc::p>
    </x-doc::column>
  </x-doc::page>
</x-doc::document>
PHP
use Papercut\{Column, Document, Page, Text};
use function Papercut\{mm, pt};

$document = Document::make(
    Page::a4()->margin(mm(20))->body(
        Column::make(
            Text::h1('Hello, Ada'),
            Text::p('A column of text. Inter is bundled, so this embeds a real font.'),
        )->gap(pt(8)),
    ),
)->title('Hello');

$document->toPdf()->save('hello.pdf');

A Blade view needs exactly one <x-doc::document> at the root. If you put content directly inside the document without a <x-doc::page>, Papercut wraps it in a page for you, using the paper size and margin from your config.

Getting the PDF out

In plain PHP, toPdf() returns an Output with three methods:

MethodWhat it does
save($path)Writes the PDF to a file.
bytes()Returns the PDF as a string.
stream()Writes the PDF to the output buffer and returns the number of bytes.

In Laravel, Papercut::view($view, $data) returns a pending document, and calling ->pdf() on it gives you a PendingOutput:

MethodWhat it does
download($filename)Returns a response that downloads the file.
inline($filename)Returns a response that opens the PDF in the browser.
save($path)Writes the PDF to a local file.
store($path, $disk)Writes the PDF to a storage disk. Leave out $disk to use the default one.
toString()Returns the PDF as a string.

The filename defaults to document.pdf. If you return a PendingOutput straight from a route, the PDF opens inline.

You can mix the two styles. To send a document you built in PHP as a Laravel response, wrap it with Papercut::make($document)->pdf(). To go the other way, Papercut::view(...)->document() gives you the core Document that a Blade view built.

Password protection

To make the PDF open only with a password, call encrypt() before pdf(): Papercut::view(...)->encrypt('open-sesame')->pdf(). Passwords, signatures and merging covers permissions.

Saving to storage

store() writes to any disk in config/filesystems.php, which makes it a good fit for queued jobs that generate a document and send a link to it later:

use Illuminate\Support\Facades\Storage;
use Papercut\Laravel\Facades\Papercut;

Papercut::view('pdf.invoice', ['invoice' => $invoice])
    ->pdf()
    ->store("invoices/{$invoice->number}.pdf", 's3');

$url = Storage::disk('s3')->temporaryUrl("invoices/{$invoice->number}.pdf", now()->addDay());

A third argument is passed on to the disk, so store($path, 's3', 'public') makes the file publicly visible. If the disk reports that the write failed, store() throws a RuntimeException.

Components are immutable

Every method returns a new copy and leaves the original untouched:

$label = Text::make('Total')->bold();
$big   = $label->size(pt(14));   // $label is still the default size

That means you can build a piece once and reuse it in as many places as you like, without one use affecting another.

Next

Layout covers rows, columns and units.

Edit this page on GitHub
Last Updated: 10/21/26, 1:31 PM
Prev
Installation