Force text to be downloaded in a format accepted by Msword with PHP?

Asked

Viewed 1,637 times

5

I’d like to know how to force the download of a file, with some extension accepted by Microsoft Word, through function header.

I searched a few times, tested the MIME types I found, like the ones found in this microsoft list, but I was unsuccessful.

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

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

Full 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);
  • 1

    I don’t know if I understand... You want to turn an aquivo .php in .doc and then make it available for download? If so has the Phpword...

  • @gustavox No, I want to take any text, it can be coming from the database or not, and export it in . doc

  • 1

    So explain how you want to do this. Specific function in PHP I think does not exist, I’m almost sure you will need Phpword even... take a look.

  • With Phpword, you can create DOCX, ODT, or RTF Documents dynamically using your PHP 5.3+ scripts. Below are some of the Things that you can do with Phpword library: [...] Create header and footer for each sections

  • @Okay, I’ll take a look at this class, but "I heard" that could force the download the same way q a txt file, I don’t know...

  • I wish there was, I could use it... :-)

  • 1

    @gustavox rsrsrs as it is... I’ll leave it open here, see if more suggestions arise

  • nah, forget everything I said before... see that.

  • @Thomersonroncally Always add a functional example of the problem, so it makes it easier for people to detect the fault, I recommend reading: http://answall.com/help/mcve, I removed the "if you need the comment code" part because always enter the code, it does not need to be complete, it only needs to "work" and needs to reproduce the problem (it must be Minimal, Complete and Verifiable) --- I hope the answer helps you :) See more.

  • 1

    @Gustavox strange that your second comment says the answer (you will need the same Phpword), now that I saw, I did not understand why not added it the answer. The example of the author will not work precisely for this, he is trying to send a simple text pro output and force but with the extension .doc, However software like Msword and Libreoffice cannot read this. The docx file for example 'and a zip file containing several files, among them the main and an xml (office open xml https://en.wikipedia.org/wiki/Office_Open_XML_file_formats) :)

  • Yes @Guilhermenascimento, I had already looked at this library, it’s very good, but at the time I found it a little complicated for me... and as ap said it was possible, I thought it would be much simpler to use only the header, since a part of what I need is only text (Phpword will be better if I get it because it rents all html right.)... But anyway, so there is no way anyway, because in Open Office it opens, but it is opening in asc II right, and the windows word does not open like this... I downloaded. Thanks so far! Hugs. + 1

  • In time: I was able to install right, and already I get the examples that come in the folder, but I still could not make work with the code generated dynamically from my form, but I think this would be another question... Thanks.

  • 1

    Thanks @gustavox :)

Show 8 more comments

2 answers

7


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

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

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

Therefore neither .doc and neither .docx are common text files.

Note: Programs like Abiword and Openoffice (as cited by @gustavox) worked because they themselves try to recode the plain text files to type files doc or odt and so it was possible to view.

If you want to create a file .docx true PHP will require a library. A library that can be useful to you and Phpword.

Requirements to use Phpword

Using the Phpword

Example to generate a file .docx 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);
  • 2

    Actually, the way was to use this library, Phpword, to generate a . docx file without corrupting it. I appreciate the attention of all who responded... @gustavox, for having cited the Phpword library and for his efforts in testing, and Guilherme for clarifying the problem and how to use the library. Thank you :)

2

UPDATE

I was having some difficulty using Phpword calling external HTML files, and during the search due to some errors I ended up finding this sensational library.

The use is quite simple. After downloading, unzip within your project and you are ready. It already comes with the necessary files (Phpword etc, but you might 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 is a file example.php where only this line needs to be changed:

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

To get dynamically created files, I created a while in the entry page to get the id of the generated HTML file, and in the file example.php picked 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 about 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 Translator)

Description of the Project

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

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

The result is a document familiar to most people who use Word documents and therefore easy to use. It is not intended in any way to recreate complex layouts of web pages in a Word document.

This converter requires Simplehtmldom and Phpword * for the function - copies of both are included in this version (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 of this answer soen.

Update: With the Content-Disposition The way above was not working, but following this point the other answer to that same question, I managed to download in .doc here in this way:

<?php
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header("Content-Disposition: attachment; filename=\"{$No}_{$Name}_{$Test}.docx\"");
  • I tried here using these MIME types and did not roll :/ I ask you to check on code I made available on ideone to, if appropriate, test there. Because it downloads the .docx, but gives error while opening in word. :/

  • @Thomersonroncally Ah, damn Windows guy :P, because here on Ubuntu 14.4, using both Abiword and Openoffice, the file opens perfectly using the code you posted on ideone... PS: Is the problem not with some configuration of your Word?

  • Just for the record, when I open in Openoffice it opens an ASCII Filter Options screen, with the suggested preconfiguration like this: Unicode:UTF-8 / Default-Fonts: Times New Roman / Language - English-BR... and clicking with this preconfiguration even it opens normally... the problem in your Word may be with Unicode....

Browser other questions tagged

You are not signed in. Login or sign up in order to post.