TCPDF Header and Top Margin on fist page only then no header and different top margin on remaining pages - tcpdf

I am using tcpdf to generate a pdf. I only want the header to appear on the first page and have it so that it does not appear on the remaining pages. However, I would like the top margin of the remaining pages shifted up since there is no header on those pages.
I'm using MYPDF to extend TCPDF to customize the header to only show on the first page.
// Extend the TCPDF class to create custom Header and Footer
class MYPDF extends TCPDF {
//Page header
public function Header() {
if (count($this->pages) === 1) { // Do this only on the first page
$html .= 'header text';
}
$this->writeHTML($html, true, false, false, false, '');
}
}
// create new PDF document
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, 'LETTER', true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE, 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, 25, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(10);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, 20);
// 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('droidsansfallback', '', 10);
// add a page
$pdf->AddPage();
$pdf->resetColumns();
$pdf->setEqualColumns(3, 57); // KEY PART - number of cols and width
$pdf->selectColumn();
$content = '';
$content .= '
<table cellspacing="0" cellpadding="3">
';
$content .= fetch_data();
$content .= '</table>';
$pdf->writeHTML($content);
$pdf->Output('file.pdf', 'I');

Something like this worked for me:
public function Header() {
if ($this->page == 1) {
$html .= 'header text';
$this->writeHTML($html, true, false, false, false, '');
} else {
$this->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
}
}
Only write the header HTML on the first page, then change the margins for the other pages.

Related

Multiple html2canvas div content in single .pdf file

I'm using attached script to allocate content of div into .pdf file with jsPDF and html2canvas.
All works nicely with content of one single div (inputdiv).
However, I would like to add conent from few more additional div's into same .pdf file.
Question is how to do that?
With approach from below, only content of single div can be mapped through relevant canvas function. I tried to find some extra details in documentation and also here but unfortunately without success.
Any reference would be highly appreciated!
function generatePDF() {
var doc = new jsPDF ("l", "mm", "a4", "true");
html2canvas(inputdiv, {
width: 2000,
height: 1450,
scale: 2,
onclone: function (clonedDoc) {
clonedDoc.getElementById('inputdiv').style.display = 'block';
}
})
.then(function(canvas) {
var imgData = canvas.toDataURL('image/jpeg',1.0);
const imgProps= doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, 'jpeg', 14, 19, pdfWidth, pdfHeight, undefined, 'FAST');
doc.save('File.pdf');
});
}
This is an example of how you can solve this, for 2 divs that will print on 2 pages.
Of course if you have many divs, it would need to be refactored to avoid code repetition; but this one worked for me to include 2 different divs.
html2canvas(div1)
.then((canvasDiv1) =>{
//...
pdf.addImage(/* ... */);
})
.then(() => {
pdf.addPage();
html2canvas(div2)
.then((canvasDiv2) => {
//...
pdf.addImage(/* ... */);
// save on the last element
pdf.save(/* ... */);
})
})
If you need both divs to be on the same page, then just remove the pdf.addPage() and adjust the coordinates to place the second div where you need.

TCPDF footer image overlapping on main content

I am using tc pdf library to generate pdf.
I have set custom hedar and footer like below
class CustomTcpdf extends \TCPDF {
public function Header() {
$headerData = $this->getHeaderData();
$this->writeHTML($headerData['string'], true, false, true, false, '');
}
public function Footer() {
// Position at 15 mm from bottom
$this->SetY(-50);
$image_file = 'footer.png';
$this->Image($image_file, 15, 250, 183);
}
}
Following is the code for creation
$tcpdf = new CustomTcpdf();
$tcpdf->setHeaderData($ln = '', $lw = 0, $ht = '', $pdf_header_data, $tc = array(0, 0, 0), $lc = array(0, 0, 0));
$tcpdf->AddPage('A4', 'Portrait');
$tcpdf->SetFooterMargin(60);
//$tcpdf->setHeaderMargin(40);
$tcpdf->SetAutoPageBreak(TRUE, 0);
$tcpdf->SetY(70);
$tcpdf->writeHTML($content, true, false, true, TRUE, '');
$tcpdf->Output('HAKO.pdf', 'I');
output for footer is as below
Expected output is,
Instant of overlapping the content should come on next page.
I use the following code in header function like below
class CustomTcpdf extends \TCPDF {
public function Header() {
$headerData = $this->getHeaderData();
$this->writeHTML($headerData['string'], true, false, true, false, '');
$this->SetTopMargin(70);
}
}
With the help of this->SetTopMargin(70) solve the header problem
and for footer $tcpdf->SetAutoPageBreak(TRUE, 65); 65 is margin from bottom with this 2 mothod overlapping issue will be solve.

Create footer with page number not displayed using Document object of EvoPdf

I have a pdf file that converted from html by EvoPdf HtmlToPdfConverter. I read the file bytes by evopdf Document Class and add footer element to it. after saving the bytes - it's displaying inline webBrowser.
the footer with page number isn't displayed.
This is my code:
Document pdfDoc = new Document("myFilePath.pdf");
//create the footer element
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font( new System.Drawing.FontFamily("Arial"), 10, System.Drawing.GraphicsUnit.Point));
footerText.EmbedSysFont = true;
footerText.TextAlign = HorizontalTextAlign.Right;
pdfDoc.AddFooterTemplate(50);
pdfDoc.Footer.AddElement(footerText);
byte[] outBuffer = pdfDoc.Save();
pdfDoc.Close();
//...
If I add the footer element to the htmlToPdfConverter it displayed well.
how can I display it?
Thanks.
I have also run into the same situation. Basically, I wanted to add header and footer to existing PDFs without using htmltopdfconverter.
Here is the solution with a few tweaks to your existing code:
//Create a blank document.
Document MergeDocument = new Document();
Document pdfDoc = new Document("myFilePath.pdf");
//Merged n number of existing PDFs to newly created document.
MergedDocument.AppendDocument(pdfDoc, true, true, true);
//create the footer element
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font( new System.Drawing.FontFamily("Arial"), 10, System.Drawing.GraphicsUnit.Point));
footerText.EmbedSysFont = true;
footerText.TextAlign = HorizontalTextAlign.Right;
//Apply footer to the newly created document after all documents appended.
MergeDocument.AddFooterTemplate(50);
MergeDocument.Footer.AddElement(footerText);
byte[] outBuffer = MergeDocument.Save();
MergeDocument.Close();
In order to apply headers and footer on existing PDF documents you have to create an empty Document object, define the header and footer and then append the external PDF documents using the method Document.AppendDocument(Document doc, bool enableHeaderAndFooter, bool drawHeaderOnFirstPage, bool drawFooterOnFirstPage).
Below you can find a complete example for this. You can also find an online demo at Add Header and Footer in External PDF
public void protected void createPdfButton_Click(object sender, EventArgs e)
{
// Create a PDF document
Document pdfDocument = new Document();
// Add a PDF page to PDF document
PdfPage pdfPage = pdfDocument.AddPage();
try
{
// Add a default document header
AddHeader(pdfDocument, true);
// Add a default document footer
AddFooter(pdfDocument, true, true);
// Create a HTML to PDF element to add to document
HtmlToPdfElement htmlToPdfElement = new HtmlToPdfElement(0, 0, urlTextBox.Text);
// Optionally set a delay before conversion to allow asynchonous scripts to finish
htmlToPdfElement.ConversionDelay = 2;
// Add HTML to PDF element to document
pdfPage.AddElement(htmlToPdfElement);
// Automatically close the external PDF documents after the final document is saved
pdfDocument.AutoCloseAppendedDocs = true;
// Insert an external PDF document in the beginning of the final PDF document
string pdfFileBefore = Server.MapPath("~/DemoAppFiles/Input/PDF_Files/Merge_Before_Conversion.pdf");
Document startExternalDocument = new Document(pdfFileBefore);
pdfDocument.InsertDocument(0, startExternalDocument, addHeaderFooterInInsertedPdfCheckBox.Checked,
showHeaderInFirstPageCheckBox.Checked, showFooterInFirstPageCheckBox.Checked);
// Append an external PDF document at the end of the final PDF document
string pdfFileAfter = Server.MapPath("~/DemoAppFiles/Input/PDF_Files/Merge_After_Conversion.pdf");
Document endExternalDocument = new Document(pdfFileAfter);
pdfDocument.AppendDocument(endExternalDocument, addHeaderFooterInAppendedPdfCheckBox.Checked, true, true);
// Save the PDF document in a memory buffer
byte[] outPdfBuffer = pdfDocument.Save();
// Send the PDF as response to browser
// Set response content type
Response.AddHeader("Content-Type", "application/pdf");
// Instruct the browser to open the PDF file as an attachment or inline
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=Header_Footer_in_External_PDF.pdf; size={0}", outPdfBuffer.Length.ToString()));
// Write the PDF document buffer to HTTP response
Response.BinaryWrite(outPdfBuffer);
// End the HTTP response and stop the current page processing
Response.End();
}
finally
{
// Close the PDF document
pdfDocument.Close();
}
}
/// <summary>
/// Add a header to document
/// </summary>
/// <param name="pdfDocument">The PDF document object</param>
/// <param name="drawHeaderLine">A flag indicating if a line should be drawn at the bottom of the header</param>
private void AddHeader(Document pdfDocument, bool drawHeaderLine)
{
string headerHtmlUrl = Server.MapPath("~/DemoAppFiles/Input/HTML_Files/Header_HTML.html");
// Create the document footer template
pdfDocument.AddHeaderTemplate(60);
// Create a HTML element to be added in header
HtmlToPdfElement headerHtml = new HtmlToPdfElement(headerHtmlUrl);
// Set the HTML element to fit the container height
headerHtml.FitHeight = true;
// Add HTML element to header
pdfDocument.Header.AddElement(headerHtml);
if (drawHeaderLine)
{
float headerWidth = pdfDocument.Header.Width;
float headerHeight = pdfDocument.Header.Height;
// Create a line element for the bottom of the header
LineElement headerLine = new LineElement(0, headerHeight - 1, headerWidth, headerHeight - 1);
// Set line color
headerLine.ForeColor = Color.Gray;
// Add line element to the bottom of the header
pdfDocument.Header.AddElement(headerLine);
}
}
/// <summary>
/// Add a footer to document
/// </summary>
/// <param name="pdfDocument">The PDF document object</param>
/// <param name="addPageNumbers">A flag indicating if the page numbering is present in footer</param>
/// <param name="drawFooterLine">A flag indicating if a line should be drawn at the top of the footer</param>
private void AddFooter(Document pdfDocument, bool addPageNumbers, bool drawFooterLine)
{
string footerHtmlUrl = Server.MapPath("~/DemoAppFiles/Input/HTML_Files/Footer_HTML.html");
// Create the document footer template
pdfDocument.AddFooterTemplate(60);
// Set footer background color
RectangleElement backColorRectangle = new RectangleElement(0, 0, pdfDocument.Footer.Width, pdfDocument.Footer.Height);
backColorRectangle.BackColor = Color.WhiteSmoke;
pdfDocument.Footer.AddElement(backColorRectangle);
// Create a HTML element to be added in footer
HtmlToPdfElement footerHtml = new HtmlToPdfElement(footerHtmlUrl);
// Set the HTML element to fit the container height
footerHtml.FitHeight = true;
// Add HTML element to footer
pdfDocument.Footer.AddElement(footerHtml);
// Add page numbering
if (addPageNumbers)
{
// Create a text element with page numbering place holders &p; and & P;
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font(new System.Drawing.FontFamily("Times New Roman"), 10, System.Drawing.GraphicsUnit.Point));
// Align the text at the right of the footer
footerText.TextAlign = HorizontalTextAlign.Right;
// Set page numbering text color
footerText.ForeColor = Color.Navy;
// Embed the text element font in PDF
footerText.EmbedSysFont = true;
// Add the text element to footer
pdfDocument.Footer.AddElement(footerText);
}
if (drawFooterLine)
{
float footerWidth = pdfDocument.Footer.Width;
// Create a line element for the top of the footer
LineElement footerLine = new LineElement(0, 0, footerWidth, 0);
// Set line color
footerLine.ForeColor = Color.Gray;
// Add line element to the bottom of the footer
pdfDocument.Footer.AddElement(footerLine);
}
}

