FPDF Footer on last page using If statement and {nb} - php

I have seen quite a few questions on this but not definitive answer. Im using FPDF to dynamically create PDF with values form a DB, I only want a footer on the last page, seeing as its values are based on DB values the PDF could be 2,3,4 pages long. So i started messing around with the footter of FPDF like so
function Footer()
{
$this->SetY(-15);
$this->SetFont('Arial','I',8);
//Page number
$pagenumber = '{nb}';
if($this->PageNo() == 2){
$this->Cell(173,10, ' FOOTER TEST - '.$pagenumber, 0, 0);
}
}
This retruns the value "FOOTER TEST - 2" on the second page and if i set the if to "<=2" will put the same on page one and two, GREAT! it recognises $pagenumber as 2 or if i had 3 pages as 3, so it can see that i have however many pages, however, when i change the code to:
function Footer()
{
$this->SetY(-15);
$this->SetFont('Arial','I',8);
//Page number
$pagenumber = '{nb}';
if($this->PageNo() == $pagenumber){
$this->Cell(173,10, ' FOOTER TEST - '.$pagenumber, 0, 0);
}
}
Thinking that it output the last page once, adding that to the if statement will make it work, it doesn't display anything, like the if statement cant recognize the value for $pagenumber, is this because it is a string or int trying to compare to the opposite or something else?
Any help greatly appropriated.
Ian

