Fill Pdf form using php laravel - php

I'm trying to fill a pdf and save it using php. I'm also tried FPDF this script but its throws a error FPDF-Merge Error: Object streams are not supported. After I'm also tried php-pdftk package. I'm using ubuntu 20.04 so there no instruction to found install pdftk server for Ubuntu on there website. I'm install it using method 3 of this web site given Pdftk ubuntu install bleow is my code after configure pdftk
$pdf = new Pdf(public_path().'/test.pdf');
$result = $pdf->fillForm([
'name_field'=>'hello',
])
->flatten()
->saveAs(public_path().'/filled.pdf');
// Always check for errors
$error ='';
if ($result === false) {
$error = $pdf->getError();
}
return response()->json($error, 200);
this result always return false and error message is empty.
Can any one help me to figure this out if I'm done anything wrong or Is there any better solution for fill PDF form?
Thank you.

Change ->flatten() to needAppearances().
Note: When filling in UTF-8 data, you should always add the needAppearances() option. This will make sure, that the PDF reader takes care of using the right fonts for rendering, something that pdftk can't do for you. Also note that flatten() doesn't really work well if you have special characters in your data.
https://github.com/mikehaertl/php-pdftk

Related

PDF: An image could not be created from the given input

I am using Spatie\PdfToImage in my Symfony application to change PDFs into images. Here is the function I am using:
public function savePdfPreviewImage($fullFilePath, $thumbnailPath)
{
$pdf = new Pdf($fullFilePath);
$pdf->saveImage($thumbnailPath);
return $this;
}
When given a path to a PDF, the library returns this message:
An image could not be created from the given input
How can I go about finding a solution to this?
So far I have tried verifying with an ls that the file exists in the place where the app thinks it is. I have also tried opening the file -- which has a .pdf file extension -- in a PDF reader to verify that it is not corrupt. Neither of those two actions yielded any clues.
=====
Edit 1: I traced this message back to the Imagine.php file, where I removed an error-suppression line. That gave me this slightly less opaque message:
Warning: imagecreatefromstring(): Data is not in a recognized format
====
Edit 2: I have also verified that ghostscript is installed. The gs command is available from my server environment. I have also verified that the path provided for $thumbnailPath is a valid path/filename ending in .jpg.
I figured out what the problem was.
The conversion to PDF was actually behaving just fine. What was misbehaving was a later call within the application to the Imagine.php library, unsuccessfully resizing the image that my code successfully created. Here is the code that allowed me to see this:
public function savePdfPreviewImage($fullFilePath, $thumbnailPath)
{
//$pdf = new Pdf($fullFilePath);
//$pdf->saveImage($thumbnailPath); //This gives us "An image could not be created from the given input" and "Data is not in a recognized format"
//Let's try it with a manual call to GhostScript instead ...
exec(
'gs -o ' . //This creates the image successfully, but the error still shows up.
$thumbnailPath . //That means the error isn't coming from here, since we're no longer calling any external PHP libraries.
' -sDEVICE=jpeg ' .
$fullFilePath
);
return $this;
}
You do not need a lib for this, imagick alone will do fine.
$pdf = new \Imagick();
$pdf->setColorspace(\Imagick::COLORSPACE_SRGB);
$pdf->readImage($srcPath);
$pdf->setIteratorIndex($pageNo);
$pdf->writeImage($outPath);
(Imagick will recognize the file extension from $outPath)

Laravel 5: Output tFPDF

