Force text download in MSWord-supported format with PHP?

4

I would like to know how to force the download of a file, with some extension supported by Microsoft Word p>

I've searched a few times, tested the MIME types I found, like the ones in this Microsoft's list , but I did not succeed.

This code works to force you to download a file with .txt extension , but if you try with .doc , an error will occur when trying to open the word file downloaded.

header('Content-Type: application/octet-stream; charset=utf-8');
header('Content-disposition: attachment; filename="' . uniqid(time()) . '.txt";');
header('Content-Length: '. filesize($filename));
readfile($filename);

Complete example:

<?php

$file = tmpfile();

$content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent a vehicula mi, eu lacinia sem. Donec pellentesque egestas pulvinar. Donec ultricies risus vitae tellus tincidunt sagittis sed a odio. Curabitur vitae egestas metus, sit amet consectetur nisi. In pellentesque, mauris consequat ornare ullamcorper, mi nunc condimentum leo, ac feugiat lectus metus in nulla. Nulla ac vestibulum lacus. Donec sit amet felis pulvinar, vestibulum metus at, mattis lorem. Duis efficitur, velit vitae ullamcorper blandit, erat quam vehicula risus, dignissim volutpat nulla orci quis augue. Donec nisi velit, sagittis sed consectetur vitae, ornare eget turpis. Vivamus tincidunt, ligula sit amet aliquet iaculis, sapien risus rutrum purus, a sollicitudin nunc lacus sit amet purus. Pellentesque lacinia, tortor ut rhoncus molestie, eros nisl venenatis turpis, eget elementum quam ligula eget eros. Phasellus aliquam neque blandit scelerisque mattis. Maecenas purus erat, sodales at tincidunt eu, facilisis non velit. Quisque blandit arcu non dolor efficitur hendrerit.

Morbi ultricies arcu tempor, convallis sem non, faucibus risus. Praesent ut nunc sit amet quam placerat iaculis non at nibh. Maecenas imperdiet aliquam risus, ut sodales justo consequat id. Donec sollicitudin maximus cursus. Sed placerat, mauris a ornare hendrerit, ipsum enim ornare augue, non efficitur magna nulla auctor mi. Praesent sodales sed erat non luctus. Aliquam erat volutpat. Duis eget semper augue. Suspendisse pellentesque condimentum vehicula. Aliquam tempor arcu non leo vehicula, vitae ornare tortor sagittis. Vivamus posuere nibh massa, et dapibus nisl viverra quis. Phasellus tincidunt tellus id vehicula varius. Cras efficitur libero vitae accumsan tincidunt.

Nam molestie enim non nulla imperdiet interdum. Ut eget tortor venenatis, lobortis est a, consequat leo. Quisque consequat pellentesque velit eget vulputate. Integer pharetra felis sed hendrerit tristique. Donec tempus gravida diam, non maximus metus semper ac. Nulla ultrices egestas turpis. Fusce at dui ligula. Nam eget ligula sit amet quam tincidunt mollis. Mauris vitae dapibus lectus. Vestibulum id purus lacus. Proin tincidunt felis ac suscipit tristique.

Maecenas ullamcorper quis risus nec suscipit. Nam sodales tincidunt laoreet. Mauris interdum auctor massa, sit amet blandit nulla ullamcorper hendrerit. Curabitur ante libero, feugiat id iaculis quis, vestibulum ut eros. Morbi eleifend leo vitae mi laoreet eleifend. Ut vel accumsan mi. Cras sit amet bibendum tortor, nec vestibulum risus. Vestibulum suscipit rutrum turpis eu lacinia. Mauris porttitor maximus eros. Nullam augue arcu, sodales et porttitor eget, hendrerit eu odio. Vestibulum suscipit nisi sed commodo posuere. Proin volutpat nunc non neque accumsan posuere. Duis consequat, leo nec dictum sodales, neque leo congue nisl, eget consequat odio dolor eget nunc. Proin accumsan enim nisi.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam egestas hendrerit nisi, tristique pretium velit condimentum vel. Etiam sit amet purus nec risus finibus finibus auctor in metus. Integer nec risus mauris. Fusce aliquet egestas purus sed venenatis. Fusce non finibus sapien. Integer eu augue ligula. Sed urna sapien, hendrerit et pharetra sed, posuere eu elit. Sed a nibh id ipsum scelerisque iaculis. Vestibulum convallis sollicitudin erat ut blandit. Integer scelerisque odio vel nisl ullamcorper, vel feugiat nibh pretium. Sed et lectus vulputate, feugiat lacus vitae, lobortis sem.";

