I am currently working on a CSV generator in Zend Framwork. At this point I am able to create a valid CSV file on the server side and now I want to download that file. I am currently using the following code:
$reader = new \PHPExcel_Reader_CSV();
$reader->setReadDataOnly(true);
$excel = $reader->load($file); //$file = Path of the csv file in the local storage
$writer = \PHPExcel_IOFactory::createWriter($excel, 'CSV');
$path = 'public/download';
$fileName = 'test.csv';
$writer->save($path . '/' . $fileName);
$response = new ResponseStream();
$response->setStream(fopen($path . '/' . $fileName, 'r'));
$headers = new Headers();
$headers->addHeaders([
'Content-Type' => [
'application/force-download',
'application/octet-stream',
'application/download'
],
'Content-Length' => filesize($path . '/' . $fileName),
'Content-Disposition' => 'attachment;filename=' . $fileName,
'Cache-Control' => 'must-revalidate',
'Pragma' => 'no-cache',
'Expires' => 'Thu, 1 Jan 1970 00:00:00 GMT'
]);
$response->setHeaders($headers);
$cookie = new SetCookie('downloadComplete', 'true', time() + 60 * 60, '/');
$response->getHeaders()->addHeader($cookie);
$response->setContent($writer);
return $response;
The problem is now that I only get a Zend error popup:
statusCode 200 thrownError SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 21 of the JSON data
And the content of my CSV as response text.
Do you have an idea?
Thanks in advance.
After a lot of investigation I found out that the download only fails if we send a Post request to the download action via zend (I assume it overrides the self-setted headers). So I sendt the request via a java script redirect ($viewModel->addScriptBlock('window.location = "Your URL";');) and it worked.
Related
Hello i have some problem with doing a force download.
Here is my code :
public function download(Request $request, $id) {
$document = Document::find($id);
$s3 = Storage::disk('s3');
$name = substr($document->link, strrpos($document->link, '/') + 1);
$file = $s3->get($name);
$headers = [
'Content-Type' => 'application/pdf',
'Content-Description' => 'File Transfer',
'Content-Disposition' => "attachment; filename={$name}",
'filename'=> $name
];
return response()->download($file);
}
i don't get it how to access the good file
response :
is_file() expects parameter 1 to be a valid path, string given
Any ideas ?
Your headers are not actually attached to the response. If you refer to: https://laravel.com/docs/5.5/responses#attaching-headers-to-responses you will see that the proper way to send headers in Laravel is:
return response($file)
->header('Content-Type', 'application/pdf')
->header('Content-Description', 'File Transfer')
->header('Content-Disposition', "attachment; filename={$name}")
->header('Filename', $name)
The $file is alse sent as a paramenter in reponse() instead of as download().
I have a Silex project where I want to generate a PDF of a view of this project.
I installed locally wkhtmltopdf on OSX, and i'm using Snappy.
For example, you're on localhost:8001/test/702254 and the page appears. If you access localhost:8001/test/702254/print then the page will be the PDF of the previous (I want the browser show the PDF to the client, then he can download it).
I have a variable in my routes and if it has the 'print' value I want to display the PDF.
$body = null;
$headers = null;
if ($request->get('print') == 'print') {
$uri = str_replace('/print', '', $_SERVER['REQUEST_URI']);
$this->snappy->setOption('cookie', array('MY-COOKIE' => $_COOKIE['MY-COOKIE']));
//$this->snappy->setTimeout(360);
$body = $this->snappy->getOutput('http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$uri}");
$headers = array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="Export.pdf"'
);
}
else {
$body = $app['twig']->render('views/index.html.twig', $twigParams);
$headers = array('Cache-Control' => 'max-age=300, public');
}
return new Response($body, 200, $headers);
My problem is when I call the URL with '/print', I have the following error :
ProcessTimedOutException in Process.php line 1211:
The process "/usr/local/bin/wkhtmltopdf --lowquality --cookie 'MY-COOKIE' '4vkvcjnt2svf0' 'http://localhost:8001/test/702254' '/var/folders/2h/qwnt4dk97dsg1mhv_63ycbrh0000gp/T/knp_snappy574713575a5e51.78801388.pdf'" exceeded the timeout of 60 seconds.
I hope it is not an 'OSX issue' as I read in some topics...
So i'm using Laravel for a while. I wrote this:
public function downloadUserFile(){
$result = $_POST['filename'];
$entry = File::where('filename', '=', $result)->firstOrFail();
$file = Storage::disk()->get(storage_path($entry->filePath));
$headers = array('Content-Disposition' => 'attachment; filename="'.basename($entry->filePath).'"', 'Content-Type' => $entry->mimetype );
return (new Response($file, 200))->header($headers);
}
With the hope that I can download a selected file. Well I get two exceptions in FilesystemAdapter.php line 58 and in Filesystem.php line 381: File not found at path: C:\xampp\htdocs\bluedrive\drive\storage\uploads\1\SHTURCITE - Ti I Az.mp3 ---- This file is in the directory and i can't understand why laravel can't find it.
I have searched for creating pdf file in symfony 2.3 but was not successful. I've got 2 bundle
Knp snapy bundle and another is
psliwa / PHPPdf
My task is just download pdf file on click. For this I have given the link in html.twig like
Download file
In pdf action I am generating the PDF file
In knp snapy bundle I am doing:
$html = $this->renderView('MyBundle:Foo:bar.html.twig', array(
'some' => $vars
));
return new Response(
$this->get('knp_snappy.pdf')->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="file.pdf"'
)
);
And got error
The exit status code '1' says something went wrong: stderr: "The
system cannot find the path specified.
Is wkpdftohtml necessary for installation if YES then how can I install on sharing based hosting.
In psliwa / PHPdf I have read the example from:
psliwa/PdfBundle
psliwa/PHPPdf
and got
unable to find twig file
If I change the $format = $this->get('request')->get('_format'); to $format='pdf'; then it show simple html file.
Unable to understand what should I do for completion of task...
Yes. For Knp Snappy Bundle, wkhtmltopdf is required and you need to configure it properly in the config.yml
knp_snappy:
pdf:
enabled: true
binary: /usr/local/bin/wkhtmltopdf #path to wkhtmltopdf binary
options: []
This is an excerpt from a controller in a live shared host environment using psliwa/PHPPdf:
$facade = $this->get('ps_pdf.facade');
$response = new Response();
$this->render('ManaClientBundle:Contact:roster.html.twig', array(
'date' => $found['latestDate'],
'center' => $location,
'roster' => $found['contactSet'],
), $response);
$date = new \DateTime($found['latestDate']);
$filename = str_replace(' ', '', $location) . date_format($date, '_Ymd') . '.pdf';
$xml = $response->getContent();
$stylesheet = $this->renderView('ManaClientBundle:Contact:contact.xml.twig', array());
$content = $facade->render($xml, $stylesheet);
return new Response($content, 200, array
('content-type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename=' . $filename
));
I'm a little sure as to how to launch a download of a file from Amazon S3 with Laravel 4. I'm using the AWS
$result = $s3->getObject(array(
'Bucket' => $bucket,
'Key' => 'data.txt',
));
// temp file
$file = tempnam('../uploads', 'download_');
file_put_contents($file, $result['Body']);
$response = Response::download($file, 'test-file.txt');
//unlink($file);
return $response;
The above works, but I'm stuck with saving the file locally. How can I use the result from S3 correctly with Response::download()?
Thanks!
EDIT: I've found I can use $s3->getObjectUrl($bucket, $file, $expiration) to generate an access URL. This could work, but it still doesn't solve the problem above completely.
EDIT2:
$result = $s3->getObject(array(
'Bucket' => $bucket,
'Key' => 'data.txt',
));
header('Content-type: ' . $result['ContentType']);
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-length:' . $result['ContentLength']);
echo $result['Body'];
Still don't think it's ideal, though?
The S3Client::getObject() method allows you to specify headers that S3 should use when it sends the response. The getObjectUrl() method uses the GetObject operation to generate the URL, and can accept any valid GetObject parameters in its last argument. You should be able to do a direct S3-to-user download with your desired headers using a pre-signed URL by doing something like this:
$downloadUrl = $s3->getObjectUrl($bucket, 'data.txt', '+5 minutes', array(
'ResponseContentDisposition' => 'attachment; filename="' . $fileName . '"',
));
If you want to stream an S3 object from your server, then you should check out the Streaming Amazon S3 Objects From a Web Server article on the AWS Developer Guide
This question is not answered fully. Initially it was asked to how to save a file locally on the server itself from S3 to make use of it.
So, you can use the SaveAs option with getObject method. You can also specify the version id if you are using versioning on your bucket and want to make use of it.
$result = $this->client->getObject(array(
'Bucket'=> $bucket_name,
'Key' => $file_name,
'SaveAs' => $to_file,
'VersionId' => $version_id));
The answer is somewhat outdated with the new SDK. The following works with v3 SDK.
$client->registerStreamWrapper();
$result = $client->headObject([
'Bucket' => $bucket,
'Key' => $key
]);
$headers = $result->toArray();
header('Content-Type: ' . $headers['ContentType']);
header('Content-Disposition: attachment');
// Stop output buffering
if (ob_get_level()) {
ob_end_flush();
}
flush();
// stream the output
readfile("s3://{$bucket}/{$key}");