TCPDF with FPDI templates and CSS - php

When using TCPDF together with FPDI templates, some CSS support is lost in the process. The problem are things like borders or background-colors, that end up in layers below the PDF template. TCPDF uses SetLineStyle() to convert CSS borders/backgrounds to PDF and this seems to be the problem.
For example:
$this->setSourceFile($filename); // /path/to/my/background.pdf
$imported_page = $this->ImportPage(1);
$this->useTemplate($imported_page);
...
$html = '<table style="border: 1px solid #000;"><tr><td style="background-color: #ff0000;">...</td></tr></table>';
$this->writeHTMLCell(45, 25, 160, 29, $html);
doesn't render the CSS borders. As soon as useTemplate() is removed the borders are there. Analyzing the resulting PDFs with Illustrator shows some interesting things:
PDF layers with useTemplate() - top to bottom:
Table/Content layers
PDF Template layers (group)
Border and background layers (paths)
PDF layers without useTemplate() - top to bottom:
Table/Content layers
Border and background layers (paths)
When disabling the layer group containing the PDF template in Illustrator, the borders and backgrounds become visible.
Unfortunately we didn't find a way to put the PDF template layer group at the bottom of the stack so everything else renders above it. The only workaround we could come up with, was wrapping the writeHTMLCell() call in startTemplate() / endTemplate() and finishing up with printTemplate():
$this->setSourceFile($filename); // /path/to/my/background.pdf
$imported_page = $this->ImportPage(1);
$this->useTemplate($imported_page);
...
$html = '<table style="border: 1px solid #000;"><tr><td style="background-color: #ff0000;">...</td></tr></table>';
$workaround_template = $this->startTemplate($w, $h);
$this->writeHTMLCell(45, 25, 160, 29, $html);
$this->endTemplate();
$this->printTemplate($workaround_template, $x, $y, $w, $h, 'T', 'L');
So out of curiosity: is this the only way to do it, or is there a way to put the PDF template at the bottom of all things to come?
Thanks in advance!

The solution is to use setPageMark() indeed.
Here is what worked very well for me:
public function AddPage($orientation = '', $format = '') {
global $pdf_data_path;
parent::AddPage($orientation, $format);
if ($this->use_headed) {
$this->setSourceFile($pdf_data_path."/headed.pdf");
$tplidx = $this->importPage(1, '/MediaBox');
$this->useTemplate($tplidx, 0, 0, 0, 0, true);
$this->setPageMark();
}
}
The key is to place setPageMark() after you used the template. The borders will then be stacked on top of the template in resulting PDF.

Did you try using the setPageMark()-method?

Related

Page footer centering using MPDF

I have this pdf:
How can I make the page numbering centered instead of right alignment?
This is how I added the page numbering:
include("mpdf60/mpdf.php");
$mpdf=new \mPDF('c','A4','','' , 0, 0, 0, 0, 0, 0);
$mpdf->setFooter('{PAGENO} of {nbpg}');
$mpdf->WriteHTML($body);
$mpdf->Output('Packing Slip.pdf','I');
How can I make it center? its the 'setFooter' ?
Im am using mpdf.
You can set an HTML Footer and give the proper format:
$mpdf->SetHTMLFooter('<div style="text-align: center">{PAGENO} of {nbpg}</div>');
SetHTMLFooter() Function
you can try the following:
$mpdf->setFooter('|{PAGENO} of {nbpg}|');
This will center align the page numbers. Any thing on the left of first | will be left aligned and anything on the right of second | will be right alligned.

dompdf - text on a single page / page_script doesnt work

