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);
Related
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()
I'm using Code Igniter framework, and tcpdf third-parties
I have a global variable in controller :
public $pdf_content = '';
here is some of my function to book :
$data['success'] = $this->hotel_model->set_hotel(); //get the data from database
//view reservation detail
$this->load->view('hotel/header');
$this->load->view('hotel/success', $data );
$this->load->view('hotel/footer');
//assign the HTML page into global variable
$this->pdf_content = $this->load->view('hotel/success', $data , TRUE);
In my view file I'm using a button to download the HTML as pdf file, here is the download function :
public function download(){
$this->load->library("Pdf");
$this->load->helper('pdf_helper');
$pdf = new Pdf('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
// Add a page
$pdf->AddPage();
$pdf->writeHTMLCell(0, 0, '', '', $this->pdf_content , 0, 1, 0, true, '', true);
$pdf->Output('invoice.pdf', 'I');
}
Both function located inside the same controller.
I think there is nothing wrong in my code based on any tutorial I ever read.
But it downloaded some blank page instead, and when I try to assign string value into $pdf_content, it works fine, The string value is written into the downloaded PDF file.
Anybody know what I missed there?
Or there is something wrong in my code?
Any help is appreciated.
There are multiple ways. The easiest would be to save the page as pdf manually (ctrl+p) and then make it available as download. OR, you can show the page and run the following script in the bottom of the body.
<script>
var yourName = "someName';
document.title = yourName;
window.print();
</script>
This fires the ctrl+p command and allows users to either print or save the page.
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.
Is it possible to "merge" or "paste" a PDF-file into antother PDF? Or must it be a image instead?
The PDF i want to to paste or merge, is a simple picture that is going to appear at the bottom of the finished PDF:
//Generate the "Original" PDF here..
function addReklam($reklamblad) //The PDF that should be merged into the PDF that is created above
{
//Count how many pages that has been created, and add it at the bottom of the PDF:
if($this->drawed_lines<52)
{
$this->active_page = $this->pdf->pages[2];
}
elseif($this->drawed_lines<92)
{
$this->active_page = $this->pdf->pages[3];
}
elseif($this->drawed_lines<132)
{
$this->active_page = $this->pdf->pages[4];
}
else
{
$this->active_page = $this->pdf->pages[5];
}
//$this->active_page = $this->pdf->pages[5]; // page 5 is the last
//Add it here???
}
My recommendation would be to use the Zend_Pdf::load() method to load the "Original" PDF file into a local instance of Zend_Pdf and then you can access the pages using the pages[] array as in your sample code and use the all the standard functions like drawImage() etc to make the needed modifications prior to saving the updated version.
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;