php-pdftk icon indicating copy to clipboard operation
php-pdftk copied to clipboard

Example of creating Bookmarks for pdf merge

Open yannicklin opened this issue 5 years ago • 2 comments

I know it's possible to making bookmarks with multiple pdf files merging via PDFtk direct. Is this possible via php-pdftk? If yes, can you do a small demo for me? For example, I have three (or more) pdf files, PDF1 is 4 pages, and PDF2 is 3 pages, and PDF3 is 2 Pages, is it possible to create the merged file with bookmarks indicated PDF2 is from Page5 (to Page7), and PDF3 is from Page8 (to Page9) ?

yannicklin avatar Mar 30 '20 01:03 yannicklin

It should probably work with updateInfo() somehow. I can not give you an example though as I've never done that before either. If you find out if and how it works, I can add a little example to the README.

I would start by analyzing a PDF file that already has bookmarks with getData(). The bookmark data should be there somewhere. Then try to pass similar data to updateInfo() on a new file without any bookmarks.

mikehaertl avatar Mar 30 '20 07:03 mikehaertl

The way I did is to create a temporary book mark, and then put the path of this bookmark.

Make up the initial head

$bookmarks_sample = "InfoBegin\nInfoKey: Title\nInfoValue: PriceList\nInfoBegin\nInfoKey: Author\nInfoValue: Yannick\nBookmarkBegin\nBookmarkTitle: Price List @ ".date('Ymd')."\nBookmarkLevel: 1\nBookmarkPageNumber: 1\n";`

Then the each section of bookmark is

foreach ($results as $lv1Category)
        {
            /* Combine Cover and PriceList , and then encrypt */
            .....CODES IGNORED.....

            // Start to build BookMark
            $bookmarks_sample .= "BookmarkBegin\nBookmarkTitle: ".$lv1Category['name']."\nBookmarkLevel: 2\nBookmarkPageNumber: ".(int)$initPage."\n";

            // Count the total pages so far
            $tmppdf = new FSpdftk($category_filename);
            $tmppdf_info = (array) $tmppdf->getData()->__toArray();

            $initPage += (int) $tmppdf_info['NumberOfPages'] ;
            unset($tmppdf, $tmppdf_info);
}

 /* Combine Cover and PriceList , and then encrypt */
        $bookmark_filename = str_replace('.pdf', '_bmk.txt', $filename);
        file_put_contents($bookmark_filename, $bookmarks_sample);

        $pdf_final = new FSpdftk();
        $pdf_final->pdfCombine_Encrypt($arrLv1CategoryFiles, $filename, true, 'Yannick001', '', $bookmark_filename);

The class "FSpdftk" is I extended from original PDF class

class FSpdftk extends Pdf
{
    public function pdfCombine_Encrypt($arraySource, $resultFile, $compress, $owner_pswd = null, $user_pswd = null, $bookmark = null)
    {
        $tmpFile = str_replace('.pdf','_tmp.pdf', $resultFile);

        if (isset($bookmark) ) {
            $tmppdf = new Pdf($arraySource);
            $tmppdf ->saveAs($tmpFile);
            $pdf = new Pdf($tmpFile);
            $pdf ->updateInfo($bookmark) // Add BookMarks
                ->allow('Printing')      // Change permissions
                ->compress($compress); // Compress/Uncompress
        } else {
            $pdf = new Pdf($arraySource);
            $pdf ->allow('Printing')      // Change permissions
                ->compress($compress); // Compress/Uncompress
        }

        if (isset($owner_pswd) || isset($user_pswd)) {
            $pdf ->setPassword($owner_pswd)          // Set owner password
                ->setUserPassword($user_pswd)      // Set user password
                ->passwordEncryption(128)   // Set password encryption strength
                ->saveAs($resultFile);
        } else {
            $pdf ->saveAs($resultFile);
        }
        return $resultFile;
    }
}

I hope this mess of codes could help you to do the example.

yannicklin avatar Apr 06 '20 01:04 yannicklin