I am trying to add a cell to an existing PDF, but unfortunately the document is a scan, which interprets it as one layer - a photo - I think so.
When adding a cell to such a file, I only have borderless text and no cell fill color on the visible layer of the document.
Am I in any way controlling the layers of the file in such a way that the cell being added is always the top layer and is fully visible?
Method to get existing PDF:
protected function getOldPDF()
{
$pdf = new Fpdi();
$pdf->SetCreator('Test');
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetMargins(0, 0);
$numPages = $pdf->setSourceFile($this->filePath);
for($pageNum = 1; $pageNum <= $numPages; $pageNum++) {
$tpl = $pdf->importPage($pageNum);
$pdf->AddPage();
$pdf->useTemplate($tpl);
}
return $pdf;
}
I add cells with TCPDF::MultiCell()
Related
I've created a PDF generator thanks to FPDF, it uses data from a mysql database and works very well. Number of pages is variable.
Then I wanted to add to every of this PDF some pages imported from other PDF files. Number of added page and adress of imported file are variable too.
It works very well, excepted that my Footer doesn't appear anymore. I want to keep this Footer on every page, the ones created by the generator and the ones imported. Can someone tell me where is the problem?..
This i my code :
require_once('gpdf/fpdf.php');
require_once('gpdf/fpdi.php');
class PDF extends FPDI
{
function Header()
{
}
function Footer()
{
// Positionnement à 1,5 cm du bas
$this->SetY(-15);
// Police Arial italique 8
$this->SetFont('Arial','I',8);
// Numéro de page
$this->Cell(0,10,'Devis from MyCompany - Page '.$this->PageNo().'/{nb}'.' Paraphes :',0,0,'C');
}
}
// Instanciation de la classe dérivée
$pdf = new FPDI();
$pdf->AliasNbPages();
$pdf->AddPage();
// Here is page 1, you don't need the details
$pdf->AddPage();
// Here is page 2, some other pages can come too
// Then begins the importation
// get the page count
$pageCount = $pdf->setSourceFile('cgua/cgu_'.$customer['num'].'.pdf');
// iterate through all pages
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
// import a page
$templateId = $pdf->importPage($pageNo);
// get the size of the imported page
$size = $pdf->getTemplateSize($templateId);
// create a page (landscape or portrait depending on the imported page size)
if ($size['w'] > $size['h']) {
$pdf->AddPage('L', array($size['w'], $size['h']));
} else {
$pdf->AddPage('P', array($size['w'], $size['h']));
}
// use the imported page
$pdf->useTemplate($templateId);
}
$pdf->Output('devis.pdf','I');
I've found no explanation about how to keep my Footer in FPDI's manual... I'm sure it's easy to rule the problem, I just didn't find the way!
Thanks!
You created a new class that inherits the FPDI class. This new class, PDF, defines the Footer method correctly. But then you instantiated the FPDI class, instead of the PDF class.
Just change
$pdf = new FPDI();
to
$pdf = new PDF();
so that you can instantiate your new class and see the results of the new Footer method.
I've created a form that allows users to create a pdf that has an unlimited number of pages, I've got SetAutoPageBreak set so that it continues onto a second page however I cannot get the pages created after the page break to continue to use the original template file. The basic code can be seen below.
require('fpdf.php');
require('fpdi.php');
$pdf = new FPDI('P','mm','A4');
$pageCount = $pdf->setSourceFile("source_file.pdf");
$tplIdx = $pdf->importPage(1);
$pdf->AddPage();
$pdf->useTemplate($tplIdx);
$pdf->SetTextColor(63,76,89);
$pdf->SetMargins(5,39,5,20);
$pdf->SetAutoPageBreak(true,22); //page created doesn't have template attached
$pdf->SetDrawColor(225,225,225);
$pdf->SetFillColor(248,248,248);
$pdf->SetLineWidth(1);
$pdf->SetXY(82, 40);
$pdf->MultiCell(165,5,$company.$block,0,L,false);
$pdf->SetXY(19, 45);
$pdf->MultiCell(165,5,$date.$block,0,L,false);
$pdf->Output();
Having looked around, this question is the closest I can find however I'm not sure whether it is even relevant: FPDF/FPDI UseTemplate
Thanks
Just place the imported page in the Header method:
class PDF extends FPDI
{
protected $_tplIdx;
public function Header()
{
if (null === $this->_tplIdx) {
$this->_tplIdx = $this->importPage(1);
}
$this->useTemplate($this->_tplIdx);
}
}
$pdf = new PDF('P','mm','A4');
$pdf->AddPage();
...
...and everything should work as expected.
in addition to #JanSlabon`s answer: (i dont have the needed reputation to write a comment, so i´ll post this here, hope that´s ok)
If you only want to use a certain template for the first page and a different one for all other pages, you can do so as follows:
class PDF extends FPDI
{
protected $_tplIdx;
public function Header()
{
if (null === $this->_tplIdx) {
$this->setSourceFile('paper1.pdf');
$this->_tplIdx = $this->importPage(1);
} else {
$this->setSourceFile('paper2.pdf');
$this->_tplIdx = $this->importPage(1);
}
$this->useTemplate($this->_tplIdx);
}
}
i know its not exactly what #Searlee was looking for, but maybe it helps someone else.
I have created a pdf file with FPDF in PHP. When i insert the header and footers in it, they automatically gets displayed on all the pages of the pdf file. But i want to stop these header and footer from getting displayed on the first page and display them starting from the second page of the pdf file. I have searched the net but unable to find a solution.
In other words i want to dynamically create a cover page for the pdf report i have created with FPDF.
Can anybody give me some tips on how to perform this task of hidinh header and footer from the first page in pdf file!
Any help will be appreciated!
That's an easy task. Try the following:
class PDF extends FPDF {
...
function Header() {
if ( $this->PageNo() !== 1 ) {
// Add your stuff here
}
}
function Footer() {
if ( $this->PageNo() !== 1 ) {
// Add your stuff here
}
}
}
The problem is the Footers are created in Close() method at line 288 which is called from Output() at line 987 what means you're effectively turning the Footer off and then on just to display it anyways. What I would do if I needed the flexibility is something like:
class PDF extends FPDF {
function Header() {
if (!isset($this->header[$this->page]) || !$this->header[$this->page]) {
// ...
}
}
function Footer() {
if (!isset($this->footer[$this->page]) || !$this->footer[$this->page]) {
// ...
}
}
}
and then use it like:
$pdf->header[1] = false;
$pdf->footer[1] = false;
$pdf->AddPage();
$pdf->header[2] = true;
$pdf->footer[2] = true;
$pdf->AddPage();
It might be not the most elegant solution, but it works and it effectively allows you to change the visibility of the footers dynamically (p.s.: not specifying the state would also leave you with headers on effectively reducing the amount of code you need)
I'd like to add an answer for people coming here that don't want to skip the first, but the last (or any) page. Especially handy if you have dynamically changing text and cant foresee page numbers.
This can be done by setting a boolean while adding the page to the PDF.
Define your Header / Footer as
class PDF extends FPDF {
function Header() {
if (!$this->skipHeader) {
// ...
}
}
function Footer() {
if (!$this->skipFooter) {
// ...
}
}
}
Then, when initializing the pdf make sure to set these bools to false, so you will get headers/footers in general.
$pdf = new PDF();
$pdf->skipHeader = false;
$pdf->skipFooter = false;
Once you actually want to skip a Header or Footer, set the respective bool to true
$pdf->AddPage();
$pdf->skipHeader = true;
$pdf->AddPageContents();
Remember to set them back to false if you want headers/footers on the next page!
As an extension of what Paul's said, the footer is rendered after any content, so set skipFooter to true after rendering content.
$pdf->AddPage();
$pdf->skipHeader = true;
$pdf->AddPageContents();
$pdf->skipFooter = true;
How can I get height and width of a document in FPDF.
For example, I've next line:
$this->Cell(200,5,'ATHLETIC DE COLOMBIA S.A.',1,1,'C',1);
But, I want to do something like:
// $x = width of page
$this->Cell($x,5,'ATHLETIC DE COLOMBIA S.A.',1,1,'C',1);
Needed to do this myself so was just checking the most recent version of FPDF and it looks like the width & height are already available as public properties. So for anyone looking for the same info:
$pdf = new FPDF();
$pdf->addPage("P", "A4");
$pdf -> w; // Width of Current Page
$pdf -> h; // Height of Current Page
$pdf -> Line(0, 0, $pdf -> w, $pdf -> h);
$pdf -> Line($pdf -> w, 0, 0, $pdf -> h);
$pdf->Output('mypdf.pdf', 'I');
Update: November 2017
Nowadasy, you can simply call GetPageWidth and GetPageHeight methods.
$pdf = new FPDF();
$pdf->addPage("P", "A4");
$pdf->GetPageWidth(); // Width of Current Page
$pdf->GetPageHeight(); // Height of Current Page
Encase someone needs to get the width taking margins into consideration...
class FPDF_EXTEND extends FPDF
{
public function pageWidth()
{
$width = $this->w;
$leftMargin = $this->lMargin;
$rightMargin = $this->rMargin;
return $width-$rightMargin-$leftMargin;
}
}
note: read Ross' McLellan's answer below
As far as I remember you can't do it with vanilla FPDF. You can either extend it to have a method that would return this value for you, or just store the width as a public property of fpdf object.
I am using TCPDF to generate PDFs. The PDF uses a PDF-template via the fpdi-class. Some of the generated PDFs are onepaged. But sometimes I have a second page. I use $pdf->MultiCell to output my content. The page-break works fine via $pdf->SetAutoPageBreak(true).
Now my problem: I need a different top-margin on the second page. What I tried so far is the use of the AcceptPageBreak()-function - unfortunaly with no success.
With the following code-snipped I managed to change the margin on the second page. But it adds one empty page at the end of the PDF.
public function AcceptPageBreak() {
$this->SetMargins(24, 65, 24, true);
$this->AddPage();
return false;
}
I tried to remove the last page with $pdf->deletePage but it does not work.
I tried to insert some conditions into the function:
public function AcceptPageBreak() {
if (1 == $this->PageNo()) {
$this->SetMargins(24, 65, 24, true);
$this->AddPage();
return false;
} else {
return false;
}
}
This works fine for PDFs with text for 2 pages. But now I get allways two paged PDFs - even if I have just a small text. It seems that the function "AcceptPageBreak()" is called every time the PDF is generated.
How can I prevent the empty page at the end of my PDF?
Using some of your code and the original function, I found out a way where it doesn't add an unneccessary blank page at the end of the file.
public function AcceptPageBreak() {
if (1 == $this->PageNo()) {
$this->SetMargins($left_margin, $top_margin, $right_margin, true);
}
if ($this->num_columns > 1) {
// multi column mode
if ($this->current_column < ($this->num_columns - 1)) {
// go to next column
$this->selectColumn($this->current_column + 1);
} elseif ($this->AutoPageBreak) {
// add a new page
$this->AddPage();
// set first column
$this->selectColumn(0);
}
// avoid page breaking from checkPageBreak()
return false;
}
return $this->AutoPageBreak;
}
I finally found a solution to my own question.
Maybe it's interesting for someone else with the same problem.
I took the function AcceptPageBreak() like posted above (Version 1). After saving the PDF I import the PDF into a new PDF without the last page and save the new PDF.
Here the code:
$pdf = new MYPDF();
$pdf->SetMargins(24, 54);
$pdf->AddPage();
...
$pdf->MultiCell('0', '', $text, '', 'L');
$pdf->lastPage();
$lastPage = $pdf->PageNo() + 1;
$pdf->Output($filePath, 'F');
// remove last page
$finalPdf = new FPDI();
$finalPdf->setSourceFile($filePath);
for ($i=1; $i < $lastPage; $i++) {
$finalPdf->AddPage();
$tplIdx = $finalPdf->importPage($i);
$finalPdf->useTemplate($tplIdx);
}
$finalPdf->Output($filePath, 'F');
Hope it helps.
TCPDF Automatic Page Breaks cause some inconsistency in rendering of content. Elements that may inadvertantly extend out of the boundaries of the page can cause additional pages to be generated. It is better to only autopage break when you are adding your content using:
$pdf->SetAutoPageBreak(true, $margin_bottom);
Then disable it when there it is not needed.
$pdf->SetAutoPageBreak(false);