how TCPDF prevent the extra blank page - php

I have create class to make page by using TCPDF.
I need to convert HTML to pdf, so I using writeHTML and AcceptPageBreak().
The $html is Dynamically changed, could be very long.
class MY_TCPDF extends TCPDF{
public function makePage($html){
$head_image="header.jpg";
$this->SetMargins(PDF_MARGIN_LEFT, 70, PDF_MARGIN_RIGHT);
$this->setPrintHeader(false);
$this->AddPage();
// get the current page break margin
$bMargin = $this->getBreakMargin();
// get current auto-page-break mode
$auto_page_break = $this->getAutoPageBreak();
// disable auto-page-break
$this->SetAutoPageBreak(false, 0);
// set bacground image
$img_file = $head_image;
$this->Image($img_file, 0, 0, 210, 68, '', '', '', false, 300, '', false, false, 0);
// restore auto-page-break status
//$this->SetAutoPageBreak($auto_page_break, PDF_MARGIN_BOTTOM);
// set the starting point for the page content
$this->setPageMark();
$this->writeHTML($html, true, false, true, false, '');
$this->lastPage();
ob_start();
//Close and output PDF document
$this->Output('my.pdf', 'I');
ob_end_flush();
}
public function AcceptPageBreak() {
$this->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
$this->AddPage();
return false;
}
}
The problem is I genenrate PDF, but alway has a extra blank page in the end of the PDF.
I tried use $this->delete($this->getPage()) ,but it only remove last page which has content and the extra blank page remain. this seems writeHTML will create a page break after it.
how to prevent this extra blank page?

Try this deletePage function
$lastPage = $this->getPage();
$this->deletePage($lastPage);
Instead Delete use deletePage

I had the same Problem:
I fixed it with:
class TCPDFextended extends \TCPDF {
public function Output($name = 'doc.pdf', $dest = 'I')
{
$this->tcpdflink = false;
return parent::Output($name, $dest);
}
}

You should check your $html variable.
1) If it could contains any <html />, <head />, <title />, <body /> tag then please remove them and just take html contents after and before <body />.
2) You should avoid any css, js link file within $html content.
3) Finally you should use $html=utf8_encode($html); just before $this->writeHTML($html, true, false, true, false, '');.
4) You may need to adjust your MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT and MARGIN_BOTTOM to solve such problems. Please check $this->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); and $this->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);.
Hopefully it can solve your problem.

My answer is similar to #kanti. I think we can set the default to false even before the Output generation.
Background. The extra page we see is basically
"If true print TCPDF meta link".
so by default the TCPDF::$tcpdflink = true , is set true.
All we need is
class My_PDF extends TCPDF {
public function changeTheDefault($tcpdflink) {
$this->tcpdflink = $tcpdflink;
}
}
call your public function later when you need it. ...
$get_pdf = new My_PDF (your_parameters);
$get_pdf->changeTheDefault(false); # changes the default to false
Good Luck.

Check also the height of your enclosing div.
It should not be 100%.
Try to remove any height property from the CSS style of the enclosing div ( I mean the div which encloses all the content).

The problem is the 4th parameter (unicode = true) in your create_pdf.php file. This parameter is passed into tcpdf.php on line 1838
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'ISO-8859-1', false);
change it to false.

Related

Send dynamic data to Header function in TCPDF

As I need to get some dynamic content to my page header. So, let me know the way to send data through parameters. I have not found how to call, send parameters to the header function. Please help me to solve this..
How can I call Header() function with parameters?
I need to send data through parameters to Header() function.
This can be accomplished by setting a new property of the TCPDF class. The property will need to be set before the AddPage() method is called for the next page. Before creating a new property you may want to check the TCPDF documentation for an existing property that may be useful. Searching “get” will allow you to quickly find them.
Be careful to give the new property a unique name, so you don’t change an existing property of TCPDF. You may want to include a check for the property in case one were to be added in a future version.
Setting a parameter of the Header() method is more difficult because it is called through a series of other methods (AddPage(), startPage(), setHeader()).
Example
This example sets a new string for each page header with the new CustomHeaderText property. The example will run inside the TCPDF examples directory.
<?php
require_once('tcpdf_include.php');
class MYPDF extends TCPDF
{
public function Header()
{
$this->Write(0, $this->CustomHeaderText);
}
}
$pdf = new MYPDF();
$pdf->CustomHeaderText = "Header Page 1";
$pdf->AddPage();
$pdf->writeHTMLCell(0, 0, '', 30, '<p>Page 1 Content</p>', 0, 1, 0, true, '', true);
$pdf->CustomHeaderText = "Header Page 2";
$pdf->AddPage();
$pdf->writeHTMLCell(0, 0, '', 30, '<p>Page 2 Content</p>', 0, 1, 0, true, '', true);
$pdf->Output('example.pdf', 'I');
You can do this by adding a new property in your extended class MYPDF in this example
<?php
require 'tcpdf.php';
class MYPDF extends TCPDF {
protected $company;
public function setCompany($var){
$this->company = $var;
}
// Page footer
public function Footer() {
// Position at 15 mm from bottom
$this->SetY(-15);
// Set font
$this->SetFont('helvetica', 'I', 8);
// setCompany Text
$this->Cell(0, 10, $this->company, 0, false, 'C', 0, '', 0, false, 'T', 'M');
}
}
To access this
// create new PDF document
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->setCompany("My Company");