fwrite($file, $content);
fseek($file, 0);

$metadata = stream_get_meta_data($file);
$filename = $metadata["uri"];

header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-disposition: attachment; filename="'. uniqid(time()) . '.docx";');
header('Content-Length: '. filesize($filename));
readfile($filename);
    
asked by anonymous 11.09.2015 / 07:13

2 answers

7

Your problem is not with file extension or with header passed, the problem is that you are trying to force software such as Microsoft Word to read a plain ASCII text file as if it were a .doc .

Files .docx and .docm are zipped files that use Office Open XML , which contain the files (for example) [Content_Types].xml , docProps/core.xml , word/document.xml and the _rels folder that "form" the Word file.

The .doc file is a binary document that follows its own pattern, and there are variations for each version of Word, how it generates such a document, and the extension has also been used by other software and had a different format.

So neither .doc nor .docx are common text files.

  

Note : Programs like Abiword and OpenOffice (as quoted by doc or odt and why this was possible to visualize.

If you want to create a true .docx file with PHP you will need a library. A library that might be useful to you and PHPword .

Requirements to use PHPWord

Using PHPWord

Example to generate a .docx file and download it:

<?php
require_once 'src/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();

$filename = 'helloWorld.docx';

$phpWord = new \PhpOffice\PhpWord\PhpWord();

$section = $phpWord->addSection();
$section->addText(
    htmlspecialchars('Ola mundo!')
);

//Texto com Tahoma e fonte tamanho 10
$section->addText(
    htmlspecialchars('Ola 2'),
    array('name' => 'Tahoma', 'size' => 10)
);

$fontStyle = new \PhpOffice\PhpWord\Style\Font();
$fontStyle->setBold(true);
$fontStyle->setName('Tahoma');
$fontStyle->setSize(13);
$myTextElement = $section->addText(
    htmlspecialchars('"Teste test." (Texto customizado)')
);
$myTextElement->setFontStyle($fontStyle);

//Salva o documento como word2007 (ou docx)
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$objWriter->save($filename);

header('Content-Type: application/octet-stream; charset=utf-8');
header('Content-disposition: attachment; filename="' . uniqid(time()) . '.docx";');
header('Content-Length: '. filesize($filename));
readfile($filename);
    
17.09.2015 / 04:17
1
  

UPDATE

I was having some difficulty using PHPWord by calling external HTML files, and while searching for some errors I ended up finding this sensational library >.

The use is quite simple. After downloading, unzip inside your project and you're done. It already comes with the necessary files (PHPWord etc, but you may want to download the updated versions, which for me complicated so I left with the ones that come by default - see below).

Inside the folder there is a file example.php where you only need to change this line:

// HTML fragment we want to parse:
$html = file_get_contents('../arquivo.html');

To get dynamically created files, I created a while on the login page to get the id of the generated HTML file, and in the file example.php I get the id by the URL to choose the right file:

$numberfile = (int)$_GET['id'];

And then:

$html = file_get_contents('../arquivo'.$numberfile.'.html');

And that's it. Of course this is a basic example, that there are many possible settings, and that will only work with simple HTML codes, but it's much easier than anything I've found so far.

(translated by Google Translate)

Project Description

This code converts HTML to Word documents ( docx format). The code is written in PHP, and works with PHPWord.

This converter is specially designed to take simple HTML - the type of HTML typically produced by WYSIWYG editors (such as TinyMCE) or that can be included in a blog - and converts them to a Word document docx .

The result is a document familiar to most people using Word documents and therefore easy to use. There is no way to recreate complex web page layouts in a Word document.

This converter requires SimpleHTMLDom and PHPWord * for the function - copies of both are included in this release (although you may want to download the latest versions of these).

This converter was developed through the Commtap project that supports people working with children with communication disabilities.

If you like this converter, feel free to donate!

  

/ UPDATE

The correct headers are:

for Excel (* .xlsx):

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $fileName . '"');

for Word (* .docx):

header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment;filename="' . $fileName . '"');

* Translated this answer from SOen.

Update: With Content-Disposition of the above form was not working, but following at this point other answer of this same question , I was able to download in .doc here like this:

<?php
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header("Content-Disposition: attachment; filename=\"{$No}_{$Name}_{$Test}.docx\"");
    
11.09.2015 / 08:04