How to Generate PDF Files and Enable Downloads with Laravel 11 Livewire 3

featured_img1737788630.webp

How to Generate PDF Files and Enable Downloads with Laravel 11 Livewire 3

Table of Contents

    Learn how to create dynamic PDF files using Laravel 11 and Livewire 3. This step-by-step guide demonstrates generating and downloading bills, invoices, and reports with proper styling using the barryvdh/laravel-dompdf package.

    What is Livewire?

    Livewire is a full-stack framework for Laravel that allows you to build dynamic interfaces directly in PHP. It eliminates the need for complex JavaScript, offering a simple yet powerful way to enhance your applications.

    File Downloads in Livewire?

    File downloads in Livewire work like Laravel but use Base64 encoding to send file data to the frontend, where it's decoded for client-side download

    Follow these simple steps, and you’ll quickly learn how to generate and download PDFs in Laravel Livewire, even with a fresh project setup.

    Step 1: Setting Up the Laravel Project

    Before diving into the implementation, ensure you have a Laravel project set up with Livewire installed.

    Open your terminal and run the following command to create a fresh Laravel application:

                                        
                                            composer create-project laravel/laravel BillGenApp
                                        
                                    

    Navigate to the BillGenApp directory by running the following command in your terminal

                                        
                                            cd BillGenApp
                                        
                                    

    Step 2: Installing Livewire V3

    Install Livewire in Laravel with the following command in your application root directory

    Next, install Livewire using this command:

                                        
                                            composer require livewire/livewire
                                        
                                    

    Step 3: Creating a Template Layout

    This command will generate a file called resources/views/components/layouts/app.blade.php

                                        
                                            php artisan livewire:layout
                                        
                                    

    Include livewire frontend Assets and add bootstrap CDN link in the following path: resources/views/components/layouts/app.blade.php

                                        
                                            <!doctype html>
                                            <html lang="en">
                                            <head>
                                                    <meta charset="UTF-8">
                                                    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
                                                    <title>PDF Generator in Laravel</title>
                                                    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
                                                    @livewireStyles
                                            </head>
                                            <body>
                                                    @yield('content')
                                                    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
                                                    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
                                                    @livewireScripts
                                                    @yield('script')
                                            </body>
                                            </html>                                       
                                        
                                    

    Step 4: Integrate a PDF generator package

    Install barryvdh/laravel-dompdf composer package with the following command in your application root directory

                                        
                                            composer require barryvdh/laravel-dompdf
                                        
                                    

    This package can be used to create PDFs from HTML. In a Laravel application the easiest way to generate some HTML is to use a Blade view.

    Creating PDFs

    After successfully install package use PDF Facade in your Logic File to create a PDF from a Blade view

    Here's an example

                                        
                                            use Barryvdh\DomPDF\Facade\Pdf; 
    
                                            Pdf::view('bill-payment-details',['bill_record' => $billRecord])->save('/public/bills/yourbill.pdf');
                                        
                                    

    To explore more features of PDF generation, visit the official documentation: Spatie Laravel PDF Documentation.

    Step 5: Creating a Livewire Component

    Run the following command to generate the BillPaymentDetails component:

                                        
                                            php artisan make:livewire DownloadReport\\BillPaymentDetails
                                        
                                    

    This will create the following files:

    Update the Component Logic (BillPaymentDetails.php)

    Edit the BillPaymentDetails.php file to handle PDF Generate logic.

                                        
                                                namespace App\Livewire\DownloadReport;
                                                
                                                use Livewire\Component;
                                                use Barryvdh\DomPDF\Facade\Pdf;
                                                class BillPaymentDetails extends Component
                                                {
                                                     
                                                    public function render()
                                                    {
                                                        return view('livewire.download-report.bill-payment-details');
                                                    }
                                                
                                                    public function downloadBillPaymentDetails(){   
                                                        
                                                        $records_info = [
                                                              "biller_id" => "PASC00000GUJ8A",
                                                              "biller_name" => "Electricity (PGVCL)",
                                                              "customer_name" => "SATISHBHAI PARMAR",
                                                              "mobile" => "XXXXXXX104",
                                                              "bill_date" => "2024-11-20",
                                                              "bill_period" => "Oct,-Nov,24",
                                                              "bill_number" => "8333503741320241820",
                                                              "due_date" => "2024-11-30",
                                                              "bill_amount" => 860,
                                                              "cust_conv_fee" => 0,
                                                              "txn_date" => "2025-01-21",
                                                              "txn_status" => "Success",
                                                              "init_channel" => "AGT",
                                                              "payment_mode" => "Cash",
                                                              "approval_ref_number" => "8333503741320241820"
                                                        ];
                                                        $viewName = "livewire.download-report.bill-receipt";
                                                        $pdfContent = PDF::loadView($viewName,["records_info" => $records_info])->output();
                                                        return response()->streamDownload(fn () => print($pdfContent), "BillPaymentReceipt" . time() . ".pdf");
                                                    }
                                                }
                                            
                                    

    Update the Component View (bill-payment-details.blade.php)

    Edit the bill-payment-details.blade.php file to design the UI for displaying the Bill Download Button.

                                        
                                                                                        
                                                <div>
                                                    <div class="container mt-5">
                                                        <h2>Click this Button to Download Bill Receipt </h2>
                                                        <button type="button" class="btn btn-success btn-sm me-2 mb-0" wire:click="downloadBillPaymentDetails()" fdprocessedid="2tqh59">
                                                            Download Bill Receipt
                                                        </button> 
                                                     </div>   
                                                 </div>                                       
                                            
                                        
                                    

    Step 6: Create styled, downloadable PDF files.

    Run the following command to generate the bill-receipt Blade HTML View file:

                                            
                                                php artisan make:view livewire.download-report.bill-receipt
                                            
                                        

    Edit the bill-receipt.blade.php file to design the UI for displaying the Bill Details.

                                            
                                                    
    <!doctype html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Print Expense Report< </title> <link href="https://fonts.googleapis.com/css?family=Calibri:400,700,400italic,700italic"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700&display=swap" rel="stylesheet"> <head> <body> <div> <section class="section" style="width: 600px; margin: auto; float: none; display: block;"> <div class="logo-css text-center"> <img src="{{ public_path('images/logo.png') }}" alt="" style="width: 200px; height: 80px;"> </div> <div class="card"> <div class="card-header"> <div class="float-center text-center" style="margin: auto; padding: 15px;"> <h4 class="card-title" style="color: #3968b1;">Bill Payment Details </h4> </div> </div> <div class="card-body"> <div class="offset-lg-3 col-lg-6"> <div class="separator separator-dashed mb-2"></div> <div class="table-responsive pr-5 pl-5"> <table class="table table-head-custom table-head-bg table-vertical-center" style="margin: auto; padding: 15px;"> <tbody> <tr> <td style="padding: 5px;"><b>Biller ID</b></td> <td style="padding: 5px;" class="text-right fw-500 p-4">: &nbsp;&nbsp; {{ $records_info['biller_id'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Biller Name</b></td> <td style="padding: 5px;" class="text-right fw-500 p-4">: &nbsp;&nbsp; {{ $records_info['biller_name'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Customer Name </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['customer_name'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Mobile Number </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['mobile'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Bill Date </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['bill_date'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Bill Period </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['bill_period'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Bill Number </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['bill_number'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Due Date </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['due_date'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Bill Amount </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{"Rs. ". $records_info['bill_amount'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Customer Convenience Fees </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{"Rs. ". $records_info['cust_conv_fee'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Total Amount </b></td> <td style="padding: 5px;"class="text-right fw-500">: &nbsp;&nbsp; {{"Rs. ". $records_info['bill_amount'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Transaction Date & Time </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['txn_date'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Initiating Channel </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['init_channel'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Payment Mode </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['payment_mode'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Transaction Status </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['txn_status'] ?? '' }} </td> </tr> <tr> <td style="padding: 5px;"><b>Approval Number </b></td> <td style="padding: 5px;" class="text-right fw-500">: &nbsp;&nbsp; {{ $records_info['approval_ref_number'] ?? '' }} </td> </tr> </tbody> </table> </div> </div> </div> </div> </section> </div> </body> </html>

    Step 7: Setting Up Routes And Run Project

    1. Add Route

      Define the route in routes/web.php

                                                  
                                                      use App\Livewire\DownloadReport\BillPaymentDetails;
      
                                                      Route::get('/download-bill-receipt', BillPaymentDetails::class);                                          
                                                  
                                              
    2. Run the Project

      Start the development server:

                                                  
                                                      php artisan serve                                         
                                                  
                                              
    3. Preview the Application

      Open your web browser and navigate to the following URL to view the code preview:

      Preview:

    Conclusion

    This tutorial showed how to generate and download dynamic PDFs in Laravel 11 with Livewire 3. From setup to styled invoices and routes, you’ve learned the essentials for creating professional PDFs dynamically. Customize it for your needs and happy coding!

    Did this solution work for you? Drop a like or comment below!

    Satish Parmar

    Satish Parmar

    Experienced Full-Stack Web Developer

    I'm a passionate full-stack developer and blogger from India, dedicated to sharing web development tips and solutions. As the creator of TipInfoTrove.com, my goal is to help developers and tech enthusiasts solve real-world challenges with expertise in PHP, Laravel, JavaScript, Vue, React, and more. Through detailed guides and practical insights, I strive to empower others to excel in their projects and stay ahead in the ever-evolving world of technology.

    0 Comments

    Post Comment

    Your email address will not be published. Required fields are marked *