Laravel 5 Zipp invoices files using zipper

Requirements Install chumper/zipper Package

composer require chumper/zipper

Config define providers and aliases

Find the providers in config folder in app.php file and register the ZipperServiceProvider.

'providers' => [
        // ...
       'Chumper\Zipper\ZipperServiceProvider',
    ]

Locate the aliases in config >> app.php file and designate the aliases.

'aliases' => [
        // ...
        'Zipper' => 'Chumper\Zipper\Zipper',
    ]

Controller

We are creating an export function that will return download link with zipped PDF invoices files. For this controller we will use classes :

use Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use PDF;

 

public function export()
{           
    $inputs = Request::all();

    //Clean directory
    // Get all files in a directory
    $files =   Storage::allFiles('public/invoices/');
    // Delete Files
    Storage::delete($files);

    try { 

            // take invoices ids
            $invoices = \DB::table('invoices')
                ->select('id')
                ->get();

            // for each invoiuce we will generate PDF file from view and storage into disk path
            foreach ($invoices as $invoice){
   
                $pdf = invoice($invoice->id);
                $file = $pdf[0]->output();
                Storage::put('public/invoices/inv_'.$pdf[1].'.pdf', $file);   
            }
        }
         // zip all files into temp
            $files = glob(storage_path('app/public/invoices/*'));
            if ($files) {
              \Zipper::make(storage_path('app/public/invoices/invoices_'.date('Y-m-d').'.zip'))->add($files)->close();
              // return link
              return Storage::download('public/invoices/invoices_'.date('Y-m-d').'.zip');
            }
            return back();   
    } 
    catch(\Illuminate\Database\QueryException $ex){ 
      return $ex->getMessage(); 
    }
}

Helper function to generate PDF file from view.

This helper function will return an array with pdf object and invoice number.

function invoice($id){

    $items = \DB::table('invoice_items')
        ->select('service', 'gross', 'net', 'vat', 'pst')
        ->where('id_invoice', $id)
        ->get();
    
    $pdf = PDF::loadView('invoice', compact('items'));
    return [$pdf, $inv_number];
}

Invoice View

We are creating the simple HTML view invoice blade file: invoice.blade.php for this example. You can update this HTML as per your requirement.

