Hey guys.
I am having a hard time getting this started.
I need to have a page where a user can select or de-select (check boxes, radio doesnt matter) pdfs and then have the selected pdfs merged into a single pdf.
I have used PDF Merger in the past but I used it in a different way.

I need a page with a list of pdfs that can be selected and posted to this pdf merger.
Any ideas?
I am still a PHP novice but I am learning, although slowly...
Happy New Year Everyone!

Recommended Answers

All 9 Replies

Member Avatar for diafol

Ok, haven't used it myself, but it looks pretty straightforward

From the link:

include 'PDFMerger.php';

$pdf = new PDFMerger;

$pdf->addPDF('samplepdfs/one.pdf', '1, 3, 4')
    ->addPDF('samplepdfs/two.pdf', '1-2')
    ->addPDF('samplepdfs/three.pdf', 'all')
    ->merge('file', 'samplepdfs/TEST2.pdf');

Your links page may look something like this:

Get your data - assuming files are stored in your DB and using PDO:

$tablerows = '';
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
    $tablerows .= 
    "<tr>
        <td><input type='checkbox' name='pdfs[]' value='{$row['file_name']}' /><td>
        <td>{$row['file_name']}</td>
    </tr>";    
}

Otherwise, you can SPL directory iterator or glob() to get pdf files from a directory and do something similar

$tablerows = '';
foreach (glob("*.pdf") as $file_name) {
   $tablerows .= 
    "<tr>
        <td><input type='checkbox' name='pdfs[]' value='$file_name' /><td>
        <td>$file_name</td>
    </tr>"; 
}

Place the table contant into your markup at the suitable point, e.g.

<form method="post" action="handlepdfs.php">
    <table>
        <?php echo $tablerows;?>
    </table>
    <label for = "newfilename">Name merged file:</label>
    <input id="newfilename" name="newfilename" /> .pdf
    <input type="submit" value="Merge Selected PDFs" />
</form>    

Then in handlepdfs.php

$result="?result=0";

if(isset($_POST['pdfs']) && isset($_POST['newfilename']) && trim($_POST['newfilename']))
{
    include 'PDFMerger.php';
    $merger = new PDFMerger;

    $location = "mypdffolder";
    $mergedLocation = "mergedpdfs";

    $pdfs = (array) $_POST['pdfs'];

    foreach($pdfs as $pdf)
    {
        if(file_exists($location/$pdf))
        {
            $merger->addPDF("$location/$pdf", 'all');
        }    
    }

    //you need to clean the filename to make sure its ok before next bit
    $mergefile = trim($_POST['newfilename']) . time() . ".pdf";
    $merger->merge('file', "$mergedLocation/$mergefile");
    if(file_exists("$mergedLocation/$mergefile"))
    {
        $result="?result=1&file=" . urlencode("$mergedLocation/$mergefile"); 
    }
}
header("Location: formpage.php$result");

That's all off the top of my head so there'll be errors I'm sure. But I don't think it's far off what you need.

Thanks so much diafol.
I will give this a shot and report back!

I am such a noob, could you help point me in the right direction.
Here is where I am working from PDF TEST MERGE
I could post my source code if that would help.

Member Avatar for diafol

Yes, that page doesn't really show anything with regard to the workings.

Here is my tables page with the options.

<?php
$tablerows = '';
foreach (glob("*.pdf") as $file_name) {
   $tablerows .= 
    "<tr>
        <td><input type='checkbox' name='pdfs[]' value='$file_name' /><td>
        <td>$file_name</td>
    </tr>"; 

}
?>
<form method="post" action="handlepdfs.php">
    <table>
        <?php echo $tablerows;?>
    </table>
    <label for = "newfilename">Name of pdfs:</label>

    <table width="300" border="1">
  <tbody>
    <tr>
      <td><input type="checkbox" id="newfilename" name="newfilename" />1</td>
      <td><input type="checkbox" id="newfilename" name="newfilename" /> 2</td>
    </tr>
    <tr>
      <td><input type="checkbox" id="newfilename" name="newfilename" />3</td>
      <td><input type="checkbox" id="newfilename" name="newfilename" /> 4</td>
    </tr>
    <tr>
      <td><input type="checkbox" id="newfilename" name="newfilename" />5</td>
      <td><input type="checkbox" id="newfilename" name="newfilename" /> 6</td>
    </tr>

  </tbody>
</table>

    <input type="submit" value="Merge Selected PDFs" />
</form>    

And here is the handspdfs.php

<?php

$result="?result=0";
if(isset($_POST['pdfs']) && isset($_POST['newfilename']) && trim($_POST['newfilename']))
{
    include 'PDFMerger.php';
    $merger = new PDFMerger;
    $location = "samplepdfs";
    $mergedLocation = "mergedpdfs";
    $pdfs = (array) $_POST['pdfs'];
    foreach($pdfs as $pdf)
    {
        if(file_exists($location/$pdf))
        {
            $merger->addPDF("$location/$pdf", 'all');
        }    
    }
    //you need to clean the filename to make sure its ok before next bit
    $mergefile = trim($_POST['newfilename']) . time() . ".pdf";
    $merger->merge('file', "$mergedLocation/$mergefile");
    if(file_exists("$mergedLocation/$mergefile"))
    {
        $result="?result=1&file=" . urlencode("$mergedLocation/$mergefile"); 
    }
}
header("Location: formpage.php$result");

