Generate multiple pdf with Dompdf - php

I want to generate multiple PDFs in one foreach. When I run my Code, it also generates mulitple PDFs with the right name and saves it in the right folder. But the strange thing is, that only the first PDF that is generated has text in it and looks like I want it to be, and the others are all empty PDF-Files. Can someone explain, what I did wrong?
//here I get from my Database all bills, that are saved in my Database
$rgAll = $this->rechnungDatabase->getRGs();
foreach ($rgAll as $rgInfo){
$dompdf = new Dompdf();
$kundenid = $rgInfo->kundenid;
//here I get the User from my User Database
$userInfo = $this->indexDatabase->getUser($kundenid);
ob_start();
//this is a function to find my html site, the first two values are needed to find the file and the array gives the values, that are needed for the html site
$this->pageload("Rechnung", "kundenrechnung", [
'rgInfo' =>$rgInfo,
'userInfo' => $userInfo,
]);
$html = ob_get_contents();
ob_get_clean();
$dompdf->loadHtml($html);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'portrait');
// Render the HTML as PDF
$dompdf->render();
//$dompdf->stream("Rechnung".$rgInfo->rgnummer, array("Attachment"=>1));
$output = $dompdf->output();
//the PDF is now in the right folder
$filepath= __DIR__."/../../PDFRechnung/Rechnung$rgInfo->rgnummer.pdf";
file_put_contents($filepath, $output);
unset($dompdf);
}
Thank you in advance for your kind help.

Related

mpdf not generating pdf if data is larger

I'm trying to generate a labels for the members. It comes with two things Address and Name. I'm using mpdf to generate pdf. I don't know why mpdf is not generating pdf for twenty second data on-wards.
So, i tried to check it by replacing same data on 21st data on-wards. and again the result is same. I tried like below to create the problem I'm facing.
change for loop increment number from 21 to 22 and that's all...! Mpdf stops working. why only for 21st data it will generate pdf ? I Don't know.
require_once __DIR__ . '/vendor/autoload.php';
$style= "<style>html,body{height:297mm;width:210mm;padding: 8mm 4mm 8mm 4mm} p{font-size:14px;} div{overflow:hidden;width:65mm;height:38mm; float:left;border:1px solid;margin:0;padding:-2 0 -2 5px;} </style>";
for ($x = 0; $x < 21; $x++) {
$data .= "<div style='page-break-inside:avoid;padding:5px;'><p>ANAND S.N.</p><P> #54, M/S, RAJATHA ENTREPRISE V.T.STREET, SARJAPURA POST
BENGALURU RURAL, ANEKAL, 562125</P></div>";
}
$data_print = $style.'<p>'.$data.'</p>';
echo $data_print;
$mpdf = new mPDF();
// $mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML($data_print);
$mpdf->Output('mpdf.pdf','D');
I have more then twenty thousand records list and I need to take print on this format. So, will mpdf work or Do i need to go for any other alternatives.
For others who are getting same problem. once check if you gave
ob_start();
after
include('vendor_pdf/vendor/autoload.php');
followed by your php code
and then
$content = ob_get_clean(); // get content of the buffer and clean the buffer
$mpdf = new \Mpdf\Mpdf();
$mpdf->SetDisplayMode('fullpage');
$mpdf->WriteHTML($content);
$mpdf->Output();

Fill form with fpdm.php doesn't work with select value

this is my first question ever.
I have a form pdf that i need to fill with php, it works fine with fpdm. When I open the file in chrome or in Architect 4 even the dropdown list are filled but when I open the same file in Adobe Reader, everything is filled except the dropdown list.
Anyone have any thoughts about it ? I think maybe it's a conversion problem between FDF and PDF but i have really no idea on how to solve it.
EDIT :
$fieldsI = array(
/* ---------------- Beneficiaire 1 ----------------*/
'ZA1benefNom1' => $InfosFormateur[0]['nom'],
'ZA1benefPrenom1' => $InfosFormateur[0]['prenom'],
[...]
'ZA4nature1' => 'H ', //strval('H'),
'ZA4montant1' => strval($montant[$InfosFormateur[0]['IdProfil']])
);
$pdf = new FPDM('pdf/das2/form2.pdf');
$pdf->Load($fieldsI, true); // second parameter: true if UTF-8
$pdf->Merge();
I don't know where i can upload the result.
I have an other problem by the way, when I want to merge all my pdf filled, i try many solutions. I have one almost working :
public function combine_pdf($outputName,$fileArray)
{
$merged_pdf = "";
foreach($fileArray as $filename){
$merged_pdf .= " ".$filename;
}
exec("pdftk".$merged_pdf." cat output ".$outputName);
header(sprintf('Location: %s', $outputName));
}
But when i open the pdf generated in Adobe Pdf reader, everything is blank again.
I have found the solution. It's working !
You need pdftk on your server :
public function combine_pdf($outputName,$fileArray, $rep = "download/DAS/")
{
$merged_pdf = "";
foreach($fileArray as $filename){
$merged_pdf .= " ".$filename;
}
exec("pdftk".$merged_pdf." cat output ".$rep."tmpfinal.pdf "); //merge all my filled pdf to 1 pdf
exec("pdftk ".$rep."tmpfinal.pdf generate_fdf output ".$rep."final.fdf"); //generate a clean fdf from this pdf
exec("pdftk ".$rep."tmpfinal.pdf fill_form ".$rep."final.fdf output ".$outputName); // then use the pdf as template filled by the fdf.
header(sprintf('Location: %s', $outputName));
}
I hope it will help someone

