FPDF not writing on all pages - php

Hi I'm using FPDF and FPDI, I'm using FPDI to concatenate several PDFs then using FPDF to fill in the information based on a form that is filled out, I've setup a SetPage method within FPDF to be able to set the page on which I'm working on, I'm able to write on the first file completely fine (first 3 pages). However, when I'm trying to write on the second file (4th and continuing pages), I use the SetXY and Write but nothing is written, I am able to add an image (barcode at the bottom of the page) but no text, any ideas as to what I'm doing wrong?
This is the code that I've got to concatenate the files:
<?php
session_start();
require_once('lib/pdf/fpdf.php');
require_once('lib/pdi/fpdi.php');
require_once('lib/barcode/class/BCGFontFile.php');
require_once('lib/barcode/class/BCGColor.php');
require_once('lib/barcode/class/BCGDrawing.php');
require_once('lib/barcode/class/BCGcode39extended.barcode.php');
$contractType = $_SESSION['addition'];
require_once('barcode.php');
if(isset($contractType))
{
$files = array('lib/blank/NDA.pdf');
if($contractType = 'artist')
{
array_push ($files,
'lib/blank/Distro.pdf',
'lib/blank/Management-Trial.pdf'
);
} else {
echo "Whoops! Something must've happened when you were filling out your contracts! Please try filling them out again. Sorry!";
}
}
$pdf = new FPDI();
foreach ($files AS $file) {
$pageCount = $pdf->setSourceFile($file);
for($n = 1; $n <= $pageCount; $n++) {
$tmpIdx = $pdf->importPage($n);
$size = $pdf->getTemplateSize($tmpIdx);
if($size['w'] > $size['h']) {
$pdf->AddPage('L', array($size['w'], $size['h']));
} else {
$pdf->AddPage('P', array($size['w'], $size['h']));
}
$pdf->useTemplate($tmpIdx);
}
}
//NDA FILLER
include('lib/filler/NDA.php');
//Distro Contract Filler
include('lib/filler/Distro.php');
//session_unset();
$pdf->Output();
?>
This is the code for filling out the first PDF (which works completely fine):
NDA.php
<?php
//ID No.
$idcoded = 'idbars/'.$_SESSION['name'].'.png';
/*
for($p = 2; $p <= $pages; $p++)
{
$pdf->Image($idcoded,0,350);
$pdf->setPage($p);
}
*/
$pdf->SetPage(1);
$pdf->Image($idcoded,0,350);
$pdf->SetFont('Helvetica');
$pdf->SetTextColor(255, 0, 0);
//NDA DATE
$pdf->SetXY(51, 109.5);
$pdf->Write(0, date(d));
$pdf->SetXY(72, 109.5);
$pdf->Write(0, date(F));
//Legal Name
$pdf->SetXY(72, 114.5);
$pdf->Write(0, $_SESSION['name']);
//stage Name
$pdf->SetXY(80, 119.5);
$pdf->Write(0, $_SESSION['sname']);
$pdf->setPage(2);
$pdf->Image($idcoded,0,350);
$pdf->setPage(3);
$pdf->Image($idcoded,0,350);
$signature = 'idbars/'.$_SESSION['name'].'_sig.png';
$pdf->Image($signature,20,105,100);
?>
This is what I'm using to try to write on the second PDF, I've tried combining the NDA.php and Distro.php into one file and that makes no difference
Distro.php
<?php
$pdf->SetPage(4);
$pdf->SetXY(10,10);
$pdf->Cell(0, $_SESSION['name']);
$pdf->Write(0, $_SESSION['name']);
$pdf->Image($idcoded,0,350);
?>
The page that this is building works off of this form:
https://secure.gr8label.com/sign/artist/Dev%20Test/

FPDF "caches" the font information that is currently used. As you jump back to another page FPDF "thinks" that the font is already defined/set but in the PDF file itself it isn't. You should set your font and size in your import loop, to ensure that the font is available on all pages (I think it also could work, by defining it only on the first one).
Anyhow you should have seen that jumping between written pages results in problems and you should create a logic which creates the file from top to bottom without using things like "SetPage()" at all.

Related

FPDF PHP - Line is not working properly in second page

