The problem is, I need to write data to several copies of the same imported pdf file, and save it as one pdf. I can write data to one page just fine, but when I try to write to more than one, or even continue text (using SetAutoPageBreak()), it simply stops writing once it hits the next page. Although, if I add an arbitrary loop to write more data, the resulting pdf's number of pages is increased to accommodate the added data, but the pages beyond the first are still blank. I have simplified what I'm trying to do into a smaller example to illustrate the issue:
public function actionSample() {
$pdf = new FPDI();
$pdf->AcceptPageBreak();
$pdf->SetAutoPageBreak(true, 30);
$pagecount = $pdf->setSourceFile('images/sample.pdf');
for ($i = 1; $i <= $pagecount; $i++) {
$pdf->AddPage();
$tplidx = $pdf->ImportPage($i);
$pdf->useTemplate($tplidx, 10, 10, 200);
$s = $pdf->getTemplatesize($tplidx);
$pdf->SetTextColor(32,32,32);
$pdf->SetFontSize(10);
$pdf->SetXY($pdf->getX(), $pdf->getY()+10);
$pdf->Write(2, 'This is not!');
}
$pdf->Output('Sample.pdf', 'D');
}
The sample document has 3 blank pages initially. (I did this to make it easier to see what was being written)
$pdf->AddPage();
you have to just put this piece of code inside for loop near closing braces.
All the best..!!
Related
I'm using setasign V1 as our servers are yet to be updated past 5.5.9 and am trying to import the first page from 3 different pdf's to create a new pdf. But if I use any more than one file, I get an error.
I am also running this using the Slim framework and have had to add namespaces to each of the setasign files to get them to read in.
It works perfectly with single files, but not when trying to get a page out of multiple files.
In my below code, the loop goes through each file to get the first page and then add some text. This is a function where I pass in an array of "jobs" and also the $savedFile path to save to.
If I put the line "$pdf->setSourceFile($file)" before the loop and define $file as any of the files in the $inputFiles array, it works fine but obviously has just the first page of the first file on each of the 3 pages created. It also works if I make it bring in just the second file or just the third. But if I put this line inside the loop I get an Empty Response error.
I have also tried to unset the parser at the end of each loop but that didn't make any difference.
At the moment, I can't figure out where it's going wrong as no error details are thrown.
$pdf = new FPDI();
$inputFolder = $_SERVER["DOCUMENT_ROOT"] . '/' . $app->config->get('saveLocations.COC') . '/';
$inputFiles = [];
foreach($jobs as $job){
$coc = $app->coc_approval->getCOC($app, $job);
$cocFile = $coc->file;
array_push($inputFiles, $inputFolder . $cocFile);
}
foreach($inputFiles as $file){
$pdf->setSourceFile($file);
$pdf->AddPage();
$tpl = $pdf->importPage(1);
$pdf->useTemplate($tpl, 0, 0, null, null);
// Set font and color
$pdf->SetFont('Helvetica');
$pdf->SetFontSize('10');
$pdf->SetTextColor(0, 0, 0); // RGB
// Add Customer and PO details
$x = 75.5;
$pdf->SetXY($x,67);
$pdf->Cell(0, 15, $customer);
$pdf->SetXY($x, 73);
$pdf->Cell(0, 15, $PO);
//unset($pdf->parsers[$file]);
}
$pdf->Output($savedFile, 'F');
I am expecting the first page of each file listed in the $inputFiles array to be saved in the final output pdf.
Any advice would be very much appreciated thanks!
I am using FPDF and FPDI to extract 2 pages from a pdf document that is generally about 28 pages long. The pdf files are basically a page with an image filling each page entirely and are around 35-40mb.
When using FPDI to extract the last 2 pages from the full document and create a new file, the file size of the new 2 page file remains almost the same. Any ideas why this might be?
Here is the basic code used to do the extracting:
public function extractPagesFromFile($file, $outputFileName, $numPages = 2) {
$pageCount = $this->_fpdf->setSourceFile($file);
if ($numPages < 0 || $numPages > $pageCount) {
return false;
}
for ($pageNo = $pageCount - $numPages + 1; $pageNo < $pageCount + 1; $pageNo++) {
$tplIdx = $this->_fpdf->ImportPage($pageNo);
if (!isset($s)) {
$s = $this->_fpdf->getTemplatesize($tplIdx);
}
$this->_fpdf->AddPage($s['w'] > $s['h'] ? 'L' : 'P', array($s['w'], $s['h']));
$this->_fpdf->useTemplate($tplIdx);
}
$this->_fpdf->Output('F', $outputFileName);
$this->_fpdf->cleanUp();
}
FPDI copies all resources of a page. I guess that all images in your file are located in a single resource dictionary. Because of this all of them will be copied. This is a common issue when extracting pages from existing PDF documents. Without parsing and interpreting the pages content stream it is impossible to know which resources should be copied or not. There's no solution with/for FPDI atm.
Anyhow we (Setasign) offer other non-free PHP components, such as the SetaPDF-Merger, that work on a lower level and for which we'd build a demo that fixes this behaviour.
I have two features which uses FPDF in the application I am developing. The other one prints things correctly, while the other outputs only a blank sheet and I really dont know where's the error in here. I already tried to var_dump to know if values are fetch correctly from the database and everything is good except for this printing the pdf part. What should I do?
Here is the code snippet for the one that only outputs a blank sheet.
function generate(){
$sample= $this->model_a->get_a();
$j = 10;
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetMargins(0.5, 0.5, 0.5);
$pdf->Cell(40,4,'TITLE','',0,'C',0);
$pdf->setXY(12.5,$j+=4);
$pdf->SetFont('times','B',10);
$pdf->Cell(42,4,'COL1','TLRB',0,'C',0);
$pdf->Cell(100,4,'NAME','TLRB',0,'C',0);
$pdf->Cell(42,4,'NAME2','TLRB',0,'C',0);
foreach($sample as $s){
$x= $s['id'];
$y= "{$s['f_name']}, {$s['l_name']} {$s['mi']}.";
$z= "{$s['f_name1']}, {$s['l_name1']} {$student['mi1']}.";
$this->addRow($pdf,$x,$y,$z, $j);
}
$pdf->Output();
}
function addRow($pdf,$x,$y,$z,&$j){
$pdf->setXY(12.5,$j+=4);
$pdf->SetFont('times','',10);
$pdf->Cell(42,4,$x,'TLRB',0,'C',0);
$pdf->Cell(100,4,$y,'TLRB',0,'C',0);
$pdf->Cell(42,4,$z,'TLRB',0,'C',0);
}
I think that the function addRow have to return the pdf object. Alternatively you can create the new FPDF in a variable class ($this->pdf) and change all the other $pdf.
Is there a way to import pdf files which stored in database into mpdf class instance?
As for now i can use import for certain page from file only like shown below.
$mpdf->SetImportUse();
$pagecount = $mpdf->SetSourceFile('testfile.pdf');
$tplId = $mpdf->ImportPage($pagecount, 50, 50, 100, 100);
$mpdf->UseTemplate($tplId, '', '', 100, 100);
$mpdf->Output();
But what if I want to import from pdf which saved in database?
Thanks for helping.
Reading large files from a database is a bad idea, you'll find storing them somewhere on the file-system to be much faster. But, any file stored in the database should be stored in its' original form (possibly base64 encoded). Pretend the value you get from the database is the return from fread() and it should work fine.
Little bit later, but maybe this help somebody else.
With MPDF 8 and later:
Method SetSourceFile accept string (filename) OR StreamReader. The StreamReader can be created from file OR from string.
So your code will looks like:
// $mpdf->SetImportUse(); is not supported in MPDF 8
$data = ''; // your data, NOT base64
$pagecount = $mpdf->SetSourceFile(\setasign\Fpdi\PdfParser\StreamReader::createByString($data));
for ($i=1; $i<=$pagecount; $i++) {
$import_page = $mpdf->ImportPage($i, 50, 50, 100, 100); // OR just: $import_page = $mpdf->ImportPage($i);
$mpdf->UseTemplate($import_page);
if ($i < $pagecount) {
$mpdf->AddPage();
}
}
$mpdf->Output();
Note:
You can always call WriteHTML before or after or inside for cycle.
I wrote a simple FPDF code but I ran into a problem.
For some reason, the for loop skips the first row ( cell 1, cell 2, cell 3 ).
Code:
<?php
require('temp/fpdf.php');
class PDF extends FPDF
{
function Header(){
$this->SetY(0);
$this->SetFont('Arial','I',8);
$this->Cell(0,5,'Page '.$this->PageNo(),0,0,'C');
}
function Footer(){
$this->SetY(-5);
$this->SetFont('Arial','I',8);
$this->Cell(0,5,'Page '.$this->PageNo(),0,0,'C');
}
}
$pdf = new PDF();
$pdf->SetMargins(0,0,0);
$pdf->AddPage();
$pdf->SetFont('Times','',12);
for($i=0;$i<=24;$i++){
$pdf->Cell(70,30,'Printing line number '.$i,0,0,'C');
if(($i%3==0)&&($i!=0)){
$pdf->Ln();
}
}
$pdf->Output();
?>
I'm staring at the code for hours but I can't find the answer so any help is appreciated.
Your first set of printing is floating over to the right side. As a quick-fix try adding to add a line break and clear up unwanted floats in the PDF definition.
Add
$pdf->Ln();
after
$pdf->AddPage();
I see two possibilities that you might want to check. The first is that the margins are all zero, but in order for a PDF to print or save correctly, they need to be 1" on top/bottom and .5" on the sides. Also you have to consider that the first iteration of your loop $i will equal 0, and your first cell will print out 0 and not 1. Let me know if that doesn't pan out, and I can help more. I'm actually in the middle of a huge FPDF project and have found many nuances.
I just noticed this:
if(($i%3==0)&&($i!=0)){
$pdf->Ln();
}
Use this http://calculator.sdsu.edu/calculator.php to calculate the Modulus using your $i values and you'll see 0%3=0, 1%3=4, 2%3=5. That will skip your first line.
I personally would've written it like this:
$i = 1;
while($i <=25)
{
$pdf->Cell(70,30,'Printing line number '.$i,0,0,'C');
if(($i % 3) == 0)
{
$pdf->Ln();
}
}