!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Invoice - 1000</title>
    <style>
        .clearfix:after {
            content: "";
            display: table;
            clear: both;
          }
          .place {
            text-align: right;
            margin-top: 30px;
          }
          .bank {
            width: 100%;
            height: 70%;
            background: #ffff;
            border: none;
            font-size: 14px;
            font-family: Arial;
            color: black;
            overflow:hidden; 
            resize:none;
          }
          a {
            color: #5D6975;
            text-decoration: underline;
          }
          
          body {
            position: relative;
            width: 19cm;  
            height: 26cm;
            margin: 0 auto; 
            color: black;
            background: #FFFFFF; 
            font-family: DejaVu Sans, sans-serif; 
            font-size: 12px;
          }
          header {
            padding: 10px 0;
          }
          
          #logo {
            float: left;
            margin-bottom: 10px;
          }
          
          #logo img {
            height: 80px;
          }
          
          h1 {
            border-top: 1px solid  #5D6975;
            border-bottom: 1px solid  #5D6975;
            color: black;
            font-size: 2.4em;
            line-height: 1.4em;
            font-weight: normal;
            text-align: left;
            margin: 0 0 20px 0;
          }
          h2 {
            color: black;
            font-size: 1.4em;
            line-height: 1.4em;
            font-weight: normal;
            margin: 10px 10px 20px 0;
            text-align: center;
          }
          .inv {
          }
          .users {
            display: block;
            margin-right: 30px;
            margin-left: 30px;
          }
          .seller {
            float: left;
            font-size: 16px;
            margin-bottom: 30px;
          }
          .company {
            float: right;
            font-size: 16px;
            margin-bottom: 30px;
          }
          
          #seller div,
          #company div {
            white-space: nowrap;        
          }
          table {
            width: 100%;
            border-collapse: collapse;
            border-spacing: 0;
            margin-bottom: 20px;
          }
          table tr:nth-child(2n-1) td {
            background: #F5F5F5;
          }
          table th,
          table td {
            text-align: right;
          }
          table th {
            padding: 5px 5px;
            color: #5D6975;
            border-bottom: 1px solid #C1CED9;
            white-space: nowrap;        
            font-weight: normal;
          }
          table .service,
          table .desc {
            text-align: left;
          }
          table td {
            padding: 5px;
            text-align: right;
          }
          table td.service,
          table td.desc {
            vertical-align: top;
          }
          table td.unit,
          table td.qty,
          table td.total {
            font-size: 1.2em;
          }
          table td.grand {
            border-top: 1px solid #5D6975;;
          }
          #notices .notice {
            color: #5D6975;
            font-size: 1.2em;
            margin-bottom: 20px;
          }
          footer {
            color: #5D6975;
            width: 100%;
            height: 30px;
            position: absolute;
            bottom: 0;
            border-top: 1px solid #C1CED9;
            padding: 8px 0;
            text-align: center;
          }
          .total {
            font-family: Arial; 
            font-size: 14px;
          }
    </style>
  </head>
  <body>
    <header class="clearfix">
      <div id="logo">
        <img src="/logo.png">
      </div>
      <div class="place">
        <div>Place of issue: Country, City</div>
        <div>Date of issue: 2019-05-06 12:00:00</div>
        <div>Date of sale: 2019-05-06 12:00:00</div>
      </div>
      <div class="inv">
          <h2 style="float: right"><strong>ORYGINAL/COPY</strong></h2>
          <h1>INVOICE Nr - <strong>1000</strong></h1>
          <div class="users">
            <div class="company">
              <div><strong>SELLER: </strong></div>
              <div>Company name</div>
              <div>Address</div>
              <div>Country, City</div>
              <div>Tax ID</div>
            </div>
            <div class="seller">
              <div><strong>BUYER: </strong></div>
              <div>Company Name</div>
              <div>Address</div>
              <div>Country, City</div>
              <div>Tax ID</div>
            </div>
          </div>
      </div>
    </header>
    <main>
      <table>
        <thead>
          <tr>
            <th>PRODUCT</th>
            <th>NET</th>
            <th>VAT %</th>
            <th>VAT AMOUNT</th>
            <th>PST %</th>
            <th>PST AMOUNT</th>
            <th>GROSS</th>
          </tr>
        </thead>
        <tbody>
          @foreach ($items as $item)
          <tr>
            <td class="desc">{{ $item->service }}</td>
            <td class="total">{{ $item->net }}</td>
            <td class="qty total">24</td>
            <td class="total">{{ $item->vat }}</td>
            <td class="unit total">5</td>
            <td class="total">{{ $item->pst }}</td>
            <td class="total">{{ $item->gross }}</td>
          </tr>
          @endforeach
          <tr>
            <td colspan="6" class="grand total">TOTAL NET</td>
            <td class="grand total">USD {{ $invoice->total_net }}</td>
          </tr>
          <tr>
            <td colspan="6">VAT 24%</td>
            <td class="total">USD {{ $invoice->total_vat }}</td>
          </tr>
          <tr>
            <td colspan="6">PST 5%</td>
            <td class="total">USD {{ $invoice->total_pst }}</td>
          </tr>
          <tr>
            <td colspan="6" class="grand total"><strong>TOTAL DUE</strong></td>
            <td class="grand total"><strong>USD {{ $invoice->total_gross }}</strong></td>
          </tr>
        </tbody>
      </table>
      <!--Payment Terms -->
      <div id="notices">
          <div class="notice"><strong>Terms of Payment: payment terms</strong></div>
      </div>
      <!--Bank details -->
      <div>
        <div><strong>Bank Details:</strong></div>
        <textarea class="bank" disabled rows='17'>bank details</textarea>
      </div>
    </main>
    <footer>
      Invoice was created on a computer and is valid without the signature and seal.
    </footer>
  </body>
</html>

Route

Now we need to add the route in /routes/web.php for export zipped invoices.

Route::get('/invoices_export', 'InvoicesController@export');

Finally, everything’s ready now when you execute GET https://localhost//invoices_export to download the Zipped PDF files. Feel free to comment if any query.

,

Related Posts

Leave a Reply

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

Fill out this field
Fill out this field
Please enter a valid email address.

Menu