{nb} is done as a late replacement after you have finished writing (as it doesn't know how many pages there are before that) whereas the footer is output whenever a page is complete, your best bet is to probably set a flag on the class to true when you have finished outputting everything and then check the flag in the footer
function Footer()
{
$this->SetY(-15);
$this->SetFont('Arial','I',8);
//Page number
if($this->isFinished){
$this->Cell(173,10, ' FOOTER TEST - {nb}', 0, 0);
}
}
and then in your PDF writing code
...
$pdf->isFinished = true;
Hope this helps

I'm late to the party too - LOL Paul is on the right track. I amended his solution to work with a while loop.
$pdf = new PDF();
$pdf->isFinished = false;
$pdf->AddPage();
// Add your page contents here
while($row1 = $rs1->fetch_assoc()){
// output...
$pdf->isFinished = false;
}
$pdf->isFinished = true;
Now In the Footer...
function Footer()
{
$this->SetY(-15);
if($this->isFinished){
$this->Cell(195,10, "Signature:_______________________________", 0, 0,'R');
}
}
I hope this helps someone.

If you use MultiCell() and AutoPageBreak, the content you're writing may create an automatic page break.
In this case, setting a boolean flag before a MultiCell() call can create the last footer expected on the last two pages instead of the very last one only.
At the end of your code, when you don't have anything else to write in your document, do the following :
$this->InFooter = true;
$this->SetY(-15);
$this->Write(5, "My end footer text");
$this->InFooter = false;
InFooter boolean tells to FPDF that we are writing content in the Footer and FPDF will not automatically create a page break.
SetY() is needed otherwise your content will be written outside the document.

I know i'm a little late to the party here but when I ran into this same problem it was because I was not calling the AliasNbPages() function. The example they give doesn't seem to include this in their code !
I just call it right after I make a new pdf:
$pdf = new PDF();
$pdf->AliasNbPages();
Now my {nb} is replaced with the total number of pages !

For people stumbling upon this question many years later: Danny's answer above can also be used to skip the footer (or header) on any arbitrary page. You just need to make sure that you set your skip-Boolean to true after adding the page, then add the content, and set it back to false in case you want a footer on the next pages.
$pdf = new PDF();
$pdf->isFinished = false;
// [...]
$pdf->AddPage();
$pdf->isFinished = true;
// Add your page contents here
$pdf->isFinished = false;
I posted a longer version here.
I would have liked to add this as a comment to Danny's answer. However, being new and low on reputation, I had to post my own. :/

Your Main class:
$o_pdf->AddPage(); //need to add first and set isFinished true
$o_pdf->isFinished = true;
And your FPDF extended class:
if($this->isFinished) {
//your footer on last page
}
Hope this will be useful for you!!!

Related

Laravel wkhtmltopdf - text in the bottom of the last page

I'm generating an invoice PDF using laravel snappy wkhtmltopdf
and I'm tring to add some text in the bottom of the last page,
now i already have a footer-html with the number of the page.
I tried to show the content only in the last page with this way:
<!DOCTYPE html>
<div id="footer_text">
{!! nl2br($footer_text) !!}
</div>
<div class="pagination"><span id='page'></span> of <span id='topage'></span></div>
<script>
function remove(id) {
var elem = document.getElementById(id);
return elem.parentNode.removeChild(elem);
}
var vars={};
var x=window.location.search.substring(1).split('&');
for (var i in x) {
var z=x[i].split('=',2);
vars[z[0]] = unescape(z[1]);
}
document.getElementById('page').innerHTML = vars.page;
document.getElementById('topage').innerHTML = vars.topage;
if( vars.page != vars.topage && vars.topage > 1){
document.getElementById('footer_text').innerHTML = '';
remove('footer_text');
}
if(vars.topage == 1){
document.getElementById('pages').innerHTML = '';
}
</script>
and it does show me the text only in the last page BUT in the previous pages I have a big white space, here is a screenshot:
page number 1:
page number 2:
I feel like i tried everything, please help me
There is no issue with your script it might be some style issue. As you are removing footer_text in all previous pages and showing only on last page and this is somehow creating too much space. Check your CSS there must be margin-bottom or padding-bottom which is creating too much space. Enjoy!
Late to the party but looks like the ID footer_text will be set multiple times and ID's should be unique so I guess it would have worked if you used a class instead and getElementsByClassName
The footer height can't be dynamic on a different page when using Wkhtmltopdf. It's always with a static height. If this is your footer.html you have to add to your style:
body {height: 70px /for example/; position: relative;}
so you can align bottom (with position:absolute; bottom:0;) you #footer_text and content. But still, have some white space on all prev pages.
In the PDF generators, the footer content area is independent of the body content.

FPDF Get page numbers at footer on Every A4 size page

I am creating PDF reports using FPDF. Now how do I generate page numbers on each page of a report at the bottom of the page.
Below is the sample code for generating a 2 page PDF.
<?php
require('fpdf.php');
$pdf = new FPDF();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFont('Arial','',16);
$start_x=$pdf->GetX();
$current_y = $pdf->GetY();
$current_x = $pdf->GetX();
$cell_width = 25; $cell_height=14;
$j = 20; // This value will be coming from Database so we dont know how many pages the report is going to be
for ($i = 0; $i<$j ; $i++){
$pdf->MultiCell($cell_width,$cell_height,'Hello1',1);
$current_x+=$cell_width;
$pdf->Ln();
}
$pdf->Output();
?>
Note : The $j value will be coming from the database so we don't know how many pages is the report going to be.
To add an A4 page, with portrait orientation, do:
$pdf->AddPage("P","A4");
Create a new class which extends the FPDF class, and override the pre-defined Footer method.
Example:
class PDF extends FPDF
{
function Footer()
{
// Go to 1.5 cm from bottom
$this->SetY(-15);
// Select Arial italic 8
$this->SetFont('Arial','I',8);
// Print centered page number
$this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
}
}
According to my comment you can place
$pdf->PageNo();
on your page where ever you like. Also you can add a placeholder to this
$pdf->AliasNbPages();
What would look like
$pdf->AliasNbPages('{totalPages}');
By default it's {nb}. It's not necessary to add a placeholder
Than you could add the pagesum like
$pdf->Cell(0, 5, "Page " . $pdf->PageNo() . "/{totalPages}", 0, 1);
or without your own placeholder
$pdf->Cell(0, 5, "Page " . $pdf->PageNo() . "/{nb}", 0, 1);
this would produce e.g.
Page 1/10
in case there were 10 pages :)
But beware
Using the placeholder will mess up the width of the cell. So if you have e.g. 180 page-width than 90 isn't the mid anymore (In the line where you use the placeholder). You will see if you try :)

