Hi and thanks by advance for you helps.
I'm trying to write on a PDF with FPDF on PHP.
I'm actually working on WordPress.
If I'm using this code on my first website, it's working well:
if (isset($_GET["obtenir-mon-analyse"])){
$pdfFile = getcwd() . '/wp-content/themes/childtheme/ressources/PDF_analyse_template.pdf';
require_once('library/fpdf/fpdf.php');
require_once('library/fdpi/src/autoload.php');
// initiate FPDI
$pdf = new setasign\Fpdi\Fpdi();
// add a page
$pdf->AddPage("L");
// set the source file
$pdf->setSourceFile($pdfFile);
// import page 1
$tplIdx = $pdf->importPage(1);
// use the imported page and place it at point 10,10 with a width of 100 mm
$pdf->useTemplate($tplIdx, 0,0 );
$pdf->Output('I');
}
But, with the same code on another website, the PDF generated by the output function is empty (0kb).
Also, the template is working because FDPF is well detecting the available page number.
PS:
The 2 website are hosting on the same host.
I have not any error.
I really don't know where is the problem.
Thanks a lot.
I think nobody will see this answer but:
On wordpress
With the plugin WP-optimize
If you use the mimify option on HTML, you will not be able to use FPDF
Related
I'm new to using FPDF / FPDI. My predecessor here extended the FPDF class and I'm adding onto his code to edit his PDFs and make new ones. I've been able to create the first 3 pages of a PDF I want to make by writing values from my database into blank pages, using FPDF. All good!
Now I want to import an existing single page PDF as page 4 and write some stuff on it, and it looks like I need FPDI to do that.
I used the example here: https://www.setasign.com/products/fpdi/about as suggested by another post. However, it's just adding a blank page to the end of my PDF.
I've written the path of the PDF I want to import into my log and ensured that it is correct (I'm not getting any errors in the php log either, which I would expect if the pdf was not found).
I'm initializing the pdf as FPDF, not FPDI, so that may be the issue? But if I initialize it as FPDI then I get an error that my methods are undefined, because they are defined extending the FPDF class. So I'm not sure how to do what I want...do I need to redefine my classes to extend FPDI? I'm just worried this will break the PDFs already being created using some of the same methods. I'm also not getting any errors about using FPDI methods like useImportedPage...so I feel like maybe that's not the issue?
Sorry if I'm not explaining this well, let me know if you have questions. Here is the relevant code:
require_once(APPPATH.'libraries/fpdf/fpdf.php');
require_once(APPPATH.'libraries/fpdi/autoload.php');
require_once(APPPATH.'libraries/fpdi/Fpdi.php');
public function make_fieldpacketMA(){
$plotID=$this->input->get('PlotID');
$year=$this->input->get('Year');
$pdf = new PDF('P','in','Letter');
// Make additional info first page- this works!
$additional_info=$this->fhm_model->get_additionalplotinfo($plotID, "MA");
$pdf->AdditionalInfoSheet($additional_info, $pdf);
//make plot info pages (same as subplot info pages on VT style plots)- this works!
$plotInfo=$this->fhm_model->get_sheetinfoMA($plotID,$year);
$pdf->SubplotSheet($plotInfo, "MA", $pdf);
//make seedling sheet from existing template- this does not work
$seedlingInfo=$this->fhm_model->get_seedlingInfo($plotID, $year);
$pdf->SeedlingSheet($seedlingInfo, $pdf);
//Write the output
$rand=uniqid();
$filename='./fhm_sheets/PlotPacket_'.$rand.'.pdf';
$pdf->Output($filename,"F");
$this->load->helper('download');
$data = file_get_contents($filename);
force_download($plotID.'_'.($year+1).'_FHMPlotPacket.pdf',$data);
}
//Create PDF creation class
class PDF extends PDF_Rotate{
function SeedlingSheet($seedlingInfo=array()) {
$pageCount = $this->setSourceFile(FCPATH.'fhm_template/MAFHM_Microplot_SeedlingForm.pdf');
$pageId = $this->importPage(1);
$this->AddPage();
// $this->useTemplate($pageId);
$this->useImportedPage($pageId, 10, 10, 90);
}
This works! Looks like I needed a second argument for importPage to define the bounding box
function SeedlingSheet($seedlingInfo=array()) {
$pageCount = $this->setSourceFile(FCPATH.'fhm_template/MAFHM_Microplot_SeedlingForm.pdf');
$pageId = $this->importPage(1, \setasign\Fpdi\PdfReader\PageBoundaries::MEDIA_BOX);
$this->AddPage();
$this->useTemplate($pageId, 0, 0);
}
I have many PDFs that are generated and uploaded to my server.
The problem is they contain the same page three times (3 pages in total with the same content).
My goal is to edit the PDF with PHP so that it contains only one page.
Is there any library that allows me to simply load a PDF and keep only the first page?
Thank you!
Using FPDI, you can create a function to extract the first page of a PDF file:
function first_page ($path) {
$pdf = new FPDI();
$pdf->AddPage();
$pdf->setSourceFile($path);
$pdf->useTemplate($pdf->importPage(1));
return $pdf;
}
Then output the extracted PDF as you would do with FPDF:
// Extract first page from /path/to/my.pdf
// and output it to browser with filename "MyPDF".
first_page('/path/to/my.pdf')->Output('MyPDF', 'I');
FPDF (http://www.fpdf.org/) or MDPF (http://www.mpdf1.com/mpdf/index.php) are great libraries for work with PDF files. I have experiences only with creating PDF; but I assume that one of those libraries can solve your problem.
Edit: Here is some example with FPDF
https://gist.github.com/maccath/3981205
I'm trying to merge 2 PDF, one on my server (not dynamically generated) and one generated just before the merge and not saved anywhere on the server (I just want my client to download it). So I only have the pdf's content. Both PDF have the same format (A4).
The merged file will have 2 pages and won't be saved on server as well.
Since, I'm using Zend Framework, I would prefer a solution with it (can't find one online...) else any advice ?
(common solution found online but doesn't work)
Edit : because people are lazy to click. The code is in the link anyway since it's wrong and doesn't work.
I try the script below, but I get the
error:
Uncaught exception
'Zend_Pdf_Exception' with message
'Page is attached to one documen, but
rendered in context of another
Alright, with the guide from #Gordon 's comment in my question, I got a solution.
You must have at least Zend Framework 1.11 (I was in 1.9, first error) (found thanks to the 3rd comment to this question)
You must clone page from the PDF you want to merge, else, your application will print an error (self explanatory one) (found thanks to this slideshare which is very interesting for Zend_Pdf)
The static PDF must be a PDF <= 1.4 (mine was 1.6). Zend_Pdf can't parse PDF which version is > 1.4
I used this application to convert the static files I had in version 1.6 to 1.4.
Here's the rough code I have and work (I know it's not optimised, I'll do it later; but still, it can be useful)
$pdf2show = new Zend_Pdf(); // Initializing the merged PDF
$pdf1 = Zend_Pdf::parse($pdfContent, 1); // $pdfContent is the generated one, got the content...
$template = clone $pdf1->pages[0]; // cloning the page (a must do)
$page1 = new Zend_Pdf_Page($template); // Creating the first page of the merged PDF with the previous content
$pdf2show->pages[] = $page1; // Adding this page to the final PDF
$pdf2 = Zend_Pdf::load('urlToYourPDF.pdf'); // Loading the statif PDF
$template2 = clone $pdf2->pages[0]; // cloning the page (a must do)
$page2 = new Zend_Pdf_Page($template2); // Creating the second page of the merged PDF with the previous content
$pdf2show->pages[] = $page2; // Adding this page to the final PDF
sendToWebBrowser('title', $pdf2show->render());
sendToWebBrowser is a function sending the PDF content to browser with the title as... title.
$pdf2show->render() produces the merged PDF content as a string.
$extractor = new Zend_Pdf_Resource_Extractor();
$clone_page_to_use_in_any_pdf = $extractor->clonePage($original_pdf->pages[0]);
This is how I did it.
Hope this helps everyone.
TJ
$extractor = new Zend_Pdf_Resource_Extractor();
$page1 = $extractor->clonePage($pdf->pages[$templatePageIndex1]);
$page2 = $extractor->clonePage($pdf->pages[$templatePageIndex2]);
$page1->drawText('Some text...', $x, $y);
$page2->drawText('Another text...', $x, $y);
$pdf = new Zend_Pdf();
$pdf->pages[] = $page1;
$pdf->pages[] = $page2;
Right from the horses mouth.
http://framework.zend.com/manual/en/zend.pdf.pages.html#zend.pdf.pages.cloning
My experience in merging pdfs :
Zend_Pdf is slow and not efficient for large compilations,
pdftk loose document's bookmarks and crashed if document's size is larger than document merged,
pdflib is really fast and preserve bookmarks, is efficient for large compilations.
Have you tried merging them using the PDF toolkit?
Merging multiple PDFs with it can be achieved using :
pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf
123.pdf will be the resulting PDF. You can temporarily store the resulting PDF on the server, send it to the browser and remove it when it's no longer needed.
In a web app developed in PHP we are generating Quotations and Invoices (which are very simple and of single page) using TCPDF lib.
The lib is working just great but it seems to generate very large PDF files. For example in our case it is generating PDF files as large as 4 MB (+/- a few KB).
How to reduce this bloating of PDF files generated by TCPDF?
Here is code snippet that I am using
ob_start();
include('quote_view_bag_pdf.php'); //This file is valid HTML file with PHP code to insert data from DB
$quote = ob_get_contents(); //Capture the content of 'quote_view_bag_pdf.php' file and store in variable
ob_end_clean();
//Code to generate PDF file for this Quote
//This line is to fix a few errors in tcpdf
$k_path_url='';
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');
// create new PDF document
$pdf = new TCPDF();
// remove default header/footer
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// add a page
$pdf->AddPage();
// print html formated text
$pdf->writeHtml($quote, true, 0, true, 0); //Insert Variables contents here.
//Build Out File Name
$pdf_out_file = "pdf/Quote_".$_POST['quote_id']."_.pdf";
//Close and output PDF document
$pdf->Output($pdf_out_file, 'F');
$pdf->Output($pdf_out_file, 'I');
///////////////
enter code here
Hope this code fragment will give some idea?
You need to see what it is putting inside the PDF. Is it embedding lots of images or fonts?
You can examine the contents with lots of PDFtools. If you have Acrobat 9.0, there is a blog article showing how to do this at http://pdf.jpedal.org/java-pdf-blog/bid/10479/Viewing-PDF-objects
Finally I have managed to solve the problem.
The problem was that by mistake I had inserted a link to email id in the web page that was getting rendered to PDF. By just removing this link the size of the generated PDF went down to just 260 kb!
Thanks everyone who tried to help me out in solving this problem.
Current TCPDF version now includes font subsetting by default to dramatically reduce PDF size.
Check the TCPDF website at http://www.tcpdf.org and consult the official forum for further information.
I have several PDF templates that I would like to load and modify and output using tcpdf.
Is it possible to load an existing PDF and use it as a starting point in tcpdf?
You want to use FPDI.
There's some example code here.
I have tried the free version of FPDI but does not support PDF version 1.5 or higher.
If someone else is looking for a free solution I have used TCPDI. You can find it on github https://github.com/pauln/tcpdi
If you are using composer, you can find some fork for composer too. Just search tcpdi on github.
Once you add it to your project, the code is quite simple. It is an extension of TCPDF so all your previous code keep working
This is a snippet from my code. I used it to save a copy of the privacy policy (a static pdf) with the user name and agreement date on each page footer.
// Create new PDF document
$pdf = new TCPDI(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
...
// Add the pages from the source file.
$pagecount = $pdf->setSourceFile($policyPdfPath);
for ($i = 1; $i <= $pagecount; $i++) {
$tplidx = $pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($tplidx);
// Add agreement text in document footer
$pdf->SetXY(15,282);
$pdf->Cell(180, 5, "Documento approvato da {$fullName} il {$date}", 0, 0, 'C');
}
// Send PDF on output
$pdf->Output(FOLDER_PATH . DIRECTORY_SEPARATOR . "{$userId}.pdf", 'F');
For anyone else finding this, it does appear a PARSER and import class were built for TCPDF (https://tcpdf.org/docs/srcdoc/TCPDF/source-class-TCPDF_IMPORT/#50-100) but as of 2018 was still under development.
Its also worth noting that the solutions above do not allow the contents of the PDF pages to be edited. In other words you import the page as a whole, you cannot edit text content or images.
You can use fpdf with fpdi. You can’t modify directly a template, but you can add a text cell with a white background to cache the old content (note that the old content can be read by using some tools). Then save your new pdf. This tools are relatively easy to use. To resolve the fact that fpdi not read 1.5 pdf version in the free version, you can convert 1.5 version in 1.4 version by using ghost script with the exec command. I use this and work fine.