CSamp CSamp - 1 month ago 5
PHP Question

Downloading a docx file in CakePHP

I am trying to make a download action that downloads a Word doc generated in the 'download' controller using PHPDOCX. So far PHPDOCX is able to save the desired .docx file in the correct folder, but something goes wrong when I try to download it. Since Media Views were deprecated, I must use the CakeResponse file method as suggested in the CakePHP 2.x Cookbook:

// In the controller:
$this->response->file($file['path'], array('download' => true, 'name' => $filename));
return $this->response;

I was able to use this method for to export an RTF with no problem (the RTF was generated using PHPRTFLite), but when I use the method for a .docx file using PHPDOCX I receive the following error in Firefox:

The character encoding declaration of the HTML document was not found
when prescanning the first 1024 bytes of the file. When viewed in a
differently-configured browser, this page will reload automatically.
The encoding declaration needs to be moved to be within the first 1024
bytes of the file.

I would like to use a document generator that accepts HTML, which is why I chose PHPDOCX. Considering the above error, I set off to define the headers and content-type using the following method:


But I still receive the same error in CakePHP:

The requested file APP/files/info_sheets/filename.docx was not found or not readable

One thing I was thinking is that PHPDOCX sends many errors when it generates the document and this is interfering with the Mime-type or encoding. But according to the 2.x Cookbook:

Headers are not sent when
is called either.
They are just buffered until the response is actually sent.

Another idea is that I need to set the character encoding in the header right after the content-type:


But this results in garbled text.

Does anyone have any ideas how to resolve this? The "download.ctp" view file is currently blank. Please let me know if you need additional information about this issue.




First of all, you might try to disable autoRender, otherwise CakePHP might still try to render your view and layout;

$this->autoRender = false;

Also, haven't tested it, but have you tried this to set the header:

// register the type 
$this->response->type(array('docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'));
// set the type for the response

See the documentation: http://book.cakephp.org/2.0/en/controllers/request-response.html#dealing-with-content-types