PHP mPDF library won't number even/odd pages properly

I'm trying to do some PDF generation in PHP. I found mPDF which generally has worked quite well. One problem I'm having though is that I need to be able to set separate headers for even/odd pages for some sections. I don't think the function is working right. Here's my code:
// load mPDF
// --------------------------------------------------------------------------
include('mpdf.php');
$mpdf = new mPDF();
// generate a lot of content so it spans multiple pages
// --------------------------------------------------------------------------
$i = 0;
$out = '';
while ($i < 300)
{
$i++;
$out .= '<p>Lorem Ipsum</p>';
}
// set html header for odd pages, write html and output
// --------------------------------------------------------------------------
$mpdf->SetHTMLHeader('ODD {PAGENO}', 'O');
$mpdf->WriteHTML($out);
$mpdf->Output();
When I run this code it puts "ODD Page 3" or whatever page it's on... on every page. Not just the odd pages. It seems to not consider naturally broken pages as new pages for the purposes of even or odd, only manually broken ones. If I run the AddPage() function it will consider the next group an even page. But that could be 50 auto page breaks later.
Any suggestions on how to get it to set different headers for actual even/odd pages, not just after manual page breaks?
your forget to write
$mpdf->mirrorMargins = 1;
here is your working example
<?php
include("../mpdf.php");
$mpdf=new mPDF('utf-8','A4');
$mpdf->debug = true;
$mpdf->mirrorMargins = 1 ;// Use different Odd/Even headers and footers and mirror margins
// generate a lot of content so it spans multiple pages
// --------------------------------------------------------------------------
$i = 0;
$out = '';
while ($i < 300)
{
$i++;
$out .= '<p>Lorem Ipsum</p>';
}
// set html header for odd pages, write html and output
// --------------------------------------------------------------------------
$mpdf->SetHTMLHeader('{PAGENO}/{nb}', 'O',true);
/* Note: SetHTMLHeader() and SetHTMLFooter() without a side(2nd argument)
- sets ODD page header/footer only as default..so you can also write just
$mpdf->SetHTMLHeader('{PAGENO}/{nb}'); */
$mpdf->WriteHTML($out);
$mpdf->Output();
exit;
?>
Reference:
setHTMLHeader

How to create FPDF tables?