I'm using dompdf 0.7.0 and try to write down text in PHP on my pdf after rendering. I need text on specific pages and found the following from Answer from Brian
DomPDF {PAGE_NUM} not on first page
The function page_script sound like the correct answer.
I could check if loop is currently on page 3 or whatever.
Does I have to enable any options for this function?
Example:
$dompdf = new Dompdf( $options );
$dompdf->set_option('default_font', 'open sans');
$dompdf->set_option('fontHeightRatio', 1);
$dompdf->setPaper('A4')
$dompdf->set_option('enable_html5_parser', true);
$dompdf->set_option('enable_php', true);
$dompdf->loadHtml( $html );
$dompdf->render();
$canvas = $dompdf->get_canvas();
$canvas->page_script('
if ($PAGE_NUM > 1) {
$current_page = $PAGE_NUM-1;
$total_pages = $PAGE_COUNT-1;
$canvas->text(0, 0, "$current_page / $total_pages", "open sans condensed", 10, array(0,0,0));
}
');
It still be shown on my first page.
$canvas wouldn't be available from the page script as it is out of scope. The canvas object can be referenced inside your page script as $pdf.
Try the following page_script call instead:
$canvas->page_script('
if ($PAGE_NUM > 1) {
$current_page = $PAGE_NUM-1;
$total_pages = $PAGE_COUNT-1;
$font = $fontMetrics->getFont("open sans condensed", "normal"); // or bold, italic, or bold_italic
$pdf->text(0, 0, "$current_page / $total_pages", $font, 10, array(0,0,0));
}
};
There are a few variables available from within page scripts or embedded script:
$PAGE_NUM: current page number
$PAGE_COUNT: total number of pages
$pdf: the canvas object
$fontMetrics: an instance of the FontMetrics class
If you're using page text you have access to the following template variables:
{PAGE_NUM}: current page number
{PAGE_COUNT}: total number of pages
Note: Support for parsing embedded script or page scripts is disabled by default. Enable it with the following command: $dompdf->set_option("isPhpEnabled", true);. This must be done prior to calling $dompdf->render();.

Why lines/images draw only on last page of pdf using dompdf in php

I am trying to draw line/image on every page of pdf using dompdf but it starts from second page, why this is so ? anyone has any idea ?
Here is my code
$dompdf = new DOMPDF();
$dompdf->load_html($message2);
$dompdf->set_paper('a4','portrait');
$dompdf->render();
$canvas = $dompdf->get_canvas();
//For Header
$header = $canvas->open_object();
$canvas->image($header_image1,'jpg',0, 0, 595, 100);
$canvas->line(0,100,595,100,array(0,0,0),1);
$canvas->close_object();
$canvas->add_object($header, "all");
//For Footer
$footer = $canvas->open_object();
$canvas->line(0,740,650,740,array(0,0,0),1);
$canvas->image($footer_image1,'jpg',0, 742, 595, 100);
$canvas->close_object();
$canvas->add_object($footer, "all");
$output = $dompdf->output();
this code draw line/image on pdf but it only display on last page.
I have two pages in pdf and my line/images are drawn on second page not on first page.
Please suggest any solution.
Adding objects in DomPDF works from the current page onwards. In other words, your objects will get added, but only from the page you currently have and then onwards to any new pages you add.
In your code, you've already converted your HTML to PDF, so the current page is more than likely the last page in your document. So your header / footer are added there, but not to any previous pages.
To place content on every page, domPDF provides two methods: page_text and page_script.
In your case the following type of code should do the trick:
$canvas->page_script('
$pdf->line(10,730,800,730,array(0,0,0),1);
');
Code in the page_script function is then executed for every PDF page.
The line is not displayed for me because embedded php was disabled.
This solved the problem:
$dompdf->set_option("isPhpEnabled", true);
This line has to be placed before $dompdf->render().
how to add image in all pdf page using header and footer.below is my code.
$pdf = App::make('dompdf');
$pdf->loadFile('invoice.html');
$pdf->output();
$dom_pdf = $pdf->getDomPDF();
$canvas = $dom_pdf ->get_canvas();
$image1="logo.png";
$canvas->image($image1,'png', 0, 0, 50, 25);
$canvas->page_text(10, 10, "Page {PAGE_NUM} of {PAGE_COUNT}", null, 10, array(0, 0, 0));
$pdf->save('pdf_report/eft_payment-'.$RandomAccountNumber.'.pdf');

render HTML from PHP using FPDF

having some problems rendering html when I convert to PDF. It's driving me mental and I don't know what's going on. The idea is that I have an html form in a mysql database which stores HTML tags and what not, I pull it out using PHP, render the HTML and display it as a PDF. My issue is that it won't render the HTML. it's just text and the formatting is way off. Here is the code I have so far:
$indemResult = mysqli_query($conn,"SELECT * FROM Indemnity");
$indemRow = mysqli_fetch_array($indemResult);
require('../include/PDFConverter/fpdf.php');
$pdf = new PDF();
$pdf->SetMargins(0,0,0);
$pdf->AddPage();
$pdf->SetFont('Arial','',12);
//Insert Banner
$pdf->Image('../assets/pdfBanner.png');
$pdf->Ln();
$pdf->Ln();
//Insert Indemnity form
$pdf->SetXY(50, 65);
$pdf->cMargin = 10;
$pdf->SetFont('Arial','',24);
$pdf->Cell(0, 10, $pdf->Write(1,'Indemnity Form'), 0, 1,'C', false);
$pdf->SetFont('Arial','',12);
$text=$pdf->WriteHTML(utf8_decode($indemRow['form']));
$wrap=$pdf->WordWrap($text,120);
$pdf->MultiCell(0,0,$pdf->Write($wrap, ''));
My problem was in the WriteHTML class. It didn't support UL LI tags, so I used this instead:
http://fpdf.de/downloads/addons/53/
I stripped the createPDF class, in the class PDF extends FPDF I removed $_title, $_url, $_debug=false from the PDF function, I also removed $bi from the write HTML function and inside the writeHTML function I removed:
$this->bi=$bi;
if ($bi)
$html=strip_tags($html, "<a><img><p>
<font><tr><blockquote><h1><h2><h3><h4><pre><red><blue><ul><li><hr><b><i><u><strong><em>");
I hope this helps people who are trying to render HTML before putting it onto PDF

how to write barcode in html format when using tcpdf

I am using TCPDF to generate PDF file using following command
$pdf->writeHTML($htmlcontent, true, 0, true, 0);
TCPDF also provides a way to create barcode with following commands
$pdf->Cell(0, 0, 'C39+', 0, 1);
$pdf->write1DBarcode('Code 39', 'C39+', '', '', 80, 15, 0.4, $style, 'N');
$pdf->Ln();
I want to be able to write barcode as part of the HTML code above. Is there easy way?
I can potentially call a barcode image inthe writeHTML code above, but not sure how to use above barcode function (or any in TCPDF) which would allow me to create image and then get that image into HTML generation.
You can write TCPDF Methods in HTML as below
<?php
$params = $pdf->serializeTCPDFtagParameters(array('40144399300102444888207482244309', 'C128C', '', '', 0, 0, 0.2, array('position'=>'S', 'border'=>false, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>false, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>2), 'N'));
$str='<table cellspacing="0" cellpadding="1" border="0">
<tr>
<td align="left">barcode</td>
</tr>
<tr>
<td align="center" style="padding-left:5px;">';
$str .= '<tcpdf method="write1DBarcode" params="'.$params.'" />';
$str .='</td>
</tr>
</table>';
$pdf->writeHTML($str,true, false,false,false,'left');
$pdf->Output('example_049.pdf', 'I');
?>
For detail reference please check TCPDF example_049.php
TCPDF barcode classes already contains methods to export barcodes in various formats (SVG, PNG and HTML).
2D example:
require_once(dirname(__FILE__).'/2dbarcodes.php');
$barcodeobj = new TCPDF2DBarcode('http://www.tcpdf.org', 'QRCODE,H');
// export as SVG image
//$barcodeobj->getBarcodeSVG(3, 3, 'black');
// export as PNG image
//$barcodeobj->getBarcodePNG(3, 3, array(0,128,0));
// export as HTML code
echo $barcodeobj->getBarcodeHTML(3, 3, 'black');
1D example:
require_once(dirname(__FILE__).'/barcodes.php');
$barcodeobj = new TCPDFBarcode('123456', 'C128');
// export as SVG image
//$barcodeobj->getBarcodeSVG(2, 30, 'black');
// export as PNG image
//$barcodeobj->getBarcodePNG(2, 30, array(0,128,0));
// export as HTML code
echo $barcodeobj->getBarcodeHTML(2, 30, 'black');
Check the documentation and examples at http://www.tcpdf.org for further information.
You could put your barcode number is a fake HTML tag and then parse for that tag as you write out the HTML like in this example.
This would be in your HTML:
some HTML.... <POSTNET>12345-1234</POSTNET> ....some more HTML
This is the code to parse for the fake tag.
// look to see if there is a POSTNET tag
if (strpos($letter_html, "<POSTNET>") !== false) {
$postnet_pre = explode("<POSTNET>", $letter_html);
$this->WriteHTML($postnet_pre[0], $this->line_height);
// write the barcode
$postnet_post = explode("</POSTNET>", $postnet_pre[1]);
$zip_code = $postnet_post[0];
$this->write1DBarcode($zip_code, 'POSTNET', '', '', 80, 15, 0.4, $style, 'N');
// write rest of the letter
$this->WriteHTML($postnet_post[1], $this->line_height);
} else {
// no POSTNET so just write the whole letter
$this->WriteHTML($letter_html, $this->line_height);
}
When generating a barcode, make sure that you enclose the 12-digit delivery point inside of the "slash" character. Most POSTNET fonts render the slash character as the "control" character that pre/post-fixes the barcode values. Without those control characters the barcode isn't technically valid.
The POSTNET barcode font in TrueType format can be downloaded.
I tried the following and it worked:
$params = $pdf->serializeTCPDFtagParameters(
array('https://tcpdf.org/', 'QRCODE,H', '', '', 27, 27, '', 'N')
);
$html .= '<tcpdf method="write2DBarcode" params="'.$params.'" />';

Categories