Snappy Error: The system cannot find the path specified - php

Please I am trying to use snappy for the first time to allow the user download PDF from my site. I previously used DomPDF but found it not suitable for the current situation. I first installed wkhtmltopdf, then I installed snappy using composer which installed it to c/users/computer-name/vendor (I am very new to composer). I copied the vendor folder to my project directory.
I added the code below;
require __DIR__ . '/vendor/autoload.php';
use Knp\Snappy\Pdf;
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="file.pdf"');
echo $snappy->getOutput('http://www.github.com');
as shown here: https://github.com/knplabs/snappy
The PDF downloads but does not open. Chrome says "Failed to load PDF document". When I open the PDF with notepad, I see the error;
Fatal error: Uncaught RuntimeException: The exit status code '1' says something went wrong:
stderr: "The system cannot find the path specified.
"
stdout: ""
command: /usr/local/bin/wkhtmltopdf --lowquality "https://www.google.com/" "C:\Users\CHIDIE~1\AppData\Local\Temp\knp_snappy5e42659b757116.59025588.pdf". in C:\xampp\htdocs\corporatecareer\templates\vendor\knplabs\knp-snappy\src\Knp\Snappy\AbstractGenerator.php:381
Please help. What are my missing. I know I am doing something wrong.
Thanks.

/usr/local/bin/wkhtmltopdf in snappy example is a linux binary location. Seems like you are using windows xampp. Download the wkhtmltopdf program from here https://wkhtmltopdf.org/downloads.html and update you path where you extracted the binary like so.
$snappy = new Pdf('C:\path to where you extracted binary');
Also, make sure that the extracted path doesn't required admin privileges to execute.

Related

Archive format is not recognised. ZipArchive in PHP not returning a valid format

Thanks in advance for your help
This is happening in a Ubuntu 20.10 machine and a server with apache and php 5.2
Let me paste the code:
$elementsToDownload = array(
'productTableCSV' => $productTableCSVString,
'productTableLangCSV' => $productTableLangCSVString,
'productTableShopCSV' => $productTableShopCSVString
);
// var_dump($elementsToDownload);
$zipname = 'productCSVs.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($elementsToDownload as $key => $csvString) {
if (! $zip->addFromString("$key.csv", $csvString)) {
echo 'Could not add file to ZIP: ' . "$key.csv";
die();
}
}
$zip->close();
ob_clean();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname);
It looks like something should be wrong in here, as I, randomly, can download the zip. From time to time the browser complains about not being able to download the file. Although this is not always happening, this is the message that Firefox display:
/tmp/mozilla_manu0/h03iaHVG.zip.part could not be saved, because the source file could not be read.
Try again later, or contact the server administrator.
This happens in Firefox.
Nor Mate Engrampa Archive Manager neither XArhiver are capable of opening the file. Surprisingly if I run unzip -t productCSVs.zip in the command line, it doesn't report any error. I can also unzip the file without the -t option if I do in the terminal, but no desktop app can open it.
To add some extra information, the PHP version which I'm using to generate the file is quite old, 5.2, but this is what I have until my company updates their systems, which is expected in the future.
Can anybody think of any reason why this could be happening?
EDIT:
I just realised that even though I don't have errors when decompressing the file in the terminal, I have a warning about 1 extra byte at the beginning or within zipfile:
manu#manu-NUC8i7BEH:/tmp/mozilla_manu0$ unzip -t productCSVs.zip
Archive: productCSVs.zip
warning [productCSVs.zip]: 1 extra byte at beginning or within zipfile
(attempting to process anyway)
testing: productTableCSVString.csv OK
testing: productTableLangCSVString.csv OK
testing: productTableShopCSVString.csv OK
testing: productTableCSV.csv OK
testing: productTableLangCSV.csv OK
testing: productTableShopCSV.csv OK
No errors detected in compressed data of productCSVs.zip.
I still can't understand what's going on in here
Ok, so I solved the issue.
My problem was that I had opened and closed two times the php tags in my code, leaving a space in between. Something like this:
?>
<?php
As a result that space was being added to the download stream.
I removed the closing tag and the opening tag, as they were together, and now every file I download from the server is recognised by all my zip tools
Thank you for having read me!

PHP - Converting Excel to PDF (Phpspreadsheet) - Operation not permitted