I have a problem creating tables with fpdf.
Can anyone help me making this page (or at least tell me how to do it)?
invoice tables
Or can you show how to convert HTML tables to FPDF tables and put the code here?
I also have this (along with the connection to the database):
$person = mysql_fetch_array($result);
I would like this to function when added inside the tables with this = (example)
$pdf->Cell(0,260,''.$person["CA"],'C',0 ,1); --- .$person["CA"]
Can anyone help me?
Well, FPDF works kinda like a typewriter, in that it has a roving X,Y point which it writes to, which you can manually move around or let it do it for you.
I don't know if the huge whitespace at the left is required. If so, you'd have to call $this->SetX($coordinate) before each write.
You should do something like this:
class InvoicePDF extends FPDF //Create a new class to contain the header/footer/etc. which extends FPDF
{
public function Header()
{
//Header stuff goes here, like the big Invoice
$this->SetY(10); //SetY 10 units down from the top, experiment with distance to get appropriate distance
$this->SetFont('Arial','',20); //Set Font to Arial/Helvetica 20 pt font
$this->SetTextColor(0,0,0); //Set Text Color to Black;
$this->Cell(0,9,"INVOICE",0,0,'R'); //Write the word INVOICE Right aligned in a box the width of the page, will put it at the far right of the page
}
public function Footer()
{
//any footer stuff goes here
}
public function FillHeadInfo($info) //$info would be an array of the stuff to fill the small table at the top
{
$this->SetY(0); //reset the Y to the original, since we moved it down to write INVOICE
$this->SetFont('Arial','',12);
$this->SetFillColor(224,224,224); //Set background of the cell to be that grey color
$this->Cell(20,12,"Order #",1,0,'C',true); //Write a cell 20 wide, 12 high, filled and bordered, with Order # centered inside, last argument 'true' tells it to fill the cell with the color specified
$this->Cell(20,12,"Coding",1,0,'C',true);
$this->Cell(20,12,"Sales Code",1,1,'C',true); //the 1 before the 'C' instead of 0 in previous lines tells it to move down by the height of the cell after writing this
$this->Cell(20,12,$info['ordernum'],1,0,'C');
$this->Cell(20,12,$info['coding'],1,0,'C');
$this->Cell(20,12,$info['salescode'],1,1,'C');
$this->Cell(40,12,"Name & Address",1,0,'C',true);
$this->Cell(20,12,"Date",1,1,'C',true);
$y = $this->GetY(); //Need the current Y value to reset it after the next line, as multicell automatically moves down after write
$x = $this->GetX(); // Might need the X too
$this->MultiCell(40,12,$info['customername'] . "\n" . $info['address'] . "\n" . $info['city'] . ', ' . $info['state'] . ' ' . $info['zip'],1,'L',false); //I assume the customer address info is broken up into multiple different pieces
$this->SetY($y); //Reset the write point
$this->SetX($x + 40); //Move X to $x + width of last cell
$this->Cell(20,36,date("format",strtotime($info['date'])),1,1,'C'); //Might be easier to use $this->Rect() to draw rectangles for address and date and then write the address and date into them without borders using SetX and SetY, if the borders don't line up or whatever
}
public function fillItems($items)
{
//You'd build the items list much the same way as above, using a foreach loop or whatever
//Could also easily combine this function and the one above
}
}
Then, when creating the pdf you'd do something like this:
require_once('fpdf.php');
require_once('class.invoicepdf.php');
//Get whatever info you need to fill the pdf
$pdf = new InvoicePDF('P','mm','Letter');
$pdf->AddPage();
$pdf->FillHeadInfo($info); //Could also pass $_POST and rely on the keys of the $_POST array
$pdf->FillItems($items);
$pdf->Output('filename.pdf','I');
By the way, I'd suggest rather than trying to write it from $_POST, you save the order to the DB, then pass the order ID along to the script to write the pdf via a link and $_GET, and have the script retrieve the info from the DB, this way you can select only the info you need.

FPDF Header Question - Driving me crazy!

I am trying to generate a PDF that outputs Item Names onto a template PDF (using FPDI) with the Username listed on the top of each page. Every user can have a different number of items (i.e. if there are 1-4 items, only output one page; if there 5-8 items, output two pages, etc.)
Here is an example of what I am trying to do: http://www.mediafire.com/?k2ngmqm1jmm
This is what I have so far. I am able to get all of the spacing to work by setting a TopMargin, but this doesn't allow me to put the Username header in.
<?php
require_once('auth.php');
require_once('config.php');
require_once('connect.php');
$username=$_GET['username'];
$sql="SELECT * FROM $tbl_items WHERE username='$username'";
$result=mysql_query($sql);
require_once('pdf/fpdf.php');
require_once('pdf/fpdi.php');
$pdf =& new FPDI();
$pdf->SetTopMargin(30);
$pdf->AddPage('L', 'Letter');
$pdf->setSourceFile('../pdf/files/chart_template.pdf');
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx);
$pdf->SetTextColor(0,0,0);
$pdf->SetFont('Arial', 'B');
$pdf->SetFontSize(7);
while($rows=mysql_fetch_array($result)){
$pdf->Cell(20,5,$rows['itemname'],0,0,'C');
$pdf->Ln(45);
}
$pdf->useTemplate($tplIdx);
$pdf->Output('file.pdf', 'I');
?>
Please help!
I've done it previously using the 'header' class extension:
class PDF extends FPDF
{
function Header()
{
//Select Arial bold 15
$this->SetFont('Arial','B',15);
//Move to the right
$this->Cell(80);
//Framed title
$this->Cell(30,10,'Title',1,0,'C');
//Line break
$this->Ln(20);
}
Have a look at the tutorial which explains the header usage at : http://www.fpdf.org/en/tutorial/tuto2.htm

Categories