processAjaxOnInit: is set to "false" but Ajax is still called

I'm preloading my table using PHP and then have processAjaxOnInit: false in my config. What happens is that the call to my Ajax url is still made and instead of appending rows to the table it wipes out the rows that are there. I'm assuming that it's still making the call to get the total number of rows. Can I set this on page load and completely bypass calling the Ajax url?
Thanks
.tablesorterPager({
container: $(".pager"),
ajaxUrl : '/documents_table_data.php?page={page}&size={size}&{filterList:filter}&{sortList:column}',
// use this option to manipulate and/or add additional parameters to the ajax url
customAjaxUrl: function(table, url) {
// manipulate the url string as you desire
//url += '&archive=<?php echo $_GET[archive] ?>&wor=<?php echo $_GET[wor] ?>';
// trigger a custom event; if you want
$(table).trigger('changingUrl', url);
// send the server the current page
return url;
},
ajaxError: null,
ajaxObject: {
dataType: 'json'
},
ajaxProcessing: function(data){
if (data && data.hasOwnProperty('rows')) {
var r, row, c, d = data.rows,
total = data.total_rows,
headers = data.headers,
rows = [],
len = d.length;
for ( r=0; r < len; r++ ) {
row = [];
for ( c in d[r] ) {
if (typeof(c) === "string") {
row.push(d[r][c]);
}
}
// is there a way to do that here when it pushes the row onto the array
// or perhaps there is another funtion you have implemented that will let me do that
rows.push(row);
}
return [ total, rows, headers ];
}
},
// Set this option to false if your table data is preloaded into the table, but you are still using ajax
processAjaxOnInit: false,
output: '{startRow} to {endRow} ({totalRows})',
updateArrows: true,
page: 0,
size: 10,
savePages: true,
storageKey: 'tablesorter-pager',
pageReset: 0,
fixedHeight: false,
removeRows: false,
countChildRows: false,
// css class names of pager arrows
cssNext : '.next', // next page arrow
cssPrev : '.prev', // previous page arrow
cssFirst : '.first', // go to first page arrow
cssLast : '.last', // go to last page arrow
cssGoto : '.gotoPage', // page select dropdown - select dropdown that set the "page" option
cssPageDisplay : '.pagedisplay', // location of where the "output" is displayed
cssPageSize : '.pagesize', // page size selector - select dropdown that sets the "size" option
// class added to arrows when at the extremes; see the "updateArrows" option
// (i.e. prev/first arrows are "disabled" when on the first page)
cssDisabled : 'disabled', // Note there is no period "." in front of this class name
cssErrorRow : 'tablesorter-errorRow' // error information row
});
I just added a pager option named initialRows (currently only available in the master branch). When processAjaxOnInit is false and this option is set, no initial ajax call to the server is done (demo):
$(function(){
$('table').tablesorter({
widgets: ['pager'],
widgetOptions : {
pager_processAjaxOnInit: false,
pager_initialRows: {
// these are both set to 50 initially
// the server can return different values
// and the output will update automatically
total: 50,
filtered: 50
},
// other ajax settings...
}
});
});

TCPDF Qr code resize on small size page

I use this code for create a 80x30 mm pdf file with a 25x25 mm qrcode: I change the qrcode width and height but it doesn't resize and I always see a little qrcode into the page.
Where is the error?? Please help me... I can't undertand the problem! :)
<?php
require_once('../config/lang/eng.php');
require_once('../tcpdf.php');
// create new PDF document
$pdf = new TCPDF("L", "mm", array(80,30) , true, 'UTF-8', false);
//set margins
$pdf->SetMargins(0, PDF_MARGIN_TOP, 0);
$pdf->SetHeaderMargin(0);
$pdf->SetFooterMargin(0);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
//set auto page breaks
$pdf->SetAutoPageBreak(false, 0);
//set image scale factor
$pdf->setImageScale(1);
//set some language-dependent strings
$pdf->setLanguageArray($l);
// add a page
$pdf->AddPage();
$pdf->SetAutoPageBreak(false, 0);
// new style
$style = array(
'border' => false,
'padding' => 'auto',
'fgcolor' => array(0,0,0),
'bgcolor' => false
);
$pdf->write2DBarcode('http://www.google.it/', 'QRCODE,H', 50, 1, 300, 300, $style, 'N');
// ---------------------------------------------------------
//Close and output PDF document
$pdf->Output('test.pdf', 'I');
//============================================================+
// END OF FILE
//============================================================+
?>
Thank you!!!
Problem solved:
Before:
[...]
$pdf = new TCPDF("L", "mm", array(80,30) , true, 'UTF-8', false);
[...]
$pdf->AddPage();
[/code]
After:
[code]
[...]
$pdf = new TCPDF("P", "mm", array(80,30) , true, 'UTF-8', false);
[...]
$pdf->AddPage('L', '', false, false);
[/code]
The problem is the constructor page orientation that create confusion to the system: default portrait is ok, I have only to change the Add page orientation to Landscape and the problem is solved.
Thank you again for the attention.
:)

Resources