Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Print Laravel Package

rekalogika/print

rekalogika/print is a PHP package for generating print-ready documents and PDFs. It provides a clean, framework-friendly API for managing print output, so you can add reliable document printing workflows to Laravel or any PHP application with minimal setup, and integrates smoothly into existing proj...

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a low-level value-object layer, not a full PDF engine. It gives you immutable Paper and PageLayout objects that describe what to print on, not how to render. Plan on pairing it with a renderer (mPDF, Dompdf, wkhtmltopdf, Gotenberg, etc.).

Install and inspect first:

composer require rekalogika/print

Before writing any application code, read the Paper and PageLayout classes directly — they're the entire surface area. Check whether Paper is an enum (likely: Paper::A4, Paper::Letter, Paper::Legal) or a factory-based class (Paper::A4()), and confirm the unit system (almost certainly millimeters, matching ISO 216).

First use case — an invoice layout service:

use Rekalogika\Print\Paper;
use Rekalogika\Print\PageLayout;

final class InvoiceLayoutFactory
{
    public function make(): PageLayout
    {
        return new PageLayout(
            paper: Paper::A4,
            orientation: 'portrait',
            margins: ['top' => 20, 'right' => 15, 'bottom' => 20, 'left' => 15],
        );
    }
}

Register this as a singleton in a service provider and inject it wherever you generate documents. The moment you find yourself typing 20 and 15 inline in a controller, stop and move it into config.

Implementation Patterns

Bind layouts as named configuration, not constants. Laravel's config/print.php is the right home for paper specs so operations people can adjust margins without a deploy:

// config/print.php
return [
    'layouts' => [
        'invoice' => ['paper' => 'A4', 'orientation' => 'portrait', 'margins' => [20, 15, 20, 15]],
        'receipt' => ['paper' => 'A6', 'orientation' => 'portrait', 'margins' => [5, 5, 5, 5]],
        'report' => ['paper' => 'A4', 'orientation' => 'landscape', 'margins' => [15, 15, 15, 15]],
    ],
];

Then wrap construction in a LayoutResolver that maps config keys to PageLayout instances. This keeps the package out of your controllers entirely and makes layout choices testable.

Adapter pattern for the renderer. Never let mPDF/Dompdf see PageLayout directly — write a one-method adapter so swapping renderers is a class swap:

final class DompdfLayoutAdapter
{
    public function apply(PageLayout $layout, \Dompdf\Dompdf $pdf): void
    {
        $pdf->setPaper(
            [$layout->getWidth(), $layout->getHeight()],
            $layout->getOrientation(),
        );
    }
}

This is the single most valuable pattern here: PageLayout is your domain vocabulary, the renderer is an implementation detail.

Blade pipeline. The typical flow is: layout → HTML (Blade view) → renderer → PDF bytes → Storage::put() → signed URL. Keep the layout decision at the top of the pipeline so both the CSS @page rule and the renderer call read from the same object — divergent CSS and renderer margins are the #1 source of "why is my PDF misaligned" bugs.

Testing. Because these are pure value objects, assert on dimensions directly:

it('uses A4 portrait with 20mm top margin', function () {
    $layout = app(InvoiceLayoutFactory::class)->make();

    expect($layout->getPaper())->toBe(Paper::A4)
        ->and($layout->getOrientation())->toBe('portrait')
        ->and($layout->getMargin('top'))->toBe(20.0);
});

No rendering required, so tests are fast and deterministic. Save the actual PDF byte-diffing for a separate smoke test.

Gotchas and Tips

  • This is a READ-ONLY split repository. It exists only to make rekalogika/print installable standalone. Issues, PRs, and docs belong in the upstream monorepo (rekalogika/print). Do not open issues here — they'll go nowhere, and you'll waste a day thinking the maintainer is unresponsive.

  • Zero stars, zero dependents. Treat API stability as unverified. Pin the exact version in composer.json ("rekalogika/print": "1.0.*" or tighter) and write a thin wrapper (the adapter above) so a breaking change costs you one file, not fifty.

  • No Laravel integration ships with it. There is no service provider, no facade, no config publish. Everything you see in "Implementation Patterns" above is code you write. Budget an afternoon for wiring, not five minutes for composer require.

  • Units. Confirm the unit contract before you hardcode 20. If it's millimeters and your CSS is in points, your margins will be off by ~2.83×. Dump a known paper's dimensions and sanity-check against the ISO spec (A4 = 210 × 297 mm).

  • Immutability. PageLayout and Paper are almost certainly immutable value objects with with*() methods. Mutating properties directly will either fail or silently do nothing. Recreate instead of mutate: $layout->withMargin('top', 25).

  • print-contracts vs print. The contracts package defines the interfaces; this package supplies the concrete Paper and PageLayout. Type-hint against the contracts interfaces in your own code so you can substitute test doubles or a future implementation without touching call sites.

  • Extension points. If you need a custom paper size (labels, tickets, thermal rolls) that isn't in the enum, implement the contract yourself rather than forking — that's what the interfaces exist for. This is the primary reason to depend on the contracts package even when you don't strictly need to.

  • Debugging. There's no logging or validation layer to lean on. When a PDF comes out wrong, dd($layout) and check the raw dimensions first. Nine times out of ten the value object is correct and the bug is in the renderer call or the CSS @page rule disagreeing with it.

  • Evaluate the alternative first. If your only need is "A4 invoice with margins," you may be better off calling $pdf->setPaper('A4', 'portrait') directly in your adapter and skipping this dependency entirely. This package earns its keep when you have many layout definitions, need to share them across renderers, or want them testable in isolation — otherwise it's abstraction tax on a solved problem.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route