I am trying to convert an Excel file to PDF (Base64).
This is the code that converts the Excel to PDF:
$spreadsheet = $this->objPHPExcel = \PhpOffice\PhpSpreadsheet\IOFactory::load("MyExcelFile.xlsx");
$class = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', $class);
$this->objPHPExcel = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
$this->objPHPExcel->writeAllSheets();
//Save the file. (THIS IS WHERE THE ERROR OCCUR)
$this->objPHPExcel->save(storage_path() . '/app/temp_files/' . $newFileName);
Everything works locally, but whenever I try to run the same code on my Laravel Forge server, I get below error:
unlink(/tmp/imagick-3.4.0.tgz): Operation not permitted
If I trace the error, it is in this specific line:
$this->objPHPExcel->save(storage_path() . '/app/temp_files/' . $newFileName);
As said, this code runs fine locally. The temp file $newFileName is created inside my /temp_files folder.
What am I doing wrong?
Ok so the solution to this was rather tricky. I found out that it had nothing to do with Phpspreadsheet but rather Mpdf.
The problem was that the file "imagick-3.4.0.tgz" file permission was set to read only. Mening that unlink could not work on this specific file. This goes all the way back to when I first installed the imagick library.
The solution was to go to the /tmp folder and delete the imagick-3.4.0.tgz file manually. This folder should actually be deleted when doing the imagick installation.

PDFTK want to transfer to another domain

I am working on a project which was developed by another developer
Now client wants me to move it from current linux based server to new windows based server
it is developed in cakephp
and PDFTK is used to fill pdf files dynamically.
I am trying to configure it first on my PC locally, to learn configuration of PDFTK
I have downloaded PDFTK Free version and installed
it generates pdfile with zero bytes size and it is not opeining
I also tried to try in in CMD
pdftk D:\wamp\www\my-project\app\webroot/files/138.pdf fill_form D:\wamp\www\my-project\app\webroot/files/results/1401.fdf output generated_pdfs/test_24.pdf
it returns the following error
Error: Failed to open output file:
generated_pdfs/test_24.pdf
No output created.
Error: unable to open file for output: generated_pdfs/test_24.pdf
while the target folder has permission to write on it
pdftk TEMPLATE_FILE fill_form DATA_FILE output OUTPUT_FILE
try using OUTPUT_FILE with fullpath as below
OUTPUT_FILE = D:/folder/.../generated_pdfs/test_24.pdf

PHP: wkhtmltopdf snappy (wrapper) fails

i have a problem using wkhtmltopdf with snappy.
I has installed wkhtmltopdf with homebrew on mac osx.
I use this code to display PDF in Browser:
<?php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="file.pdf"');
require_once('snappy/autoload.php');
use Knp\Snappy\Pdf;
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
echo $snappy->getOutput('http://www.github.com');
?>
Instead of displaying the PDF in the browser, the script opens the terminal. After i click on the terminal it starts downloading the file.pdf. The file.pdf shows the correct github page.
What i am doing wrong?
And whats the best solution to manage wkhtmltopdf's binary path that the script is working on several systems (debian, windows, ..).
EDIT:
Oh sorry.. i changed attachment to inline and the browser displays the PDF.
But i must click on the terminal first..

wkhtmltopdf: download a PDF to the user's HD

how to download automaticaly (to the user's HD) a pdf generated using wkhtmltopdf or snappy? You know.. a user click a link ("Download this page as PDF") and download the pdf to his/her HD.
Regards
Javi
PHP: there are better ways of getting wkhtmltopdf working with PHP, however, I like to be able to print out what my command line is so that I can debug the resulting page that bit more easily. It is not just about code, but about having margins and other page details correct. Here the wkhtmltopdf is a binary in the web root, margins are set to zero, the background is turned off:
$do_it=$_SERVER["DOCUMENT_ROOT"]."/wkhtmltopdf --dpi 600 -B 0 -L 0 -R 0 -T 0 --no-background http://".$_SERVER['SERVER_NAME']."/".$filename." ".$_SERVER["DOCUMENT_ROOT"]."/".$pdf_url;
//var_dump($do_it); // uncomment to see your wkhtmltopdf parameters...
$whatever=passthru($do_it);
header('Content-disposition: attachment; filename='.$pdf_url);
header('Content-type: application/pdf');
readfile($pdf_url);
I don't think much comes back when running passthru when it comes to error messages, however, it does run whatever you send it.
As for header, it is important to set the content type to PDF or else the browser will not know what to do with it.
The Snappy website actually also has a ready made example just for this.
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="file.pdf"');
echo $snappy->getOutput('http://www.github.com');
Here's how I do it in RoR
filename = "MyNew.pdf"
fullpath = "#{RAILS_ROOT}/tmp/charts/#{filename}"
# system issues a shell command
system "/usr/local/bin/wkhtmltopdf \"http://localhost/page/to/pdf?download=t\" #{fullpath}"
send_data(File.read(fullpath), :type => 'application/pdf', :filename => filename, :disposition => "attachment;filename=\"#{filename}\"")

Categories