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

Mpdf Bundle Laravel Package

dol/mpdf-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require dol/mpdf-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        DarwinOnLine\MpdfBundle\DarwinOnLineMpdfBundle::class => ['all' => true],
    ];
    
  2. Basic Usage: Inject the Mpdf service into a controller or service:

    use DarwinOnLine\MpdfBundle\Service\Mpdf;
    
    class PdfController extends AbstractController
    {
        public function generatePdf(Mpdf $mpdf)
        {
            $mpdf->WriteHTML('<h1>Hello, PDF!</h1>');
            return $mpdf->Output('output.pdf', 'D'); // 'D' forces download
        }
    }
    
  3. First Use Case: Generate a simple PDF from a Twig template:

    public function generateFromTwig(Mpdf $mpdf, $templatePath, array $data)
    {
        $html = $this->renderView($templatePath, $data);
        $mpdf->WriteHTML($html);
        return $mpdf->Output('document.pdf', 'I'); // 'I' sends inline
    }
    

Implementation Patterns

Core Workflows

  1. HTML-to-PDF Conversion:

    • Use WriteHTML() for raw HTML strings or Twig-rendered content.
    • Example with dynamic data:
      $mpdf->WriteHTML($this->renderView('pdf/template.html.twig', ['user' => $user]));
      
  2. Styling and Layout:

    • Inject CSS via WriteHTML() or SetCSS():
      $mpdf->SetCSS('path/to/styles.css');
      
    • Use mPDF’s built-in headers/footers:
      $mpdf->SetHeader('{PAGE_NUM}/{nb}');
      
  3. Dynamic PDF Generation:

    • Loop through data and append pages:
      foreach ($items as $item) {
          $mpdf->AddPage();
          $mpdf->WriteHTML($this->renderView('pdf/item.html.twig', ['item' => $item]));
      }
      
  4. Integration with Symfony Forms:

    • Serialize form data to HTML and pass to WriteHTML():
      $formView = $this->createFormView($form, $data);
      $html = $this->render('form/_form.html.twig', ['form' => $formView]);
      $mpdf->WriteHTML($html);
      

Advanced Patterns

  1. Custom Templates:

    • Extend the bundle’s Mpdf service to add reusable methods:
      // src/Service/CustomMpdf.php
      class CustomMpdf extends Mpdf
      {
          public function generateInvoice($user, $items)
          {
              $this->AddPage();
              $this->WriteHTML($this->renderView('pdf/invoice.html.twig', compact('user', 'items')));
          }
      }
      
    • Register the service in services.yaml:
      services:
          App\Service\CustomMpdf:
              decorates: 'darwin_online_mpdf.mpdf'
              arguments: ['@darwin_online_mpdf.mpdf']
      
  2. Asynchronous Generation:

    • Use Symfony’s Messenger component to queue PDF generation:
      $message = new GeneratePdfMessage($userId, $template);
      $this->messageBus->dispatch($message);
      
    • Handle in a worker with the Mpdf service.
  3. Caching:

    • Cache generated PDFs to avoid reprocessing:
      $cacheKey = 'pdf_' . md5($template . serialize($data));
      if (!$pdf = $this->cache->get($cacheKey)) {
          $mpdf->WriteHTML($html);
          $pdf = $mpdf->Output('', 'S'); // 'S' returns as string
          $this->cache->set($cacheKey, $pdf, 3600); // Cache for 1 hour
      }
      

Gotchas and Tips

Common Pitfalls

  1. Deprecated mPDF Methods:

    • The bundle wraps mPDF v6, but some methods (e.g., Write()) may behave differently than v7+. Check mPDF’s migration guide.
    • Fix: Use WriteHTML() for HTML content and Write() only for plain text.
  2. Font Issues:

    • mPDF requires fonts to be installed in its fonts/ directory. If text appears as boxes:
      • Debug: Check var/log/dev.log for font-related errors.
      • Fix: Add fonts via SetFont() or configure custom paths in config/packages/darwin_online_mpdf.yaml:
        darwin_online_mpdf:
            fonts_dir: '%kernel.project_dir%/public/fonts'
        
  3. Memory Limits:

    • Large PDFs may hit PHP’s memory limit (Allowed memory size of X bytes exhausted).
    • Fix: Increase memory_limit in php.ini or optimize HTML/CSS (e.g., inline CSS, avoid complex layouts).
  4. Twig Auto-escaping:

    • Twig escapes HTML by default, breaking PDF rendering. Use |raw filter:
      {{ form|raw }}
      
    • Alternative: Disable escaping in the controller:
      $html = $this->renderView('template.html.twig', ['form' => $form], ['escape' => false]);
      
  5. Output Modes:

    • Confusing Output() modes:
      • 'D' (Download), 'I' (Inline), 'S' (Return as string), 'F' (Save to file).
    • Tip: Use 'S' for caching or further processing:
      $pdfContent = $mpdf->Output('', 'S');
      

Debugging Tips

  1. Inspect HTML:

    • Save raw HTML to a file before passing to WriteHTML():
      file_put_contents('debug.html', $html);
      
    • Open debug.html in a browser to verify rendering.
  2. Log mPDF Errors:

    • Enable mPDF’s error logging:
      $mpdf->debug = true;
      $mpdf->error_policy = MPDF::ERROR_EXCEPTION;
      
  3. Check Configuration:

    • Validate config/packages/darwin_online_mpdf.yaml:
      darwin_online_mpdf:
          format: 'A4'          # Default paper format
          default_font: 'dejavu' # Ensure font exists
          margin_top: 10
          margin_bottom: 10
      

Extension Points

  1. Custom mPDF Configuration:

    • Override the Mpdf service to inject custom settings:
      services:
          DarwinOnLine\MpdfBundle\Service\Mpdf:
              arguments:
                  $format: 'Letter'
                  $default_font: 'arial'
                  $margin_header: 20
                  $margin_footer: 20
      
  2. Event Listeners:

    • Hook into PDF generation lifecycle (e.g., pre/post-processing):
      // src/EventListener/PdfListener.php
      class PdfListener implements KernelEventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  KernelEvents::VIEW => ['onKernelView', 20],
              ];
          }
      
          public function onKernelView(ViewEvent $event)
          {
              if ($event->getController() instanceof PdfController) {
                  // Modify $event->getControllerResult() before output
              }
          }
      }
      
  3. Symfony UX Turbo/Stimulus:

    • For real-time PDF previews, use Stimulus to trigger PDF generation via AJAX:
      // assets/controllers/pdf_controller.js
      import { Controller } from '@hotwired/stimulus';
      
      export default class extends Controller {
          generate() {
              fetch('/pdf/generate', { method: 'POST' })
                  .then(response => response.blob())
                  .then(blob => {
                      const url = window.URL.createObjectURL(blob);
                      window.open(url);
                  });
          }
      }
      

Performance Optimization

  1. Lazy Loading:

    • Defer PDF generation until the last moment (e.g., after user confirms):
      // Store data in session, generate PDF only when needed
      $this->session->set('pdf_data', $data);
      
  2. Batch Processing:

    • For bulk PDFs (e.g., invoices), use a queue system to avoid timeouts:
      foreach ($users as $user) {
          $this->messageBus->dispatch(new GeneratePdfMessage($user));
      }
      
  3. Minify HTML/CSS:

    • Use tools like htmlmin or cssmin to reduce payload size before passing to WriteHTML().
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.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo