creating excel with Greek characters - php

i have used the following headers in order to create xls files that contains Greek characters on the fly.
first attempt:
header("Content-Type: application/$file_type;charset=utf-8");
header("Content-Disposition: attachment; filename=$file_name.$file_ending");
header("Pragma: no-cache");
header("Expires: 0");
second attempt:
header("Content-Type: application/$file_type;charset=windows-1253");
header("Content-Disposition: attachment; filename=$file_name.$file_ending");
header("Pragma: no-cache");
header("Expires: 0");
the created file althought it contains the correct Greek characters (viewed with a text editor) when i open it at the ms-excel the Greek characters are shown as sympols.
i have also tried a library that creates xls (open xls binary format) with the same outcome. This library has options to set the codepage and the charset but still nothing.
any ideas?
thanks.

If you're using a library then it should have a function to set the encoding to UTF-8. For example, with PEAR's Spreadsheet_Excel_Writer (http://pear.php.net/package/Spreadsheet_Excel_Writer/redirected), you would do:
<?php
$workSheet = & $workBook -> addWorksheet('Students');
$workSheet -> setInputEncoding('utf-8');
?>
Of course, you must also make sure that your data are actually utf-8 and not ISO-8859-7 or windows-1253 for example.
Be aware that this does not support workbook name changing (ie using 'Μαθητές' instead of 'Students')

I'm not so sure about XLS files but if you'd rather use Excel readable CSV files, use UTF-16 encoding (with BOM) and tabs as separators
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=export.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo chr(255) . chr(254); // Add UTF-16 little-endian BOM
echo mb_convert_encoding("α\tβ\tγ"), 'UTF-16LE', 'UTF-8'); // from UTF-8 to UTF-16

Related

random added byte when downloading php file

I am trying to download a binary file from the server that uses PHP.
Somehow it randomly adds one byte at the front of the file, when downloading it:
Result download (Hex editor image):
Expected result download (Hex editor image):
Things i have tried:
1. Headers aproach try 1
$filename = 'spss-export.sav';
header("Content-Disposition: attachment; filename=survey_2_SPSS_syntax_file.sav");
header("Content-type: application/download; charset=UTF-8");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
readfile($filename); // do the double-download-dance (dirty but worky)
exit;
2. Header aproach try 2
$filename = 'spss-export.sav';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($filename) . "\"");
readfile($filename); // do the double-download-dance (dirty but worky)
exit;
3. Laravel response download
$filename = 'spss-export.sav';
return response()->download($filename);
Header aproaches produce files that only have the random byte at the begining, but laravel aproach produces the random byte and one missing byte at the end of file. Anyone knows what might be the problem?
Found an answer myself:
You have to add ob_end_clean() before the file output. The laravel framework was somehow adding an extra space for files.
Reference if this doesnt work:https://drupal.stackexchange.com/questions/163628/extra-space-at-beginning-of-downloaded-image/163644#163644

Generated Excel file is downloaded as XML instead

I'm generating and using the following sample XML to generate and download an XLSX file.
<!--?xml version="1.0"?-->
<!--?mso-application progid="Excel.Sheet"?-->
<ss:workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<ss:worksheet ss:name="Title">
<ss:table>
<ss:column>
<ss:row>
<ss:cell><ss:data ss:type="String">Something</ss:data></ss:cell>
<ss:cell><ss:data ss:type="String">Something</ss:data></ss:cell>
</ss:row>
</ss:column>
</ss:table>
</ss:worksheet>
</ss:workbook>
I then use the following code snippet to force the file to download.
<?php
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
;
header("Content-Disposition: attachment;filename=something.xml ");
header("Content-Transfer-Encoding: binary ");
print $this->file;
?>
The file downloads correctly; however, the extension is XML. I can manually open it in Excel and it would show correctly. I've tried changing the filename in the Content-Disposition line to something.xlsx, but when I try to open the file by double-clicking on it, I get a warning that:
Excel cannot open the file something.xlsx because the file format or
file extension is not valid. Verify that the file has not been
corrupted and that the file extension matches the format of the file.
Any idea what I'm doing wrong? Is the XML not in the right format?
You only need to set the Content-Type once, and you should set it to the correct value:
<?php
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment;filename=something.xlsx");
header("Content-Transfer-Encoding: binary");
echo $this->file;
Also best to leave off trailing ?> so that no stray whitespace gets into the downloaded file.

