I am generating pdf invoice using fpdf.
Some invoices containing many items, and details need to go into the second page. However, I need the total, and other details
I ran into this issue by having a two-column layout, where one column could be so large it would span to the next page. I wanted to set the Y position back to the same Y position as the first column, so that they are aligned to the top of each other, but also continue the document under the largest of the two columns.
My solution was to record the "Vertical Position" of the document, which includes the Page Number ($pdf->PageNo()
) and the Y Position ($pdf->GetY()
).
You need to store two different vertical positions. First, store the "Starting point" which is where you will start your second column. Second, store the "Largest point" which is the furthest down the document. The largest point was tricky because you cannot look at page number or Y value alone, you must look at both.
I created these three methods to help me out.
This solution does not include X-position in the example.
public function GetVerticalPosition() {
// Include page and Y position of the document
return array(
'page' => $this->PageNo(),
'y' => $this->GetY(),
);
}
public function SetVerticalPosition( $pos ) {
// Set the page and Y position of the document
$this->page = $pos['page'];
$this->SetY( $pos['y'] );
}
public function FurthestVerticalPosition( $aPos, $bPos = null ) {
if ( $bPos === null ) $bPos = $this->GetVerticalPosition();
// Returns the "furthest" vertical position between two points, based on page and Y position
if (
($aPos['page'] > $bPos['page']) // Furthest position is located on another page
||
($aPos['page'] == $bPos['page'] && $aPos['y'] > $bPos['y'] ) // Furthest position is within the same page, but further down
) {
return $aPos;
}else{
return $bPos;
}
}
Usage is pretty straightforward. Before you draw your variable-height columns you need to grab the starting position, and start collecting the maximum position.
$startPos = $this->GetVerticalPosition();
$furthestPos = $this->GetVerticalPosition();
After rendering each cell, before rendering another cell on the same level, you want to update the furthest position (if needed), then set back to the starting position.
// Returns the furthest of the two possibilites
$furthestPos = $this->FurthestVerticalPosition( $this->GetVerticalPosition(), $furthestPos );
$this->SetVerticalPosition( $startPos );
When you finish rendering your columns, set the document to the maximum distance that you have recorded so far.
$this->SetVerticalPosition( $furthestPos );
Now your columns are properly aligned, and the document pointer is located immediately after the furthest-drawn column.