Image from database into PDF using FPDF

I have an image that is sent from an iPad app to an SQL database. I can retrieve this image and display in a web page using the following php:
$img = base64_encode($row['photoData']);
echo "<img src=\"data:image/jpg;charset=utf8;base64, $img\"/>";
This displays fine. What I want to do now is put this image into a PDF document using FPDF however I am struggling to do this.
This:
$img = base64_encode($row['photoData']);
$pdf->Image($img);
give this error:
FPDF error: Image file has no extension and no type was specified:
So I tried this (although I realise I will then have to look at how to get the size of the image sorted):
$pdf->Image($img, 20, 20, 20, 20 'JPG');
which give me:
FPDF error: Missing or incorrect image file:
What is the correct way to do this?
Or would it be easier to temporarily save the image to the server and then place the saved image into the PDFdoc?
As mentioned in the comments above this is possible by using a stream ("data url") to hand over the image data to the fpdf library without writing physical files to disk:
<?php
// load the 'fpdf' extension
require('fpdf.php');
// just for demonstration purpose, the OP gets the content from a database instead
$h_img = fopen('img.jpg', "rb");
$img = fread($h_img, filesize('img.jpg'));
fclose($h_img);
// prepare a base64 encoded "data url"
$pic = 'data://text/plain;base64,' . base64_encode($img);
// extract dimensions from image
$info = getimagesize($pic);
// create a simple pdf document to prove this is very well possible:
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello Image!');
$pdf->Image($pic, 10, 30, $info[0], $info[1], 'jpg');
$pdf->Output();
If this is a good advice is another question, this is merely meant to prove that this is possible...
According to the Docs FPDF::Image accepts a filename as the first argument, not a binary blob.
If you want to use FPDF specifically, save the image to a temporary file first, and then pass that to FPDF::Image.
To do that, something like this should work:
$tmpFile = tempnam(sys_get_temp_dir(), 'fpdfimg');
if (file_put_contents($tmpFile, $row['photoData'])) {
$fpdf->Image($tmpFile);
// save/display image
unlink($tmpFile);
}
Alternatively, if you want to just serve the image as a PDF (with no other content) you could use Imagick:
$im = new \Imagick();
$im->readImageBlob($row['photoData']);
$im->setImageFormat('pdf');
header('Content-Type: application/pdf');
echo $im;
Since FPDF cannot use base64 data to produce images on the PDF, I would recommend saving the file to the disk permanently as opposed to writing a temp file for every PDF operation.
This will save you a lot of I/O overhead.
Assuming your table has unique photo_id or photo_name to accompany photoData then you can use something like this to create your images and use them in FPDF.
I will also assume you have a last_update and photo_extension column.
<?php
$path = '/path/to/fpdf/images/';
$filename = $row['photo_id'].'.'.$row['photo_extension'];
$filepath = $path.$filename;
// If a physical file is not available then create it
// If the DB data is fresher than the file then make a new file
if(!is_file($filepath) || strtotime($row['last_update']) > filemtime($filepath))
{
$result = file_put_contents($filepath, $row['photoData']);
if($result === FALSE)
{
die(__FILE__.'<br>Error - Line #'.__LINE__.': Could not create '.$filepath);
}
}
$pdf->Image($filepath);
If you plan on updating the photoData which is stored in your DB then you will have to make sure to also have a timestamp column and compare that timestamp against the filemtime($filepath) of the image on your disk.
Another solution for this ;)
Make a new php by copying and pasting this (piece of fpdf's code edited):
require('fpdf.php');
class DATAIMAGE extends FPDF
{
protected function _parsedata($file)
{
// Extract info from a JPEG file
$a = getimagesizefromstring($file);
if(!$a)
$this->Error('Missing or incorrect image file: '.$file);
if($a[2]!=2)
$this->Error('Not a JPEG file: '.$file);
if(!isset($a['channels']) || $a['channels']==3)
$colspace = 'DeviceRGB';
elseif($a['channels']==4)
$colspace = 'DeviceCMYK';
else
$colspace = 'DeviceGray';
$bpc = isset($a['bits']) ? $a['bits'] : 8;
return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$file);
}
}
Then call this php instead of fpdf.php in your main php.
You'll now be able to display an image simply by adding 'data' to the end of the function:
$pdf->Image($mysqlrow["blob"],0,0,40,0,'data');