PHPEXCEL set UTF-8 encode

I have headers:
header('Content-Type: text/html; charset=UTF-8');
header("Content-type: application/octetstream");
header('Content-Disposition: attachment; filename="export.csv"');
but decoding not work correct if I have word in database "Pagrindinė" in excel show "PagrindinÄ", what is wrong with my headers ?
What is wrong with my headers ?
Nothing, your headers are looking fine.
What is wrong with Excel?
The user who opens the file in Excel needs to tell Excel that the file is in UTF-8 encoding. Direct that user to contact the vendor of the software it uses for her/his support options.
Users of LibreOffice or a derivate of it do not have that problem btw., so one solution is to tell those to install a suite of such, open the CSV file and save it as Excel file for example.
Or you directly create the Excel file on your server.
Maybe if you change the format text encoding of your .php file when you save it, to Unicode (UTF-8). It works for me.
Hope it helps.
try this:
header('Content-Transfer-Encoding: binary');
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
header('Content-Disposition: attachment; filename = "Export '.date("Y-m-d").'.xls"');
header('Pragma: no-cache');
//these characters will make correct encoding to excel
echo chr(255).chr(254).iconv("UTF-8", "UTF-16LE//IGNORE", $out);

PHP downloading excel file becomes corrupt

I have an excel file that i want a user to be able to download from my server. I have looked at a lot of questions on here but i cannot find a way to correctly download the file w/o corruption. I am assuming it is the headers but i haven't had a working combination of them yet. This is what i have right now and in the corrupt file that i receive i can see the column names of the spreadsheet i want but its all messed up.
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-type: application/octet-stream");
header("Content-type: application/vnd-ms-excel");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
readfile($filename);
edit: Solution I forgot to add that i was using Zend and it was corrupting the files when trying to use native php methods. My finsihed code was to place a link to another action in my controller and have the files download from there
public function downloadAction(){
$file = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="Spreadsheet.xls"');
readfile($file);
// disable the view ... and perhaps the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
}
try doing it this way
ob_get_clean();
echo file_get_contents($filename);
ob_end_flush();
For one, only specify Content-Type once. You can use the excel-specific header but the generic application/octet-stream may be a safer bet just to get it working (the real difference will be what the browser shows the user with regards to "what would you like to open this file with", but basic browsers can rely on the extension as well)
Also, make sure you specify Content-Length and dump the size (in bytes) of the file you're outputting. The browser needs to know how big the file is and how much content it's expecting to receive (so it doesn't stop in the middle or a hiccup doesn't interrupt the file download).
So, the entire file should consist of:
<?php
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($filename));
header("Pragma: no-cache");
header("Expires: 0");
#readfile($filename);
$file_name = "file.xlsx";
// first, get MIME information from the file
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file_name);
finfo_close($finfo);
// send header information to browser
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="download_file_name.xlsx"');
header('Content-Length: ' . filesize($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
//stream file
ob_get_clean();
echo file_get_contents($file_name);
ob_end_flush();

PHPExcel set specific headers for file format

While googling I found two different sets of headers that need to be set when outputting excel generated in different file format.
for e.g.
For Type "Excel5" headers are:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary ");
For Type "Excel2007" headers are:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="myfile.xlsx"');
header('Cache-Control: max-age=0');
My question: is there need to set up different headers for each file type as there are other file types also CSV, HTML and PDF?
header("Pragma: public");
No - this is just wrong - though lots of people think it has something to do with caching
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
Nothing to do with Excel - these just control caching
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
No - there should only be one content-type header. For a MS Excel file using OLE, the mimetype should be application/vnd.ms-excel
Only the second header above is a valid mime type.
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary ");
The second header is redundant, the former specifies a filename for the download.
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
Only for a .xlsx file (i.e. saved in XML). Otherwise you should use application/vnd.ms-excel. Indeed the latter should be backwardly compatible.
My question: is there need to set up different headers for each file type
Yes - the Content-Type header is the file type. But only this header needs to change.
C.

Categories