can I assign HTML page into Global variable to download it as PDF?

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.

TCPDF does not render external CSS

I am trying to generate PDFs using TCPDF library. So far, I am able to generate the PDF files using PHP code. Although it does not render external CSS and result becomes useless as without CSS the document is not readable.
Following is my code in the controller:
public function generate_pdf() {
$this->load->model('rosters', 'roster');
$data = array();
$data['start_date'] = isset($_POST['fortnightStartDate']) ?
date("Y-m-d", strtotime(getFortnightStartDate($_POST['fortnightStartDate']))) :
getFortnightStartDate();
$cid = $_POST['cid'];
$wno = $_POST['wno'];
$data['no']=$wno;
$startDate = strtotime($data['start_date']);
$data['schedule'] = $this->roster->getShifts($cid, $data);
$data['startDate'] = $startDate;
$listing = $this->load->view('roster/roster_pdf', $data, true);
/**
* Creates an example PDF TEST document using TCPDF
* #package com.tecnick.tcpdf
* #abstract TCPDF - Example: XHTML + CSS
* #author Nicola Asuni
* #since 2010-05-25
*/
// Include the main TCPDF library (search for installation path).
require_once(APPPATH.'libraries/tcpdf/tcpdf.php');
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 061');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 061', PDF_HEADER_STRING);
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
// set some language-dependent strings (optional)
if (#file_exists(dirname(__FILE__).'/lang/eng.php')) {
require_once(dirname(__FILE__).'/lang/eng.php');
$pdf->setLanguageArray($l);
}
// ---------------------------------------------------------
// set font
$pdf->SetFont('helvetica', '', 10);
// add a page
$pdf->AddPage();
$pdf->writeHTML($listing, true, false, true, false, '');
//Close and output PDF document
$pdf->Output('TEST.pdf', 'F');
}
I am passing the $listing variable which holds the data that needs to be included in the PDF. The data is printing fine but without CSS. If I try to include the external CSS it pops up the error.
Code to include external css
$listing. = '<style>'.file_get_contents(base_url("styles/style.css")).'</style>';
I try to include this line of code below the $listing variable but it generates following error:
A PHP Error was encountered
Severity: Warning
Message: array_merge(): Argument #2 is not an array
Filename: tcpdf/tcpdf.php
Line Number: 16375
Is there any other way I can load the external CSS ??
Any help will be highly appreciated.
After researching here and there, I come to know that TCPDF library has few limitations including CSS limitation and does not support many CSS properties. Then, I looked into dompdf library and found it useful. Surprisingly, it solved all my problem with almost similar code and also it is way easy to use than TCPDF. Following is my piece of code i wrote to solve my problem (The code is similar until the $listing variable then i simply change the library code.)
$listing .= '<style>'.file_get_contents(base_url("styles/style.css")).'</style>';
require_once(APPPATH.'libraries/dompdf/dompdf_config.inc.php');
$dompdf = new DOMPDF();
$dompdf->load_html($listing);
$dompdf->set_paper('a4', 'landscape');
$dompdf->render();
file_put_contents('my_pdf_test.pdf', $dompdf->output());
//$dompdf->stream("dompdf_out.pdf", array("Attachment" => true));
exit(0);

Change top margin on second page with tcpdf AcceptPageBreak()

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);

Changing or eliminating Header & Footer in TCPDF

AddPage() in tcpdf automatically calls Header and Footer. How do I eliminate/override this?
Use the SetPrintHeader(false) and SetPrintFooter(false) methods before calling AddPage(). Like this:
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, 'LETTER', true, 'UTF-8', false);
$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->AddPage();
A nice easy way to have control over when to show the header - or bits of the header - is by extending the TCPDF class and creating your own header function like so:
class YourPDF extends TCPDF {
public function Header() {
if (count($this->pages) === 1) { // Do this only on the first page
$html .= '<p>Your header here</p>';
}
$this->writeHTML($html, true, false, false, false, '');
}
}
Naturally you can use this to return no content as well, if you'd prefer to have no header at all.
Here is an alternative way you can remove the Header and Footer:
// Remove the default header and footer
class PDF extends TCPDF {
public function Header() {
// No Header
}
public function Footer() {
// No Footer
}
}
$pdf = new PDF();
How do I eliminate/override this?
Also, Example 3 in the TCPDF docs shows how to override the header and footer with your own class.
Example:
- First page, no footer
- Second page, has footer, start with page no 1
Structure:
// First page
$pdf->startPageGroup();
$pdf->setPrintFooter(false);
$pdf->addPage();
// ... add page content here
$pdf->endPage();
// Second page
$pdf->startPageGroup();
$pdf->setPrintFooter(true);
$pdf->addPage();
// ... add page content here
$pdf->endPage();
// set default header data
$pdf->SetHeaderData('', PDF_HEADER_LOGO_WIDTH, 'marks', 'header string');
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
With the help of above functions you can change header and footer.

Categories