Hi I always got error when trying to create docx file and I want to download it directly. My browser is stuck on ERR_INVALID_RESPONSE. I'm using CodeIgniter framework by the way. Here is the code.
<?php
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\Word2007;
class Test extends MY_Controller{
public function create()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addText('Hello World!');
$file = 'HelloWorld.docx';
header("Content-Description: File Transfer");
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$xmlWriter->save("php://output");
}
}
This code is just taken from the example in the PhpWord docs, but somehow it doesn't work. No error just ERR_INVALID_RESPONSE on the browser. What did I miss?
After a couple hours digging, I finally found the solution for my problem. The problem exists because it relates to temporary folder. So what I have to do is 1. setting the path where the file temporarily saved and 2. I have to tell Phpword that it should use that path to store generated file.
$path = './uploads/tmp'; // Set the temporary path
\PhpOffice\PhpWord\Settings::setTempDir($path); // Tell Phpword where the temporary path is
So this is the complete code
<?php
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\Word2007;
class Test extends MY_Controller{
public function create()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addText('Hello World!');
$path = './uploads/tmp'; // Set the temporary path
\PhpOffice\PhpWord\Settings::setTempDir($path); // Tell Phpword where the temporary path is
$file = 'HelloWorld.docx';
header("Content-Description: File Transfer");
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$xmlWriter->save("php://output");
}
}
Hope it can help those who get the same problem
Related
i got this code in attaching a pdf file to my site in order for the viewers to download such pdf file..
$fullPath = "../public/pdffiles/FolioPlusUserGuide(v3.0).pdf";
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
html code:
baseUrl().'/DownloadPdf'?>">DOWNLOAD BROCHURE
this code only accommodates 1 file path, I have more pdf files with different filename and different buttons for each to handle the download event. how can i achieve this?..thanks ahead!..=)
You can pass PDF file name via HTTP request, like this:
DownloadPDF.php?filename=test1.pdf
Then in your DownloadPDF file have something like this:
$pdfdir = "/pdffiles/folder/location/here";
$pdffilename = $_GET['filename'];
$fullPath = $pdfdir.$pdffilename;
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
Now your code is dynamic and you can download any PDF with links like this:
<a href=downloadpdf.php?filename=something.pdf>Something</a>
<a href=downloadpdf.php?filename=something2.pdf>Something2</a>
etc.
I am using zend frame works . I want to include file download section in my application. I am using this code
> header('Content-Type: application/doc'); header('Pragma: no-cache');
> header('Content-Disposition: attachment; filename="'.$resume.'"');
> readfile(RESUME_PATH_WS . $resume);
But this code is not working .It return file with 0byte . Please help me how to i download files in zend frame work
public function downloadAction() {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$filename = $this->_request->getParam('filename');
$filePath = folder/path to file/ . $filename;
if (file_exists($filePath)) {
$fileName = basename($filePath);
$fileSize = filesize($filePath);
header("Cache-Control: private");
header("Content-Type: application/stream");
header("Content-Length: " . $fileSize);
header("Content-Disposition: attachment; filename=" . $fileName);
readfile($filePath);
exit();
} else {
die('The provided file path is not valid.');
}
}
Simply in your html side
Download
Lots of questions here from people trying to implement gzip encoding in Zend - I need to do the opposite!
I have a controller which extends the standard Zend_Controller_Action. My downloadAction has a PDF file as it's response body. That works well, except that the downloaded file isn't correctly recognised by the client browsers.
The downloaded file is identified as a 'Zip Archive' by the browser download. When saved and double-clicked it opens correctly as a PDF. The response header shows Content-Encoding:gzip, so I figure that's likely the culprit.
The core of my action is:
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
if ($fd = fopen($pdfpath.$pdf->Filename,'r'))
{
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="summary.PDF"');
while(!feof($fd))
{
$buffer = fread($fd, 2048);
echo $buffer;
}
fclose($fd);
}
There is some other code before this piece, but it does nothing more exciting than populate the variables.
How would I go about disabling the Content-Encoding:gzip header for just this response, or if that's the wrong end of the stick (it would be good to use compression, but not at the expense of user experience), how do I get the client to correctly identify the downloaded file once the compression has been reversed?
I would recommend to use framework's Zend_Controller_Response_Http instead of header() function, usually I specify "default" headers with gzip compression etc. in my Bootstrap for all responses, and override them in actions for some special reasons:
public function indexAction()
{
$frontContoller = $this->getFrontController();
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$response = new Zend_Controller_Response_Http();
$response
->setHeader('Content-Type', 'application/pdf')
->setHeader('Content-Disposition', 'attachment; filename=summary.pdf')
->setHeader('Expires', ''.gmdate('D, d M Y H:i:s', strtotime('31.08.1986')) . ' GMT', true)
->setHeader('Cache-Control', 'no-cache')
->setHeader('Pragma', 'no-cache', true);
$response->setBody(file_get_contents('/full/path/to/summary.pdf'));
$frontContoller->setResponse($response);
}
am generating pdf using Zend_pdf
its saving after creating
I want to open it instead of saving.
When i access the url directly
Use render() method
// Set PDF headers
header ('Content-Type:', 'application/pdf');
header ('Content-Disposition:', 'inline;');
// Output pdf
echo $pdf->render();
I couldn't find a way to open a PDF directly, so I did this instead:
<?php
// Save PDF into file
$oPdf->save("./pdfcache/filename.pdf");
// Set headers
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename=filename.pdf');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
ini_set('zlib.output_compression','0');
// Get File Contents and echo to output
echo file_get_contents("./pdfcache/filename.pdf");
// Prevent anything else from being outputted
die();
It's not perfect, but it does the job for me.
Is there a Zend Framework method to save content from 3 files (be they dynamically generated or actually exist) and force download as a file?
Similar to this question (which didn't work for me when running from inside a controller so far, despite trying a few different ways):
PHP Zip 3 small text files and force download
You can use the PHP ZIP library (you need to have that preinstalled) like that:
$zip = new ZipArchive();
if($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true){
throw new Exception('Could not create zip file ' . $filename);
die('zip fail');
}else{
$zip->addFile($file1Uri, 'file1.txt');
$zip->addFile($file2Uri, 'file2.txt');
}
$zip->close();
if(file_exists($filename)){
return true;
}else{
throw new Exception('Could not create zip file ' . $filename);
}
Deliver the ZIP file:
protected function _deliver($file, $name, $extension, $size, $mime){
header('Pragma: private');
header("Expires: -1");
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header("Cache-Control: no-cache");
header("Content-Transfer-Encoding: binary");
header("Content-Type: " . $mime);
header("Content-Description: File Transfer");
header('Content-Disposition: attachment; filename="' . $name . '.' . $extension . '"');
header("Content-Length: " . $size);
set_time_limit(0);
if(!readfile($file)){
return false;
}
}
The answer is the upvoted one on your other question. Do it from controller, then call exit after you output the zip data so don't you render the view.