Search code examples
phppdflib

Copy PDFLib Block Layout


I have a pdf file with PDFlib blocks on it. None of these blocks have been filled. I need to copy those blocks, but not the page content, onto a set of other pdf documents, each with their own content. The blocks do not need to be filled.

The idea is each document is a form, but each varies slightly. The form fields are all in the same location, so we just need to copy the blocks, including their layout. I've already checked out this documentation page, which describes doing this on what seems to be a single document with blocks to a new (blank) document.

Any help is appreciated.


Solution

  • I worked up a PHP script to handle this. See below:

    try{
            # Create a new PDFLib instance
            $pdf = new PDFlib();
            $pdf->set_option('errorpolicy=return');
            $pdf->set_option('stringformat=utf8');
    
            # Create the optput document
            if(!($pdf->begin_document('','')))
                throw new Exception('Error: '.$pdf->get_errmsg());
    
            # Open the input document, in this case the block template file
            $block_file = $pdf->open_pdi_document('block_template.pdf','');
            if($block_file == 0) throw new Exception('Error: '.$pdf->get_errmsg());
    
            # Also open the target file we need to copy blocks to
            $target_file = $pdf->open_pdi_document('target_file.pdf','');
            if($target_file == 0) throw new Exception('Error: '.$pdf->get_errmsg());
    
            # Find the number of pages in the document
            $pages = $pdf->pcos_get_number($block_file,'length:pages');
    
            # Loop over each page
            for($page=0;$page<$pages;$page++){
    
                # Open the target file to clone its contents
                $target_input_page = $pdf->open_pdi_page($target_file,1,'');
                if($target_input_page == 0) throw new Exception('Error: '.$pdf->get_errmsg());
    
                # Create a blank PDF page with a dummy size
                $pdf->begin_page_ext(10,10,'');
    
                # Copy the contents of the input page to the new page. This also overrides the size set by the dummy page
                $pdf->fit_pdi_page($target_input_page,0,0,'adjustpage');
    
                # Count the blocks on this template file page
                $block_count = (int) $pdf->pcos_get_number($block_file, 'length:pages['.$page.']/blocks');
    
                # Loop over the blocks and copy them
                for($i=0;$i<$block_count;$i++){
                    $block_name = $pdf->pcos_get_string($block_file,'pages['.$page.']/blocks['.$i.'].key');
    
                    if ($pdf->process_pdi($block_file,0,'action=copyblock block={pagenumber='.($page+1).' blockname={'.$block_name.'}}') == 0)
                        throw new Exception("Error: " . $pdf->get_errmsg());
                }
    
                # End this page
                $pdf->end_page_ext('');
    
                # Close the pdf page
                $pdf->close_pdi_page($target_input_page);
            }
    
            # Close the PDF document
            $pdf->close_pdi_document($block_file);
            $pdf->close_pdi_document($target_file);
            $pdf->end_document('');
    
            # Get the output buffer
            $buffer = $pdf->get_buffer();
    
            # Write out the converted file
            $output_file = fopen('output_file.pdf','w+');
            fwrite($output_file,$buffer);
            fclose($output_file);
        }
        catch(PDFlibException $e){
            error_log("PDFlib exception occurred:\n" .
                "[" . $e->get_errnum() . "] " . $e->get_apiname() . ": " .
                $e->get_errmsg() . "\n");
            exit(1);
        }
        catch(Exception $e){
            error_log($e);
            exit(1);
        }