Willing to send all drawings, report, information about different departments to your boss, but they're all different PDFs that contain related information? Many users would just simply merge the PDFs and that's it. Merging files into a common PDF is extremely useful and necessary nowadays, so if you offer some kind of administrative app for some enterprise, adding such feature to your system may be useful so they won't need to install an external program or do it online using a third party service.
In this article, we'll show you how to merge multiple PDFs into a single one using the PDFMerger library.
1. Install pdfmerger
PDFMerger relies on the (installed automatically as dependencies) fpdf and fpdi classes by Setasign. There are other versions of the original library, ported into PHP5 as the original library was hosted in codeplex, however they don't have a minimum stability level (they work, but not with composer). The library fork that works with composer is the one created by @rguedes, as for Symfony, any dependency that you want to use requires a minimum stability level (not dev-master). The fork works even for Laravel too. To proceed with the installation of the package in your symfony project, open a terminal, switch to the directory of your project and install the library using composer:
composer require rguedes/pdfmerger
After the installation you will be able to use the PDFMerger class and its methods. For more information about the fork of this library, visit the repository at Github here.
2. Using the library
The usage of the library is very simple and straightforward, you create an instance of the PDF merger. This class allows you to merge many files as you want using the addPDF method and finally generate the merged result using the merge method. You can choose which pages of the PDFs should be added into the final one, decide how and where the final PDF will be generated as well.
Specifying which pages to merge
The PDFMerger class allow you to merge many PDFs as you want and need using the addPDF
method, you only need to provide the path as first argument and indicate which pages of the file should be merged into the final file using the second argument that expects a string. For example, you can merge all the pages of a PDF:
$pdf = new PDFMerger();
// Add all the pages of the PDF to merge
$pdf->addPDF("somePdfToMerge.pdf", 'all');
Specify specifically which pages you want by providing its number separed by a comma:
$pdf = new PDFMerger();
// Add only the pages 1, 3 and 5
$pdf->addPDF("somePdfToMerge.pdf", '1, 3, 5');
Or using a range, for example from the page 5 to the 10:
$pdf = new PDFMerger();
// Add only the pages from 5 to 10
$pdf->addPDF("somePdfToMerge.pdf", '5-10');
Merging model
Using the merge method, you will generate a PDF that contains the added files (the specified pages of every PDF). This file can be either stored or returned as response according to your needs. The method to process the PDF needs to be provided as first argument of the method merge, possible values for this argument are: browser
, download
, string
or file
. As second argument, the path where the PDF will be saved (if using file as method) or the name of the PDF that will be used to return it (with browser
or download
):
Generate direct download
If you don't need to save the PDF anywhere but just to generate it and return it as response, you can force the direct download of the generated PDF using the download identifier:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Require PDF class of the library
use PDFMerger;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// absolute path of the PDFs to merge
$pdfFile1Path = $this->get('kernel')->getRootDir() . '/../web/file1.pdf';
$pdfFile2Path = $this->get('kernel')->getRootDir() . '/../web/file2.pdf';
$pdfFile3Path = $this->get('kernel')->getRootDir() . '/../web/file3.pdf';
// Create an instance of PDFMerger
$pdf = new PDFMerger();
// Add 2 PDFs to the final PDF
$pdf->addPDF($pdfFile1Path, 'all');
$pdf->addPDF($pdfFile3Path, '1, 3, 5');
// Generate download of "mergedpdf.pdf"
$pdf->merge('download', "mergedpdf.pdf");
}
}
Saving into a file
You can store the merged result into a file in your server:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Use the normal response class
use Symfony\Component\HttpFoundation\Response;
// Require PDF class of the library
use PDFMerger;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// absolute path of the PDFs to merge
$pdfFile1Path = $this->get('kernel')->getRootDir() . '/../web/file1.pdf';
$pdfFile2Path = $this->get('kernel')->getRootDir() . '/../web/file2.pdf';
// Create an instance of PDFMerger
$pdf = new PDFMerger();
// Add 2 PDFs to the final PDF
$pdf->addPDF($pdfFile1Path, 'all');
$pdf->addPDF($pdfFile2Path, 'all');
// Merge the files into a file in some directory
$pathForTheMergedPdf = $this->get('kernel')->getRootDir(). '/../web/result.pdf';
$pdf->merge('file', $pathForTheMergedPdf);
return new Response(
"Files succesfully merged !"
);
}
}
Retrieve binary content of result pdf
In case you need to retrieve the content of the generated file (binary data) without saving it anywhere, you can use the string output method to retrieve the content as a variable. In this case, we'll return the binary content as a response with the PDF headers (to view in the browser). You can as well, use the browser type if you want:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Use Response class of Symfony
use Symfony\Component\HttpFoundation\Response;
// Require PDF class of the library
use PDFMerger;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// absolute path of the PDFs to merge
$pdfFile1Path = $this->get('kernel')->getRootDir() . '/../web/file1.pdf';
$pdfFile2Path = $this->get('kernel')->getRootDir() . '/../web/file2.pdf';
$pdfFile3Path = $this->get('kernel')->getRootDir() . '/../web/file3.pdf';
// Create an instance of PDFMerger
$pdf = new PDFMerger();
// Add 2 PDFs to the final PDF adding all their pages
$pdf->addPDF($pdfFile1Path, 'all');
$pdf->addPDF($pdfFile2Path, 'all');
// Merge the files and retrieve its PDF binary content
$binaryContent = $pdf->merge('string', "mergedpdf.pdf");
// Send it as response to the browser
// (view in the browser as well)
// which is the same as
// $pdf->merge('browser', "mergedpdf.pdf");
$response = new Response($binaryContent);
$response->headers->set('Content-type' , 'application/pdf');
return $response;
}
}
Happy coding !