Also here is PDFMerger.php didnt know if it might help

<?php
/**
 *  PDFMerger created by Jarrod Nettles December 2009
 *  jarrod@squarecrow.com
 *  
 *  v1.0
 * 
 * Class for easily merging PDFs (or specific pages of PDFs) together into one. Output to a file, browser, download, or return as a string.
 * Unfortunately, this class does not preserve many of the enhancements your original PDF might contain. It treats
 * your PDF page as an image and then concatenates them all together.
 * 
 * Note that your PDFs are merged in the order that you provide them using the addPDF function, same as the pages.
 * If you put pages 12-14 before 1-5 then 12-15 will be placed first in the output.
 * 
 * 
 * Uses FPDI 1.3.1 from Setasign
 * Uses FPDF 1.6 by Olivier Plathey with FPDF_TPL extension 1.1.3 by Setasign
 * 
 * Both of these packages are free and open source software, bundled with this class for ease of use. 
 * They are not modified in any way. PDFMerger has all the limitations of the FPDI package - essentially, it cannot import dynamic content
 * such as form fields, links or page annotations (anything not a part of the page content stream).
 * 
 */
class PDFMerger
{
    private $_files;    //['form.pdf']  ["1,2,4, 5-19"]
    private $_fpdi;

    /**
     * Merge PDFs.
     * @return void
     */
    public function __construct()
    {
        require_once('fpdf/fpdf.php');
        require_once('fpdi/fpdi.php');
    }

    /**
     * Add a PDF for inclusion in the merge with a valid file path. Pages should be formatted: 1,3,6, 12-16. 
     * @param $filepath
     * @param $pages
     * @return void
     */
    public function addPDF($filepath, $pages = 'all')
    {
        if(file_exists($filepath))
        {
            if(strtolower($pages) != 'all')
            {
                $pages = $this->_rewritepages($pages);
            }

            $this->_files[] = array($filepath, $pages);
        }
        else
        {
            throw new exception("Could not locate PDF on '$filepath'");
        }

        return $this;
    }

    /**
     * Merges your provided PDFs and outputs to specified location.
     * @param $outputmode
     * @param $outputname
     * @return PDF
     */
    public function merge($outputmode = 'browser', $outputpath = 'newfile.pdf')
    {
        if(!isset($this->_files) || !is_array($this->_files)): throw new exception("No PDFs to merge."); endif;

        $fpdi = new FPDI;

        //merger operations
        foreach($this->_files as $file)
        {
            $filename  = $file[0];
            $filepages = $file[1];

            $count = $fpdi->setSourceFile($filename);

            //add the pages
            if($filepages == 'all')
            {
                for($i=1; $i<=$count; $i++)
                {
                    $template   = $fpdi->importPage($i);
                    $size       = $fpdi->getTemplateSize($template);

                    $fpdi->AddPage('P', array($size['w'], $size['h']));
                    $fpdi->useTemplate($template);
                }
            }
            else
            {
                foreach($filepages as $page)
                {
                    if(!$template = $fpdi->importPage($page)): throw new exception("Could not load page '$page' in PDF '$filename'. Check that the page exists."); endif;
                    $size = $fpdi->getTemplateSize($template);

                    $fpdi->AddPage('P', array($size['w'], $size['h']));
                    $fpdi->useTemplate($template);
                }
            }   
        }

        //output operations
        $mode = $this->_switchmode($outputmode);

        if($mode == 'S')
        {
            return $fpdi->Output($outputpath, 'S');
        }
        else
        {
            if($fpdi->Output($outputpath, $mode))
            {
                return true;
            }
            else
            {
                throw new exception("Error outputting PDF to '$outputmode'.");
                return false;
            }
        }


    }

    /**
     * FPDI uses single characters for specifying the output location. Change our more descriptive string into proper format.
     * @param $mode
     * @return Character
     */
    private function _switchmode($mode)
    {
        switch(strtolower($mode))
        {
            case 'download':
                return 'D';
                break;
            case 'browser':
                return 'I';
                break;
            case 'file':
                return 'F';
                break;
            case 'string':
                return 'S';
                break;
            default:
                return 'I';
                break;
        }
    }

    /**
     * Takes our provided pages in the form of 1,3,4,16-50 and creates an array of all pages
     * @param $pages
     * @return unknown_type
     */
    private function _rewritepages($pages)
    {
        $pages = str_replace(' ', '', $pages);
        $part = explode(',', $pages);

        //parse hyphens
        foreach($part as $i)
        {
            $ind = explode('-', $i);

            if(count($ind) == 2)
            {
                $x = $ind[0]; //start page
                $y = $ind[1]; //end page

                if($x > $y): throw new exception("Starting page, '$x' is greater than ending page '$y'."); return false; endif; 

                //add middle pages
                while($x <= $y): $newpages[] = (int) $x; $x++; endwhile;
            }
            else
            {
                $newpages[] = (int) $ind[0];
            }
        }

        return $newpages;
    }

}
Member Avatar for diafol

Look closely at what my code does and then at your code. I think you'll see that you've confused a few terms. Your code seems to be all over the place. I honestly don't know what to suggest other than look at it again.

Well, even I have been using PDF merger but I have not face any problem with it. It work great and it allow selecting page range as well as you can deselect them and then you can merge multiple PDFs into single one.

Member Avatar for diafol

Glad you resurrected this dead thread to share that.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.