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

Document Generator Bundle Laravel Package

whitedigital-eu/document-generator-bundle

A PHP bundle that adds flexible document generation to Symfony applications, letting you build files from templates and reusable content. Streamline creating invoices, reports, and other documents directly from your app with a simple, configurable workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is distributed as a Symfony-style bundle rather than a native Laravel package, so the first job is bridging it into Laravel's container before you write any generation code.

  1. Install and inspect what you actually got:
composer require whitedigital-eu/document-generator-bundle

Open vendor/whitedigital-eu/document-generator-bundle/ and read, in this order:

  • composer.json — confirms the PHP constraint and whether symfony/* contracts are pulled in.
  • src/ — the generator service class and any DependencyInjection/ extension, which tells you the exact service id and configuration keys.
  • README.md — template syntax and the expected data-array shape.
  1. Register the service manually in a DocumentGeneratorServiceProvider. Symfony bundles expect a container Extension to translate config arrays into service arguments; in Laravel you replicate that with a singleton:
$this->app->singleton(DocumentGenerator::class, function ($app) {
    return new DocumentGenerator(
        templatePath: config('documents.templates'),
        outputPath: config('documents.output'),
    );
});
  1. Publish a config/documents.php with templates, output (point this at a disk path, not storage_path() directly — see gotchas) and any driver/format settings.

  2. First use case: render a DOCX invoice from a stored .docx template. Put the template in resources/templates/invoice.docx with placeholder tokens, then:

$path = app(DocumentGenerator::class)->generate('invoice.docx', [
    'customer' => $customer->name,
    'invoice_no' => $invoice->number,
    'lines' => $invoice->lines->map->only(['description', 'qty', 'price'])->all(),
]);

Start with a two-line template and one scalar placeholder before touching repeating blocks — it isolates wiring problems from template-syntax problems.

Implementation Patterns

Wrap it, don't sprinkle it. Bind the generator behind your own DocumentService interface so the bundle's classes never appear in controllers. When the bundle's API shifts (or you outgrow it), you change one adapter.

Template-first workflow. Keep templates in version control under resources/templates/, treat them as fixtures, and add a test that renders each one with a canonical data array. A broken template is otherwise only discovered in production.

Repeating blocks via n-keyed arrays. The primary pattern is passing a flat list of associative arrays for a repeating region (table rows, address lists). As of 0.3.3, numerically-indexed lists are validated correctly:

'lines' => [
    ['description' => 'Consulting', 'qty' => 2, 'price' => 500],
    ['description' => 'Hosting',    'qty' => 1, 'price' => 50],
],

Pass ->values()->all() on Eloquent collections so keys are 0..n-1 rather than the collection's original keys — this is now the supported path rather than something to work around.

Queue anything user-triggered. Generation is CPU- and disk-bound. Dispatch a GenerateDocument job, write to a private disk, and notify when done:

dispatch(new GenerateDocument($invoice));

Storage integration. Use Laravel's Storage facade for retrieval (signed temporary URLs) but hand the generator absolute filesystem paths via Storage::disk('documents')->path($file). Keep the two concerns separate in your adapter.

Data extraction is your job. Build a dedicated toDocumentArray() method on the model (or a small presenter class) rather than passing models in. This keeps the template contract explicit and testable, and it's where you normalise dates/currency to strings the template can render.

Gotchas and Tips

The 0.3.3 fix matters if you use collections. Prior to 0.3.3, validation rejected arrays with integer keys, so repeated rows coming from Collection::all() (keys 0,1,2…) failed while hand-written string-keyed arrays passed. If you were on 0.3.2 or earlier you may have a workaround in place — re-keying data with 'row_0'-style keys, wrapping in an extra object, or array_combine. Remove those shims and re-run your template tests; leaving them in will confuse the next developer and can break nested blocks.

Upgrade is low-risk. 0.3.3 is a single validation fix on top of 0.3.2. No API, config, or template-syntax changes. Bump, run your rendering tests, done. Pin it ("0.3.3" or ^0.3) — this is a 0.x package, so minor bumps can break.

Validate your own data first. The bundle's validator checks the shape of what you pass against the template, but error messages surface as exceptions mid-render. Validate the domain data (required fields, non-empty line items) in a FormRequest or a toDocumentArray() guard so failures are legible.

Config quirks in a non-Symfony host. The bundle's Symfony extension won't auto-run under Laravel. Any configuration it supports must be passed manually to the constructor, and defaults baked into the extension will not apply. Read the extension class to see which defaults you need to mirror — otherwise you'll hit puzzling nulls on output or driver settings.

Debugging failed renders. Generate to a literal storage_path() during debugging rather than a configured disk so you can open the file immediately; corrupt or half-written output usually means a template token mismatch, not a code bug. Keep a known-good template + data pair as a smoke test.

Extension points. The generator's format/driver abstraction (if exposed) and its output-path handling are the useful seams. Subclass or decorate the generator's rendering step to post-process (PDF conversion, watermarking, metadata) rather than editing templates.

Large documents. Memory usage scales with the data array, not the template. Chunk generation for anything over a few thousand rows and merge afterwards, or you'll hit PHP memory limits inside a queue worker.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo