Thanks in advance...
I am trying to generate a pdf in CodeIgniter using the fpdi and tcpdf libraries using the following code...
<?php
use setasign\Fpdi;
require_once('tcpdf/tcpdf.php');
require_once('fpdi2/autoload.php');
class Pdf extends Fpdi\Tcpdf\Fpdi
{
/**
* "Remembers" the template id of the imported page
*/
protected $logo;
/**
* Draw an imported PDF logo on every page
*/
function Header()
{
if ($this->logo === null) {
$this->setSourceFile(base_url().'assets/pdf/logo.pdf'); //Will work if these 3 lines are commented
$this->logo = $this->importPage(1); //Will work if these 3 lines are commented
}
$size = $this->useImportedPage($this->logo, 130, 5, 60); //Will work if these 3 lines are commented
$this->SetFont('freesans', 'B', 20);
$this->SetTextColor(0);
$this->SetXY(PDF_MARGIN_LEFT, 5);
$this->Cell(0, 30, 'TCPDF and FPDI');
}
}
// initiate PDF
$pdf = new Pdf();
$pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
$pdf->SetAutoPageBreak(true, 40);
// add a page
$pdf->AddPage();
$pdf->Write(5, "hello world");
$pdf->Output('generated.pdf', 'I');
?>
It runs and generates the pdf if I comment the lines I mention in the inline comments, but generates the error:
Type: InvalidArgumentException Message: Given stream is not seekable!
when I uncomment those lines.
The code works in my local server outside codeigniter.
I am able to embed the pdf in another view, so it is not a problem with the pdf nor with a restriction of accessing pdfs from my assets folder.
The same problem happens when I try to load an external font.
The view is being called by the controller this way...
class Projects extends CI_Controller{
public function fpdi(){
$this->load->view('projects/fpdi');
}
}
Thanks a lot!
(note that this is an oversimplification of the problem, I am not loading the libraries inside the view, this is just to make the problem as concise as possible for demonstration purposes)
edit-UPDATE tried the same thing with fpdf and I still get the same error "Given stream is not seekable".
UPDATE 2! Thanks to Jan Slabon's advice I kind of solved it, a replaced base_url() helper with CodeIgniter constant FCPATH so the path was relative and not a URL. Apparently this is required for fopen to function properly which is used by the fpdi library.
I don't know more and I feel this is inelegant solution but it works for now! If anybody has more info it would be greatly appreciated.
Changed the source from base_url() to relative path FCPATH. (More info at the bottom of question.)
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);
}
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
When I generate and save a document with a link in it using TCPDF. It is always showing a save as dialog before closing in the pdf reader.
"Do you want to save the changes to file.pdf before closing?"
Also there is a yellow note box in the chrome browser when I hover over the link... as shown in the image below.
My code with problem is like this.
$pdf->writeHTML('link');
However, if my links are empty in my html then there is no problem while closing the pdf, also then there is no yellow box anymore in links. The following code for example is working fine.
$pdf->writeHTML('link');
Here is a complete example to reproduce the problem.
require_once __DIR__.'../../external_classes/TCPDF/tcpdf.php';
$pdf = new \TCPDF();
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('ABC');
$pdf->SetTitle('ABC');
$pdf->SetSubject('ABC');
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, "ABC", "ABC");
$pdf->setPrintFooter(false);
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('helvetica', '', 10);
$pdf->AddPage();
$pdf->writeHTML('link');
ob_clean();
$pdf->Output('example.pdf', 'D');
The above example will generate the output like the following image. Which will have both the problems, I have tested both on tcpdf version 5.9.x and 6.2.x.
Okay, found some explanation to both the problems.
1. First Problem: The issue of Save as Dialog
For some reason the tcpdf library is appending my website html at the end of the pdf. I found this out by viewing my pdf in pure text using a text editor.
Using an exist function immediately after output() will fix it.
$pdf->Output('example.pdf', 'D');
exit();
2. Second Problem: The issue of yellow link box in chrome
This is currently an unresolved active issue in chrome. Check this link for example on mPdf forum.
You may resolve the second problem by removing annotations at all.
Create your own class MyTCPDF extends \TCPDF.
Copy to created class "protected function _putannotsobjs()" from tcpdf.php. You will override it.
Change this string in method form
`$annots .= ' /Contents ' . $this->_textstring($pl['txt'], $annot_obj_id);`
enter code here
to
`$annots .= ' /Contents ()';`
Use your class for generation pdf file.
You may put any logic in this method an disable annotations by constant or something else.
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 have bunch of images and I want to generate PDF of of all those images. I am using FPDF library (version 1.7) for achieving this. But I am getting the following error:
FPDF error: Could not include font definition file
I found some articles on google regarding this error and tried that but still problem persist.
What should be the problem here? Where I am going wrong?
I had a similar error and i share here because there is no documentation online.
"FPDF error: Font file not found"
If you convert a ttf font file for use it in FPDF with the online utility (http://fpdf.fruit-lab.de) once you have downloaded the files you need (file.php, file.afm, file.z)
you'll have to:
1) put in font folder (or any other folder, but you should use this instruction define('FPDF_FONTPATH','yourpath/yourfolder/');)
2) If you RENAME the files, you should open the file.php and search for "$file" which contains the name of the ".z" file and rename it properly.
Maybe a bit too late, but I used to have that same problem and the solution was to simply give permissions to the /font/ folder...
Rookie mistake... 755 permissions did the trick for me.
define('FPDF_FONTPATH','font/');
check in above line for correct path from local folder to server.....
exactly it runs well
define('FPDF_FONTPATH','font/');
require('fpdf.php');
class PDF extends FPDF
{
//Constructor (mandatory with PHP3)
function PDF()
{
self::__construct();
}
public function __construct()
{
$this->FPDF();
}
//Page header
function Header()
{
//Logo
//$this->Image('logo_pb.png',10,8,33);
//Arial bold 15
$this->SetFont('Arial','B',15);
//Move to the right
$this->Cell(80);
//Title
$this->Cell(30,10,'Title',1,0,'C');
//Line break
$this->Ln(20);
}
//Page footer
function Footer()
{
//Position at 1.5 cm from bottom
$this->SetY(-15);
//Arial italic 8
$this->SetFont('Arial','I',8);
//Page number
$this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
}
}
echo "<br/>";
//Instanciation of inherited class
$pdf=new PDF();
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('Times','',12);
$pdf->Image('logo_pb.png',40,20,33);
$url="demo/ivv/doc.pdf";
$dir='C:/xampp/htdocs/laravel/public/pdf/';
$filename= time().'.pdf';
$content=$pdf ->Output($dir.$filename);
?>
You must create the font definition files for the fonts you are using.
See here:
http://www.fpdf.de/tutorials/7/
Check your font path in AddFont function.
For example:
$fontInformation = pathinfo(WWW_ROOT . "files/files/font/file/" . $pdffile['font_file']);
$fontFileName = $fontInformation['filename'] . '.php';
//$pdf->fontpath = WWW_ROOT . "files/font/file/";
$pdf->AddFont($fontInformation['filename'], '', $fontFileName);
//set font for the entire document
$pdf->SetFont($fontInformation['filename'], '', 20);
This may solve your problem.
I had this kind of problem and my issue was that I was using a linux web server and I made the mistake of not using the correct case in my references to my font files.
After I changed "Arial" to "arial" the problem was resolved.