Following is my code which prints "HELLO", then a dotted line. This thing gets repeated 50 times. Everything is working fine but when 2nd page starts, dotted lines disappear. What modification is required in this code?
<?php
require("fpdf.php");
class PDF extends FPDF
{
function SetDash($black=null, $white=null)
{
if($black!==null)
$s=sprintf('[%.3F %.3F] 0 d',$black*$this->k,$white*$this->k);
else
$s='[] 0 d';
$this->_out($s);
}
}
$pdf = new PDF('P', 'mm', 'A4');
$pdf->AliasNbPages();
$pdf->AddPage();
$margin = 0;
$pdf->SetFont('Arial','B',12);
for ($i = 0; $i < 50; $i++)
{
$pdf->Cell(90, 10, "Hello", 0, 1);
$pdf->SetDrawColor(0,0,0);
$pdf->SetDash(2,2);
$margin = $margin + 10;
$pdf->Line(10,$margin,200,$margin);
}
$pdf->Output();
?>
You're incrementing the value of your $margin variable by 10 after each line even if a page break occurs in the middle of the loop. Thus, the top margin of the first line on the second page will be 10 millimeters greater than the top margin of the last line on the first page.
You need to reset the margin when a new page is added.
A solution for this problem would be to override FPDF's AcceptPageBreak method. This method intercepts the adding of a new page when the bottom of a page is reached.
class PDF extends FPDF
{
var $lineY = 0;
// ...
function AcceptPageBreak()
{
$this->lineY = 0;
return parent::AcceptPageBreak();
}
}
Then, in your loop, you can do:
$pdf->Line(10, $pdf->lineY, 200, $pdf->lineY);

Need help on FPDI & TCPDF: page 1 of output pdf will use the first page of the template, the next pages will use the second page of the template

I am trying to create an invoice document and display the items in pdf.
The problem I have is that the first page will use a pdf template(Using FPDI) that has the Company logo, company information and the list of items bought.
If the list of items will require more than one page, the next pages will need to use second page of pdf template that only shows the company logo as a header and the continuation of the items bought. Below is my sample code. I also tried to extend the fpdi based on this SO post but I cant make it work.
$pdf = new FPDI();
ob_start();
echo $this->view->print_invoice($productItems, $customerInfo);
$content = ob_get_contents();
ob_clean();
// add a page
$pdf->addPage();
$pdf->writeHTML($content);
$pageCount = $pdf->setSourceFile(ROOT_DIR . "public/pdf-templates/group.pdf");
$tplIdx = $pdf->importPage(1, '/MediaBox');
$pdf->useTemplate($tplIdx, 10, 10, 190, 280);
$pdf->Output('outfile.pdf','I');
Thanks in advance for your help!
Just implement the logic you describe in a header() method of an extending class:
class PDF extends FPDI
{
public function Header()
{
if ($this->PageNo() > 1) {
$tplIdx = $this->importPage(2);
} else {
$tplIdx = $this->importPage(1);
}
$this->useTemplate($tplIdx);
}
}
ob_start();
echo $this->view->print_invoice($productItems, $customerInfo);
$content = ob_get_contents();
ob_clean();
$pdf = new PDF();
$pdf->setSourceFile(ROOT_DIR . "public/pdf-templates/group.pdf");
$pdf->addPage();
$pdf->writeHTML($content);
$pdf->Output('outfile.pdf','I');

php barcode - display multiple barcode in single page

