TCPDF + pure HTML ... Create table of contents - php

I want to print HTML to PDF using TCPDF so I do this:
$html = '<h1>Hello</h1>
How are you?
<h2>Answer</h2>
I am well, thanks';
// ... etc. Long HTML document.
$pdf->writeHTML($html);
The question is if there is a way how to add a table of contents. If TCPDF can recognize page numbers of headings.
I also sometimes use HTML page breaks:
<div style="page-break-after: always"><span style="display:none"> </span></div>
I understand that I need bookmarks. But in this case TCPDF would have to create them automatically. If I add an ID to html-heading-tag, TCPDF probably does not find it and cannot use it.
<h1 id="abc123">header1</h1>
// but following does not do anything:
$pdf->addTOC()

Since the ToC page is created as the very last it will show that as the last page.
So instead use
$this->Cell(0, 12, ' '.$this->getAliasNumPage().' of '.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
//It will show page numbers

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.

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

Dynamic Changes for Webmaster's Code

First of all apologies, if the question title misleads you. Here is what I want to achieve.
I want webmasters to come to my site, copy a piece of code(basically it displays an image on the webmasters's website) and then paste it on their website for promotion of my website. I am good till this and have succeeded in doing so. Now, I want the image to have a dynamic rank that will be fetched from my website. So, when webmasters paste the code on their website, the rank displayed on the image(as a text) changes based on my Database setting.
Can anyone let me know how this can be achieved..
You can do an iframe as aniruddha suggested or you can also use javascript. See Twitter, Facebook, and Google Calendar on how their various widgets work.
I've provided some very simplified implementations for you to see how they work. But it's probably better to look at the examples mentioned above. Ignore the security issues in my examples here. Just wanted to show how it works on the simplest level.
iFrame Example
Client Code For Iframe Example:
<html>
<head>
</head>
<body>
<h1>User Website Title</h1>
<p>Some random user text</p>
<p>Iframe version here</p>
<!--This is the code that the client would paste in to their website -->
<iframe src="http:/your.domain.com/server_iframe_test.php?user=TestUser" height="30" width="500" scrolling="no" frameBorder="0"></iframe>
<!-- End client iframe code to paste-->
</body>
</html>
On your server, you can have page to use as the source for the iFrame. Here I'm calling mine server_iframe_test.php:
<?php
//Generating a random number to show that page will update on reload
$randomNumber = rand(1, 999);
//In the src of the iframe we will send a get parameter called user to determine which user we should look up
$data = array('user' => $_GET['user'], 'rank' => $randomNumber, 'image' => 'http://url/to/some/image.png');
?>
<!-- This is the output that will be generated in the iframe -->
<div class="widget_wrapper"><?php echo $data['user'] ?>: <?php echo $data['rank'] ?> and <? echo $data['image'] ?></div>
Javascript Example
For the javascript example it is possible to make ajax calls across domains using JSONP. You can read up on how it works here: http://www.ibm.com/developerworks/library/wa-aj-jsonp1/
Here is the client side for the javascript version:
<html>
<head>
<!-- I'm cheating here by including jquery in the head. My test script needs it-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
<h1>User Website Title</h1>
<!--Code that user pastes into their page-->
<!--First get the script from your domain-->
<script src="http://your.domain.com/test_widget.js"></script>
<!--This code is also pasted by the client. We use this to set user name and then render the html. Also I added an id to the script tag here to know where to append the html. This is a more of a shortcut.-->
<script id="test_widget_script">
var widget = new testWidget('TestUser');
widget.render();
</script>
<!-- Widget will render html here -->
<!--End Code to Paste-->
<p>Some random user text</p>
</body>
</html>
Here is the server side js script called test_widget.js:
var testWidget = function(user){
var _user = user;
this.render = function() {
//We make a JSONP call here to our php script which generates the data for the user. Note the &callback?. We need to add this to make it a JSONP call.
$.getJSON('http://your.domain.com/test_js.php?user=' + _user + '&callback=?', function(data){
//Append html result after the js tag with the following id
$("#test_widget_script").after('<div class="widget_wrapper">' + _user + ': ' + data.rank + ' and ' + data.image + '</div>');
});
}
}
Here is the php file called test_js.php that will handle the request:
<?php
$randomNumber = rand(1, 999);
$data = array('user' => $_GET['user'], 'rank' => $randomNumber, 'image' => 'http://url/to/some/image.png');
//We need to make the content type javascript
header("Content-type: text/javascript");
?>
<?php //Here we take the name of the callback passed as a GET parameter and use it as a function to pass in our json data. We don't call the function in php, but when the text gets returned, jQuery knows how to handle the response. ?>
<?php echo $_GET['callback'] ?>(<?php echo json_encode($data); ?>);
I think a iframe is required with src of your server side script page which will fetch the rendered code with rank over the image from your server. The purpose of the iframe will be to render the whole html.
Modify the code from here http://php.net/manual/en/function.imagettftext.php
to make an image with your rank in it. Here is tested example based on that code, note you need GD and truetype for this. All you need do is send then a link and use a get variable to set which user so you can get the right ranking back from your DB. I won't code that part.
// Create the image
$im = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
// The text to draw (your ranking)
$text = '21'; // <== change this as you need over time
// Replace path by your own font path
$font = 'arial.ttf';
// Add some shadow to the text
imagettftext($im, 20, 0, 11, 21, $grey, $font, $text);
// Add the text
imagettftext($im, 20, 0, 10, 20, $black, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
?>

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