I want to use tFPDF in Laravel 5.5. I added the package with composer and then I tried to output it the according to the docs but nothing worked.
I tried to output it directly to the browser:
Route::get('/test',function(){
$pdfLibrary = new tFPDF\PDF();
$pdfLibrary->AddPage();
$pdfLibrary->AddFont('DejaVuSansCondensed', '', 'DejaVuSansCondensed.ttf', true);
$pdfLibrary->SetFont('DejaVuSansCondensed', '', 14);
$pdfLibrary->Write(8, 'Hallo!');
$pdfLibrary->output();
});
but the sceen was just blank. When I tried return $pdfLibrary->output();
then it just returned
%PDF-1.3 3 0 obj <> endobj 4 0 obj <> stream x�u�� �#S�)>+�p�.......
I also tried to simply save the pdf to a file, but even
$pdfLibrary->output('F', storage_path() . '/test.pdf');
did not work.
How can I save & output the pdfs created by tFPDF ?
I found another package from SetASign which is just want I wanted. Simple tFPDF packge with namespace support. This works out of the box and is amazing.
I would strongly recommend to use the SetASing package over the DocNetUk package, because the DocNetUK package has just to many quirks. Here are some of the issues that I had using the DocNetUK package:
Output returns raw binarys, see below how to work with it
Renaming font names does not work.
method tFPDF was changed to __construct, so you have to call parent::construct in your constructor each time, which was necessary because of the namespacing(see What's difference between __construct and function with same name as class has?)
The variable names have been changed randomly and there are no docs for it:
$this->w =>$this->flt_current_width
$this->h =>$this->flt_current_height
These changes make the version from DocNetUK incompatible with basically all add-ons.
*Outdated answer
I finally realized that the unofficial composer version of tFPDF changed slightly the behavior of the output function. The output functions just returns the pdf content, but cannot save it to a file nor render it directly in the browser.
This is how to display raw binarys as a pdf in Laravel
\Response::make($this->output(), 200, ['content-type'=>'application/pdf', 'Content-Disposition' => 'inline; temp.pdf']);
Saving raw binaries goes like this:
Storage::put('file.pdf', $pdfLibrary->output());
or file_put_contents if one is not using Laravel.

Digital signed PDF with PHP [duplicate]

I'm trying to build a simple PDF document signing routine, using PHP, openssl, and the Zend framework (for pdf redering/handling).
I've found this, but it simply won't work, Zend is not able to open any pdf's, not even Zend's own test pdf and Zend will not report why, only that it 'cannot'.
I'm pretty sure I would be able to create the keys/certs effectively as that is well documented, but is there a solid approach to attaching the generated certificate to the PDF as the above Zend extension suggests it once did?
function DigiSignPDF ($pdf_sign_request) {
if (get_magic_quotes_gpc()) {
$new_pdf = stripslashes($pdf_sign_request['raw_pdf']);
} else {
$new_pdf = $pdf_sign_request['raw_pdf'];
}
$test_pdf = stripslashes(file_get_contents('path/Some.pdf'));
$test_pdf2 = ('path/Some.pdf');
$pdf = Zend_Pdf::load($new_pdf2);
//below is the signing code, from another library, it works as long as Zend_Pdf works
$certificate = file_get_contents('path/certificate.p12');
$certificatePassword = 'test123';
if (empty($certificate)) {
throw new Zend_Pdf_Exception('Cannot retrieve/generate the certificate.');
}
$pdf->attachDigitalCertificate($certificate,$certificatePassword);
$eSig_pdf = $pdf->render();
file_put_contents('path/signed_pdf.pdf', $eSig_pdf);
}
Edit, adding code: The above only works if I use 'test_pdf2' as the input for Zend_Pdf. It recognizes the cert as binary with no problems, but I need to be able to pass the PDF without ever writing it to disk.
TCPDF supports signing of pdf files. Maybe you find something useful in the source code.
Adding my solution as answer, per halfer's advice: Solved this one, because I was passing the content to Zend_Pdf as a string, i should have been using Zend_Pdf::parse($new_pdf);, as it very likely says in the manual. (oops)
Further; I solved pretty much ALL of my problems with digitally signing PDFs of various versions and form constituents by moving to TCPDF, as several of the articles here suggest. A similar caveat was met with TCPDF though, when using strings, ensure that you are using TCPDF's 'writeHTMLCell' instead of 'writeHTML'. And watch for PHPs 'magic_quotes', errant whitespace, encoding, and goblins.

With PHP, how can I check if a PDF file has errors

I have a DB system built in PHP/MySql. I'm fairly new at this. The system allows the user to upload an invoice. Others give permission to pay the invoice. The accounting person uploads the check. After check is uploaded, it generates a PDF as a cover, then uses PDFTK (using Ben Squire's PDFTK-PHP-Library) to combine all of the files together and present the user with a single PDF to download.
Some users upload PDF files which cause PDFTK to hang indefinitely when it tries to combine the PDF with others (but most of the time it works fine). No returned error, just hangs. In order to get back onto the sytem, user must clear cache and re-log in. There are no error messages logged by the server, it just freezes. The only difference I can find in the files that do or do not work in looking at them with Acrobat is that the bad files are legal sized (8.5 x 14) ... but if I create my own legal sized file and try that, it works fine.
Using Putty I've gone to command line and replicated the same problem, PDFTK can't read the file, it hangs on the command line as well. I tried using PDFMerge which uses FPDF to combine the files and get an error with the file as well (The error I get back from this is: FPDF error: Unable to find object (4, 0) at expected location). On the command line I was able to use ImageMagick to convert PDF to JPG, but it gives me an error: "Warning: File has an invalid xref entry: 2. Rebuilding xref table." and then it converts it to a jpg but gives a few other less helpful warnings.
If I could get PHP to check the PDF file to determine if is valid without hanging the system, I could use ImageMagick to convert the file and then convert it back to a PDF, but I don't want to do this to all files. How can I get it to check the validity of the file when uploaded to see if it needs to be converted without causing the system to hang?
Here is a link to a file that is causing problems: http://www.cssc-testing.org/accounting/school_9/20130604-a1atransportation-1.pdf
Thanks in advance for any guidance you can offer!
My Code (which I'm guessing is not very clean, as I'm new):
$pdftk = new pdftk();
if($create_cover) { $pdftk->setInputFile(array("filename" => $cover_page['server'])); }
// Load a list of attachments
$sql = "SELECT * FROM actg_attachments WHERE trans_id = {$trans_id}";
$attachments = Attachment::find_by_sql($sql);
foreach($attachments as $attachment) {
// Check if the file exists from the attachments
$attachment->set_variables();
$file = $attachment->abs_path . DS . $attachment->filename;
if(file_exists($file)){
// Use the pdftk tool to attach the documents to this PDF
$pdftk->setInputFile(array("filename" => $file));
}
}
$pdftk->setOutputFile($save_file);
$pdftk->_renderPdf();
the $pdftk class it is calling is from: https://github.com/bensquire/php-pdtfk-toolkit
You could possibly use Ghostscript using exec() to check the file.
The non-accepted answer here may help:
How can you find a problem with a programmatically generated PDF?
I wont say this is an appropriate/best fix, but it may resolve your problem,
In: pdf_parser.php, comment out the line:
$this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
It should be near line 544.
You'll also likely need to replace:
if (!is_array($kids))
$this->error('Cannot find /Kids in current /Page-Dictionary');
with:
if (!is_array($kids)){
// $this->error('Cannot find /Kids in current /Page-Dictionary');
return;
}
in the fpdi_pdf_parser.php file
Hope that helps. It worked for me.

