TCPDF / FPDF - Page break issue

18,921

The problem is that in the Cell() method (which is called in MultiCell()) FPDF allways adds a new page if the the current Y position + the height of the new cell is greater than the allowed page height.

The default page height seems to be 297, with SetAutoPageBreak() you substract 150 from it. So when Y + cell_height is graeter than 147 you allways get a new page when calling your cnstr_cell().

To prevent this you need to call AddPage() by yourself. Add this check in your add_product() method:

$x = $this->width;
$y = $this->pdf->GetY();

if (($y + $this->line_height) >= 147) {
    $this->pdf->AddPage();
    $y = 0; // should be your top margin
}

Btw. I also had to generate a dynamic PDF recently, I ended up using wkhtmltopdf, it was way more easy to use and customize than all the PHP libraries. I suggest to take a look at it.

Share:
18,921
clarkk
Author by

clarkk

https://dynaccount.dk https://dynaccount.dk/bogfoeringsprogram/ https://dynaccount.dk/regnskabsprogram/

Updated on July 19, 2022

Comments

  • clarkk
    clarkk almost 2 years

    I'm trying to create a PDF file with a table of data.. But when a page break is met it jumps to a new page everytime a new multicell is added to the page at the break point level..!?

    I have tried to do exactly the same with TCPDF, but still the same issue with a page break each time a new cell i added around the page break point level...

    example:

    http://www.online-økonomi.dk/_tst_fpdf.php

    require_once '../class/download/fpdf/fpdf.php';
    
    class File_PDF {
        private $pdf;
    
        private $col_product = 25;
        private $col_unit = 12;
        private $col_price = 20;
        private $col_count = 14;
        private $col_discount = 12;
        private $col_vat = 12;
        private $col_sum = 22;
    
        private $width = 200;
        private $line_height = 4.2;
        private $margin_top = 30;
    
        public function generate(){
            $this->pdf = new FPDF();
            $this->pdf->AddPage();
            $this->pdf->SetDisplayMode('real');
            $this->pdf->SetAutoPageBreak(true, 150);
    
            if($this->products){
                $i = 0;
                $this->color_light();
                foreach($this->products as $product){
                    $this->add_product($product, $i % 2 ? true:false);
                    $i++;
                }
            }
    
            $this->pdf->Output();
        }
    
        private function add_product($product, $fill){
            $this->txt();
    
            $x = $this->width;
            $y = $this->pdf->GetY();
    
            $this->cell_sum($this->col_sum, $x, $y, $product['sum'] / 100, 'R', $fill);
            $this->cell_vat($this->col_vat, $x, $y, $product['vat_percent'], 'R', $fill);
            $this->cell_discount($this->col_discount, $x, $y, $product['discount_percent'] / 100, 'R', $fill);
            $this->cell_count($this->col_count, $x, $y, $product['count'] / 100, 'R', $fill);
            $this->cell_price($this->col_price, $x, $y, $product['price'] / 100, 'R', $fill);
            $this->cell_unit($this->col_unit, $x, $y, $product['unit_name'], 'L', $fill);
            $this->cell_name(0, $x, $y, $product['name'], 'L', $fill);
            $this->cell_product($this->col_product, $x, $y, $product['product_id_'], 'L', $fill);
        }
    
        private function cell_sum($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_vat($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_discount($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_count($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_price($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_unit($width, &$x, $y, $str, $align, $fill=false){
            $this->cnstr_cell($width, $x, $y, $str, $align, $fill);
        }
    
        private function cell_name($width, &$x, $y, $str, $align, $fill=false){
            $this->pdf->SetXY($this->col_product + 10, $y);
            $this->pdf->MultiCell($x - $this->col_product - 10, $this->line_height, $str, 0, $align, $fill);
        }
    
        private function cell_product($width, &$x, $y, $str, $align, $fill=false){
            $this->pdf->SetXY(10, $y);
            $this->pdf->MultiCell($this->col_product, $this->line_height, $str, 0, $align, $fill);
        }
    
        private function cnstr_cell($width, &$x, $y, $str, $align='L', $fill=false){
            $x -= $width;
            $this->pdf->SetXY($x, $y);
            $this->pdf->MultiCell($width, $this->line_height, $str, 0, $align, $fill);
        }
    
        private function color_light(){
            $this->pdf->SetFillColor(200, 200, 200);
        }
    
        private function txt(){
            $this->pdf->SetFont('Arial', '', 8.5);
        }
    
        private function txt_marked(){
            $this->pdf->SetFont('Arial', 'B', 8.5);
        }
    
        private $products = array(
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                ),
            array(
                'product_id_' => 'ADS1550',
                'name' => 'name',
                'unit_name' => 'pcs',
                'price' => 182450000,
                'count' => 310000,
                'discount_percent' => 19900,
                'vat_percent' => 0,
                'sum' => 1587057200
                )
            );
    }
    
    $PDF = new File_PDF();
    $PDF->generate();
    
  • Tim Lewis
    Tim Lewis about 9 years
    Just an FYi, while reading this answer today, I noticed the link to wkhtmltopdf is broken.