I created a php page that print the barcode. Just to view it before i print it on an A4. Still in testing phase. The codes are as below.
<?php
include('include/conn.php');
include('include/Barcode39.php');
$sql="select * from barcode where b_status = 'NOT-PRINTED'";
$result=mysqli_query($conn,$sql);
echo mysqli_num_rows($result);
$i=0;
while($row=mysqli_fetch_assoc($result)){
$acc_no = $row["b_acc_no_code"];
$bc = new Barcode39($row["b_acc_no_code"]);
echo $bc->draw();
$bc->draw($acc_no.$i.".jpg");
echo '<br /><br />';
$i++;
}
?>
Without the while loop, it can be printed, but only one barcode. How to make it generate, for example in the database have 5 values, it will print 5 barcode in the same page. Thanks in advance
Try to use another bar code source. Because It is generate only one bar code per page. Can't able to create multiple bar code per page.
I know this is an older post but comes up in searches so is probably worth replying to.
I have successfully used the Barcode39 to display multiple barcodes. The trick is to get base64 data from the class and then display the barcodes in separate HTML tags.
The quickest way to do this is to add a $base64 parameter to the draw() method:
public function draw($filename = null, $base64 = false) {
Then, near the end of the draw() method, modify to buffer the imagegif() call and return the output in base64:
// check if writing image
if ($filename) {
imagegif($img, $filename);
}
// NEW: Return base 64 for the barcode image
else if ($base64) {
ob_start();
imagegif($img);
$image_data = ob_get_clean();
imagedestroy($img);
return base64_encode($image_data);
}
// display image
else {
header("Content-type: image/gif");
imagegif($img);
}
Finally, to display multiples from the calling procedure, construct the image HTML in the loop and display:
// assuming everything else has been set up, end with this...
$base64 = $barcode->draw('', true); // Note the second param is set for base64
$html = '';
for ($i = 0; $i < $numBarcodes; $i++) {
$html .= '<img src="data:image/gif;base64,'.$base64.'">';
}
die('<html><body>' . $html . '</body></html>');
I hope this helps anyone else facing this challenge.

How do I print a barcode using barcode generator for PHP onto a pdf formatted page where I want it?

Alright so first things first:
I've searched over this site for 6+ hours and I keep coming up with the same results. The main answer I keep getting is: How to Generate Barcode using PHP and Display it as an Image on the same page
But this is not working for me. Even the answer on that page that was accepted ends with "After you have added all the codes, you will get this way:" which is so vague I feel like I'm supposed to already be an expert to understand it. I'm getting frustrated with this problem because I cannot seem to find any "moron directions" that can help me understand how everything works in this library for barcode generator for php.
Here is what I have:
I'm using fpdf to print a pdf file which works great!
Page Name: PrintMyPDF.php
<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
$thisorderID = $_GET['Xort'];
require ('UFunctions.php');
if (trim($thisorderID) == ""){
$value = '0';
}
if (!is_digit($thisorderID) || $thisorderID < 0)
{
header('Location:ErrorInt.php');
exit;
}
//Database connection established
require_once('DBASEConnector.php');
$sql2 = "SELECT users.name, users.storenum, users.storename, Orders.OrderID, Orders.name
FROM users, Orders
WHERE Orders.name = users.name
AND Orders.OrderID = '$thisorderID'";
$result = $db->query($sql2);
$row = $result->fetch_assoc();
$ThisStoreNum = $row['storenum'];
$ThisStoreName = $row['storename'];
require('fpdf.php');
$pdf = new FPDF();
//$fpdf->SetMargins(0, 0, 0);
//$fpdf->SetAutoPageBreak(true, 0);
$pdf->SetAuthor('Walter Ballsbig');
$pdf->SetTitle('Order Form');
$pdf->SetFont('Helvetica','B',16);
$pdf->SetTextColor(0,0,0);
$pdf->AddPage('P');
$pdf->SetDisplayMode(real,'default');
$pdf->SetXY(50,20);
$pdf->SetDrawColor(0,0,0);
$pdf->Cell(100,10,'Order Form',1,1,'C',0);
$pdf->SetFontSize(10);
$pdf->SetX(50);
$pdf->Cell(100,10, 'Order: '.$thisorderID.' | Store: '.$ThisStoreNum.'-'.$ThisStoreName,1,1,'C',0);
$pdf->SetXY(10,50);
$pdf->SetFontSize(12);
$pdf->Cell(6,6,'X',1,0,'C',0);
$pdf->Cell(14,6,'QTY',1,0,'C',0);
$pdf->Cell(130,6, 'ITEM',1,0,'C',0);
$pdf->Cell(30,6, 'UNIT',1,1,'C',0);
$query = "SELECT Inventory.ProductI, Inventory.ProductName, Inventory.CurrentQty, Inventory.Pull, Inventory.Unit, OrderItems.ProductI, OrderItems.QtyO, OrderItems.OrderI
FROM Inventory, OrderItems
WHERE OrderItems.OrderI = '$thisorderID'
AND OrderItems.ProductI = Inventory.ProductI
ORDER BY Inventory.Pull, Inventory.ProductName";
$result = $db->query($query);
$num_results = $result->num_rows;
for ($i=0; $i <$num_results; $i++)
{
$row = $result->fetch_assoc();
$pdf->SetFontSize(12);
IF ($row['CurrentQty'] <=0)
{
$pdf->SetFontSize(10);
$pdf->Cell(6,6,'BO',1,0,'C',0);
$pdf->SetFontSize(12);
}else{
$pdf->Cell(6,6,' ',1,0,'C',0);
}
$pdf->Cell(14,6, $row['QtyO'],1,0,'C',0);
$pdf->Cell(130,6, $row['ProductName'],1,0,'L',0);
$pdf->Cell(30,6, $row['Unit'],1,1,'C',0);
}
$pdf->Output();
$db->close();
?>
This prints up my pdf beautifully! Now I wanted to add a barcode on the page that will represent the order number for scanning purposes.
Now here is what I have for my code that contains the barcode... code.
Name of barcode page: BarCodeIt.php
<?php
function BarCodeIt($MyID) {
// Including all required classes
require_once('./class/BCGFontFile.php');
require_once('./class/BCGColor.php');
require_once('./class/BCGDrawing.php');
// Including the barcode technology
require_once('./class/BCGcode39.barcode.php');
// Loading Font
$font = new BCGFontFile('./font/Arial.ttf', 18);
// Don't forget to sanitize user inputs
$text = isset($_GET['text']) ? $_GET['text'] : $MyID;
// The arguments are R, G, B for color.
$color_black = new BCGColor(0, 0, 0);
$color_white = new BCGColor(255, 255, 255);
$drawException = null;
try {
$code = new BCGcode39();
$code->setScale(2); // Resolution
$code->setThickness(30); // Thickness
$code->setForegroundColor($color_black); // Color of bars
$code->setBackgroundColor($color_white); // Color of spaces
$code->setFont($font); // Font (or 0)
$code->parse($text); // Text
} catch(Exception $exception) {
$drawException = $exception;
}
/* Here is the list of the arguments
1 - Filename (empty : display on screen)
2 - Background color */
$drawing = new BCGDrawing('', $color_white);
if($drawException) {
$drawing->drawException($drawException);
} else {
$drawing->setBarcode($code);
$drawing->draw();
}
//Header that says it is an image (remove it if you save the barcode to a file)
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="barcode.png"');
// Draw (or save) the image into PNG format.
$drawing->finish(BCGDrawing::IMG_FORMAT_PNG);
}
?>
Now in my PDF file just before this line:
$pdf->Output();
I have added this:
$pdf->AddPage('P');
$pdf->SetDisplayMode(real,'default');
require('/BarCodeIt.php');
$MyBarCode = BarCodeIt($thisorderID);
echo $MyBarCode;
But what it does is all of my other pdf elements disappear and I'm left with only a big barcode (the right one! that part works) but that's all that is on the screen. It's like when the barcode section runs it negates everything else and just prints the barcode. I want to print just the barcode where I want it on the PDF but I'm not clever enough to figure out what I'm doing wrong. Any help on this would be greatly appreciated.
In $pdf->SetDisplayMode(real,'default');, real is not an identifier. I believe you've forgotten the $ prefix.
Have you warnings reporting at maximum level? If not, include:
error_reporting(E_ALL);
in your script and see that it shows additional issues.
I'm not familiar with fpdf, but what you are doing seems wrong just by looking at it: Everywhere you add elements to your pdf by using methods on your $pdf object like $pdf->... and when you want to add the barcode, you echo it out directly.
Don't echo your image out. Instead get rid of the header() calls in your barcode script, save your image and look for the right method to add an image to the $pdf object.
Here is a question with answers that deals with adding an image: Inserting an image with PHP and FPDF

TCPDF and FPDI with multiple pages

This looks like the simplest thing but I can't get it to work.
I need to add text to the first page of a multi-page pdf (could be any number of pages)
Using this code on a two page pdf (without the for loop, just using $pdf->importPage(2)) I end up with two pages but the second page is a repeat of page one. The text is written on the first page only which is good but I need all pages included in the output pdf. Here is my code
// Original file with multiple pages
$fullPathToFile = 'full/path/to/file.pdf';
class PDF extends FPDI {
var $_tplIdx;
function Header() {
global $fullPathToFile;
if (is_null($this->_tplIdx)) {
$this->setSourceFile($fullPathToFile);
$this->_tplIdx = $this->importPage(1);
}
$this->useTemplate($this->_tplIdx);
}
function Footer() {}
}
// initiate PDF
$pdf = new PDF();
$pdf->setFontSubsetting(true);
// add a page
$pdf->AddPage();
// The new content
$pdf->SetFont("helvetica", "B", 14);
$pdf->Text(10,10,'Some text here');
// How to get the number of pages of original pdf???
// $numPages = $pdf->getNumPages(???);
// Carry on adding all remaining pages starting from page 2
for($i=2;$i<=$numPages;$i++) {
// Add another page
$pdf->AddPage();
// Do I need to declare the source file here?
// $pdf->setSourceFile($fullPathToWD);
$pdf->importPage($i);
}
// Output the file as forced download
$pdf->Output('theNewFile.pdf', 'D');
Links to docs
TCPDF Classes
http://www.tcpdf.org/doc/code/classTCPDF.html#a5171e20b366b74523709d84c349c1ced
FPDI Classes
http://www.setasign.de/support/manuals/fpdi/
FPDF_TPL Classes
http://www.setasign.de/support/manuals/fpdf-tpl/
Solved my problem...
// Original file with multiple pages
$fullPathToFile = 'full/path/to/file.pdf';
class PDF extends FPDI {
var $_tplIdx;
function Header() {
global $fullPathToFile;
if (is_null($this->_tplIdx)) {
// THIS IS WHERE YOU GET THE NUMBER OF PAGES
$this->numPages = $this->setSourceFile($fullPathToFile);
$this->_tplIdx = $this->importPage(1);
}
$this->useTemplate($this->_tplIdx);
}
function Footer() {}
}
// initiate PDF
$pdf = new PDF();
$pdf->setFontSubsetting(true);
// add a page
$pdf->AddPage();
// The new content
$pdf->SetFont("helvetica", "B", 14);
$pdf->Text(10,10,'Some text here');
// THIS PUTS THE REMAINDER OF THE PAGES IN
if($pdf->numPages>1) {
for($i=2;$i<=$pdf->numPages;$i++) {
$pdf->endPage();
$pdf->_tplIdx = $pdf->importPage($i);
$pdf->AddPage();
}
}
// Output the file as forced download
$pdf->Output('theNewFile.pdf', 'D');
You get the number of pages by adding the first part of this line
$this->numPages = $this->setSourceFile($fullPathToFile);
And see the second last block of code - the for loop adds the remainder of the pages.
Don't know if this is how it should be done? I read in a few places that it wasn't even possible to achieve this, also the code is not supplied in the docs. However, this works, hope it helps someone.
I struggled with this a little and tried to come up with simplest way to add some text to the last page of a multi-page document. Here is the very simple code that worked for me:
require_once('fpdf/fpdf.php');
require_once('fpdf/fpdi.php');
$pdf = new FPDI();
$fullPathToPDF = '/usr/local/common/my.pdf';
$pageCount = $pdf->setSourceFile($fullPathToPDF);
for ($i = 1; $i <= $pageCount; $i++) {
$pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($i);
}
$pdf->SetFont('Helvetica');
$pdf->SetXY(110, 225);
$pdf->Write(8, 'A complete document imported with FPDI');
$pdf->Output($fullPathToPDF);
Just change the full path to file to a location where you have a multi-page PDF.
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
...
$pdf->SetMargins(10, 10, 10);
$pdf->SetAutoPageBreak(true, 10);
foreach($array as $item)
{
$pdf->AddPage(); //add new page for new item
$txt = some_long_long_text;
$pdf->Write(0, $txt, '', 0, 'C', true);
$pdf->endPage(); //do end of page
$pdf->lastPage(); //set cursor at last page, because autopagebreak not do it
}
In example, you have 10 pupils in array, and you need create resume for each. In exam, one resume have 3 pages. So in out u get pdf with 30 pages, with correct text.
SetAutoPageBreak(true, 10), not set cursor at last page, so you need to do it manually with function $pdf->lastPage();
that code wont work, try this:
$pdf = new PDI();
$pdf->AddPage();
$pdf->setSourceFile('zzz.pdf');
$pdf->numPages = $pdf->setSourceFile('zzz.pdf');
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 10, 20, 200);
if($pdf->numPages>1) {
for($i=2;$i<=$pdf->numPages;$i++) {
$pdf->AddPage();
$tplIdx = $pdf->importPage($i);
$pdf->useTemplate($tplIdx, 10, 20, 200);
}
}

Categories