Digitally signing a PDF, using PHP, Zend, and openssl

I'm trying to build a simple PDF document signing routine, using PHP, openssl, and the Zend framework (for pdf redering/handling).
I've found this, but it simply won't work, Zend is not able to open any pdf's, not even Zend's own test pdf and Zend will not report why, only that it 'cannot'.
I'm pretty sure I would be able to create the keys/certs effectively as that is well documented, but is there a solid approach to attaching the generated certificate to the PDF as the above Zend extension suggests it once did?
function DigiSignPDF ($pdf_sign_request) {
if (get_magic_quotes_gpc()) {
$new_pdf = stripslashes($pdf_sign_request['raw_pdf']);
} else {
$new_pdf = $pdf_sign_request['raw_pdf'];
}
$test_pdf = stripslashes(file_get_contents('path/Some.pdf'));
$test_pdf2 = ('path/Some.pdf');
$pdf = Zend_Pdf::load($new_pdf2);
//below is the signing code, from another library, it works as long as Zend_Pdf works
$certificate = file_get_contents('path/certificate.p12');
$certificatePassword = 'test123';
if (empty($certificate)) {
throw new Zend_Pdf_Exception('Cannot retrieve/generate the certificate.');
}
$pdf->attachDigitalCertificate($certificate,$certificatePassword);
$eSig_pdf = $pdf->render();
file_put_contents('path/signed_pdf.pdf', $eSig_pdf);
}
Edit, adding code: The above only works if I use 'test_pdf2' as the input for Zend_Pdf. It recognizes the cert as binary with no problems, but I need to be able to pass the PDF without ever writing it to disk.
TCPDF supports signing of pdf files. Maybe you find something useful in the source code.
Adding my solution as answer, per halfer's advice: Solved this one, because I was passing the content to Zend_Pdf as a string, i should have been using Zend_Pdf::parse($new_pdf);, as it very likely says in the manual. (oops)
Further; I solved pretty much ALL of my problems with digitally signing PDFs of various versions and form constituents by moving to TCPDF, as several of the articles here suggest. A similar caveat was met with TCPDF though, when using strings, ensure that you are using TCPDF's 'writeHTMLCell' instead of 'writeHTML'. And watch for PHPs 'magic_quotes', errant whitespace, encoding, and goblins.

Categories