XMLWriter using with loop in php

i want to create multiple XML file by using php. i used following code which is working fine for single XML file generation but when i try to same code in loop for generation multiple XML file with different name its throw an error but file is save in destination driver can anyone help me to solve this issue
$fileName = date('YmdHis').rand('0000','999999')."output.xml";
working fine for single calling
xmlGenerater($pimcoArr ,$fileName);
error throw when i call it in loop
for($=0;$i<2;$i++){
xmlGenerater($pimcoArr ,$fileName);
}
error message screen
XML file genartion method
function xmlGenerater($data ,$fileName){
if(!empty($data)){
$writer = new XMLWriter();
//lets store our XML into the memory so we can output it later
$writer->openMemory();
//lets also set the indent so its a very clean and formatted XML
$writer->setIndent(true);
//now we need to define our Indent string,which is basically how many blank spaces we want to have for the indent
$writer->setIndentString(" ");
//Lets start our document,setting the version of the XML and also the encoding we gonna use
//XMLWriter->startDocument($string version, $string encoding);
$writer->startDocument("1.0", "UTF-8");
//lets start our main element,lets call it “ersvpresponse”
$writer->startElement('ersvpresponse');
$loop = 1;
foreach($data as $dataRow){
$pimco_id = $dataRow['pimco_id'];
$event_id = $dataRow['event_id'];
$contact_id = $dataRow['contact_id'];
$status = $dataRow['status'];
$writer->startElement("contact");
if($loop==1){
$dateTime = date('Y-m-d');
$writer->writeAttribute("updated",$dateTime);
}
//now we create pimcoeventid node
$writer->startElement("pimcoeventid");
$writer->text("$pimco_id");
$writer->endElement();
//now we create pimcocontactid node
$writer->startElement("pimcocontactid");
$writer->text("$contact_id");
$writer->endElement();
//now we create pimcocontactid node
$writer->startElement("ersvpstatus");
$writer->text("$status");
$writer->endElement();
$writer->endElement();
$loop++;
}
//Now lets close our main element
$writer->endElement();
//close our document
$writer->endDocument();
/*Lets output what we have so far,first we need to set a header so we can display the XML in the
browser,otherwise you will need to look at the source output. */
header('Content-type: text/xml');
//lets then echo our XML;
//echo $writer->outputMemory();
/* that is enough to display our dynamic XML in the browser,now if you wanna create a XML file we need to do this */
$filename = "exportFiles/$fileName";
//lets output the memory to our file variable,and we gonna put that variable inside the file we gonna create
$file = $writer->outputMemory();
//lets create our file
file_put_contents($filename,$file);
}
}
You are putting the documents in separate files on the server but you send them to the client as one single repsonse document, hence the
Line Number 14
<?xml ...
and that doesn't work, you can't just concatenate xml documents and expect the client-side parser to accept that.
But you could e.g. zip those files and send the archive.

PHPexcel: Image extraction

I have an excel document with multiple records which contains both the text content and images.
I have to save the images according to the record basis. A record has either an image or multiple images or no image. So If I retrieve an image means then I have to name it.
Therefore, I need to find the image's cell name. So that I can easily name it and save it.
But I have no solution to do this. Can we retrieve the cell information using
$worksheet->getDrawingCollection()
Please suggest me how to do this.
$objPHPExcel = PHPExcel_IOFactory::load("MyExcelFile.xls");
foreach ($objPHPExcel->getSheetByName("My Sheet")->getDrawingCollection() as $drawing) {
if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {
ob_start();
call_user_func(
$drawing->getRenderingFunction(),
$drawing->getImageResource()
);
$imageContents = ob_get_contents();
ob_end_clean();
$cellID = $drawing->getCoordinates();
// .... do your save here
}
}

Categories