Manual Page Break in TCPDF - pdf

I am using TCPDF to generate the PDF in one of my projects. I simply create a HTML file and give it to the TCPDF to handle the PDF generation. But now I have some HTML where multiple certificates are added one after the other and I want to have a page break in it. Page Break should be decided by HTML i.e. I want to know if there is any identifier in HTML which TCPDF understands and then accordingly adds a page break into the generated PDF.
How could I do this?

I'm using <br pagebreak="true"/>.
Find method writeHTML and code
if ($dom[$key]['tag'] AND isset($dom[$key]['attribute']['pagebreak'])) {
// check for pagebreak
if (($dom[$key]['attribute']['pagebreak'] == 'true') OR ($dom[$key]['attribute']['pagebreak'] == 'left') OR ($dom[$key]['attribute']['pagebreak'] == 'right')) {
// add a page (or trig AcceptPageBreak() for multicolumn mode)
$this->checkPageBreak($this->PageBreakTrigger + 1);
}
if ((($dom[$key]['attribute']['pagebreak'] == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
OR (($dom[$key]['attribute']['pagebreak'] == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
// add a page (or trig AcceptPageBreak() for multicolumn mode)
$this->checkPageBreak($this->PageBreakTrigger + 1);
}
}

You might use TCPDF's AddPage() method in combination with explode() and a suitable delimiter:
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8',
false);
// TCPDF initialization code (...)
$delimiter = '<h1>';
$html = file_get_contents('./test.html');
$chunks = explode($delimiter, $html);
$cnt = count($chunks);
for ($i = 0; $i < $cnt; $i++) {
$pdf->writeHTML($delimiter . $chunks[$i], true, 0, true, 0);
if ($i < $cnt - 1) {
$pdf->AddPage();
}
}
// Reset pointer to the last page
$pdf->lastPage();
// Close and output PDF document
$pdf->Output('test.pdf', 'I');

I tried using
<br pagebreak="true" />
or
<tcpdf method="AddPage" />
each of them resulted not in starting new page at the top of the page but adding the full A4-page empty space in between HTML text. So if text ended in the middle of the page and then page break was inserted, the new text was written from the middle of the next page. Which I didn't want.
What worked was this (found it here TCPDF forcing a new page):
$pdf->writeHTML($content, true, 0, true, 0);
$pdf->AddPage();
$pdf->setPage($pdf->getPage());
This now starts with writing text on top of the page.

TCPDF support the 'pagebreak' attribute for HTML tags and CSS properties 'page-break-before' and 'page-break-after'.
For example you can use <br pagebreak="true" />.
Check the official http://www.tcpdf.org website and forums for further information.

With version 5.9.142 from 2011-12-23 we could use the page-break-before, page-break-inside css properties, like this:
<div style="page-break-inside:avoid;">
some non breakable text
</div>

For someone who still has the same problem with page-break TCPDF library
You can use <div style="page-break-before:always"></div> OR <br pagebreak="true"/>
to break page manually in your HTML content.
Use $tcpdf->AddPage() to break page manually in your code.
When you set SetAutoPageBreak(TRUE, 10); that means: when the height of document reach to (bottom - 10) then move the cursor to new page. So if you want to have more space, just reduce the number into 0. It will draw until the end of the document without any margin from bottom.
Remember that TCPDF only accept the double quote (") for attributes of tags. Don't use single quote (') for your tag.
<div style='page-break-before:always' => WRONG
<div style="page-break-before:always" => RIGHT
It takes 8 hours from me because this issue :(

According to http://www.tcpdf.org/examples/example_049.phps you can use something like this
$html .= '<tcpdf method="AddPage" /><h2>Graphic Functions</h2>';
You need to verify that parameter K_TCPDF_CALLS_IN_HTML in TCPDF configuration file is true.

You can also follow this method to accomplish your needs:
$htmlcontent1="CERTIFICATE NUMBER 1 IMAGE HERE";
// output the HTML content
$pdf->writeHTML($htmlcontent1, true, 0, true, 0);
// reset pointer to the last page
$pdf->lastPage();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Print a table
// add a page
$pdf->AddPage();
$htmlcontent1="CERTIFICATE NUMBER 1 IMAGE HERE";
// output the HTML content
$pdf->writeHTML($htmlcontent1, true, 0, true, 0);
// reset pointer to the last page
$pdf->lastPage();
// ---------------------------------------------------------
//Close and output PDF document
$pdf->Output('textcertificate.pdf', 'D');
Hopes it helps someone :)
Thanks

Giving your element the page-break-after, page-break-before or page-break-inside property via CSS will apply the attribute pagebreak or pagebreakafter to the html tag during TCPDF runtime.
// page-break-inside
if (isset($dom[$key]['style']['page-break-inside']) AND ($dom[$key]['style']['page-break-inside'] == 'avoid')) {
$dom[$key]['attribute']['nobr'] = 'true';
}
// page-break-before
if (isset($dom[$key]['style']['page-break-before'])) {
if ($dom[$key]['style']['page-break-before'] == 'always') {
$dom[$key]['attribute']['pagebreak'] = 'true';
} elseif ($dom[$key]['style']['page-break-before'] == 'left') {
$dom[$key]['attribute']['pagebreak'] = 'left';
} elseif ($dom[$key]['style']['page-break-before'] == 'right') {
$dom[$key]['attribute']['pagebreak'] = 'right';
}
}
// page-break-after
if (isset($dom[$key]['style']['page-break-after'])) {
if ($dom[$key]['style']['page-break-after'] == 'always') {
$dom[$key]['attribute']['pagebreakafter'] = 'true';
} elseif ($dom[$key]['style']['page-break-after'] == 'left') {
$dom[$key]['attribute']['pagebreakafter'] = 'left';
} elseif ($dom[$key]['style']['page-break-after'] == 'right') {
$dom[$key]['attribute']['pagebreakafter'] = 'right';
}
}

Related

Razor-Pages - HTML markup

Following the answer on this post I was using #:<div class="col-md-6">
Problems
The Formatting gets all messed up:
The intellicode gets all messed up (I only deleted the paragraph on the second #:)
Also, my if (i == (Model.CellsNotStarted.Count - 1) && i % 2 != 0) won't work when using the #:; it will always go on the else. If I don't use the #: markup, and if I, for instance put all my html in a if/else instead of only the <div> tag it will work with no problems.
My question is:
Is the #: markup viable? If so, what am I doing wrong. If not what is the alternative (that does not imply putting my entire code in an if/else)
PS: I know I should not post images of code, but I wanted to show the format and syntax errors.
There are neater ways to manage conditions within your Razor code. It's difficult to provide a full example because you don't provide the full code, but you can do this, for example:
<div class="col-md-#(i+1 == Model.CellsNotStarted.Count && i % 2 ! = 0 ? "12" : "6")">
Whenever you are tempted to use a remainder operator (%) in Razor, you should also consider whether a GroupBy would be better. It most often is, as I was shown in this question: Building tables with WebMatrix
You can try to use js to set html.Here is a demo:
<div id="myDiv"></div>
<script>
$(function () {
var html = "";
if ("#(Model.CellsNotStarted != null)"=="True")
{
for (var i = 0; i <#Model.CellsNotStarted.Count; i++)
{
if (i == (#Model.CellsNotStarted.Count - 1) && i % 2 != 0)
{
html += '<div class="col-md-12">';
}
else
{
html += '<div class="col-md-6">';
}
html += i+'</div>';
}
}
$("#myDiv").html(html);
})
</script>
result:

fix footer image in tcpdf

$path = Yii::app()->basePath;
require_once($path . '/extensions/tcpdf/tcpdf.php');
$pdf = new TCPDF();
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(true);
$pdf->SetAutoPageBreak(TRUE, 0);
$pdf->AddPage();
$pdf->SetLineWidth(0.1);
$pdf->SetFont('times', '', 10);
$pdf->SetMargins(20, 20, 20, true);
$footer_image_file = Yii::app()->request->baseUrl.'/images/logo.jpg';
$content = '<div> $content </div>';
$pdf->writeHTML($content, true, false, true, false, '');
ob_end_clean();
$pdf->Output("Reports.pdf", "D");
I want to add image in fooder for every new pages.. please anyone help me...
Simply put the code displaying the image within the Footer() base method. This base method is called for any new page by either the AddPage() method and Close().
Important : The Footer method should not be called directly.
This method is supposed to be implemented in your class, so override it like this :
function Footer()
{
.... /* Put your code here (see a working example below) */
$logoX = 186; // 186mm. The logo will be displayed on the right side close to the border of the page
$logoFileName = "/images/myLogo.jpg";
$logoWidth = 15; // 15mm
$logo = $this->PageNo() . ' | '. $this->Image($logoFileName, $logoX, $this->GetY()+2, $logoWidth);
$this->SetX($this->w - $this->documentRightMargin - $logoWidth); // documentRightMargin = 18
$this->Cell(10,10, $logo, 0, 0, 'R');
}
I hope this helps and I've well understood your question.
function Footer()
{
.... /* Put your code here (see a working example below) */
$logoX = 40; //
$logoFileName = "/images/myLogo.jpg";
$logoWidth = 130; // 15mm
$logoY = 280;
$logo = $this->PageNo() . ' | '. $this->Image($logoFileName, $logoX, $logoY, $logoWidth);
$this->SetX($this->w - $this->documentRightMargin - $logoWidth); // documentRightMargin = 18
$this->Cell(10,10, $logo, 0, 0, 'C');
}
This codes are perfectly placed a image in the center of page footer.Thanks a lot pti_jul.:-)))))

whmcs server-side pagination

I'm working with WHMCS and I notice that list views are not working well.
That's because in the clientarea's list views I have tousans thousands of records to display and the DataTables is crashing.
Is there a way to paginate from the server-side? I will appreciate any idea.
Here is an idea: let' say you are viewing the Domains list page, you can use ClientAreaPage hook to create a variable to load a "paged" copy of domains:
add_hook( 'ClientAreaPage', 1, function( $vars )
{
$myVars = array();
if (App::getCurrentFilename() == 'clientarea' && isset($_GET['action']) && $_GET['action'] == 'domains') {
$domains2 = array();
foreach($vars['domains'] as $k => $domain) {
if ($k < 3) {//your code to handle pagination
$domains2[] = $domain;
}
}
$myVars['domains2'] = $domains2;
$myVars['currentpage'] = 1;
}
return $myVars;
});
In clientareadomains.tpl (template file), you need to change $domains to $domains2:
{foreach key=num item=domain from=$domains2}
Of course, it is not simple task, you need to handle pagination in the hook and the tpl files.
Hope it helps.

CMS and store hi-resolution images in generated pdf

I'm looking for good CMS for publishing software manuals.
Requirements:
publish manual pages as web pages with thumbnails and shows full resolution after click on image,
exporting manual pages to a pdf file with full resolution images instead to thumbnails.
I found IMHO best wiki system named Tiki Wiki (https://info.tiki.org/) but when I export to pdf then I gets low resolution thumbnail.
I solve this problem by very simple Tiki Wiki code modification:
Modify lib/wiki-plugins/wikiplugin_img.php to force using full image resolution instead to thumbnail in print page mode (inserted code 1) and rescale images in generated HTML by 0.5 factor (inserted code 2):
[...]
function wikiplugin_img( $data, $params )
{
[...]
$imgdata = array_merge($imgdata, $params);
// inserted code 1 (~410 line)
if ($GLOBALS['section_class']=="tiki_wiki_page print"){
$imgdata['thumb'] = '';
}
// end of inserted code 1
//function calls
if ( !empty($imgdata['default']) || !empty($imgdata['mandatory'])) {
[...]
$fwidth = '';
$fheight = '';
if (isset(TikiLib::lib('parser')->option['indexing']) && TikiLib::lib('parser')->option['indexing']) {
$fwidth = 1;
$fheight = 1;
} else {
// inserted code 2 (~410 line)
if ($GLOBALS['section_class']=="tiki_wiki_page print"){
$fwidth = $imageObj->get_width() / 2;
$fheight = $imageObj->get_height() / 2;
} else {
$fwidth = $imageObj->get_width();
$fheight = $imageObj->get_height();
}
// end of inserted code 2 (~638 line)
}
[...]
Now, after printing to pdf by wkhtmltopdf we gets pdf with small but full resolution images.
Additional modifies:
Adds following lines to cms/cssmenus.css (or other css included in print mode) for increase bottom margin of image caption:
div.thumbcaption {
margin-bottom: 5mm;
}
Removes lines from 171 to ~175 in templates/tiki-show_content.tpl for remove the "The original document is available at" foot.

Use of SPStatefulLongOperation

Can someone give me an example of the use of SPStatefulLongOperation? It's very poorly documented.
Here's an example of code I've just used. It applies a ThmxTheme (selectedTheme) to all SPWebs in an SPSite (site).
SPStatefulLongOperation.Begin(
"Applying theme to sites.",
"<span id='trailingSpan'></span>",
(op) =>
{
op.Run((opState) =>
{
for (int i = 0; i < site.AllWebs.Count; i++)
{
// Update status.
opState.Status = String.Format(
"<script type='text/javascript'>document.all.item('trailingSpan').innerText = '{0} ({1} of {2})';</script>",
site.AllWebs[i].Title,
i + 1,
site.AllWebs.Count);
// Set the theme.
selectedTheme.ApplyTo(site.AllWebs[i], true);
}
});
op.End(System.Web.HttpContext.Current.Request.UrlReferrer.ToString());
});
Note that the current value of opState.State is appended to the client's HTML (via HttpContext.Current.Response.Write and .Flush) every second. Thus you don't want to send any status message directly; you want to send some JavaScript that will update an existing status element on the page. (Here, the trailingSpan element.)