سؤال

This is right now I am using.

$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
header('Content-Description: File Transfer');
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename='.basename($type.'.xlsx'));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');   
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
print "$header\n$data";
exit;

$header variable contains the header row of excel to be generated and looks like this

$header= "Business_Name\tBusiness_Type\tType";

separated by \t

and $data contains rows to be generated under header columns. They are also separated by \t and a row is terminated by \n.

With the current setup file is downloaded but it is not opening with ms excel and showing this message.

Excel cannot open the file "file name" because the file format or file extension is not valid. Verify that the file format has not been corrupted and that the file extension matches the format of the file.

What header should be sent to server? or how do I generate that file?

هل كانت مفيدة؟

المحلول

What you have is actually a CSV file. Depending on your OS, your browser and your Excel version, then the browser will differently let you or not let your open the extensions CSV, XLS XLSX with the Excel software.

If you do want to have your data opened with Excel, then you can merge the data with an Excel template using OpenTBS. Use version 1.6.0 (or greater) which is currently in Release Candidate because it brings major facilities for Excel files.

In your title there is "no excel library PHP". I don't know why you have this specification but OpenTBS is not exactly an Excel library. It's a PHP tool for merging OpenOffice and Ms Office documents using templates.

نصائح أخرى

I achieve this in a fast, sort of cheapskate way - because it's long and winded I'll just explain it in concept rather than code.

XLSX adheres to ISO 29500 which is publicly available if you want to manipulate a document thoroughly in php. Otherwise, realise that xlsx files are zipped archives of a bunch of xml files.

Make a template that you want, say it has alternating rows with styles of different types, making that in excel or an open xml editor of some description. Make sure you put some data in there, and make sure some fields are equal (just for learning purposes).

Then save your file as xlsx, rename it .zip, or open it in an archive extractor and observe the contents.

Firstly, note the [Content_Types].xml file, this describes the location of the major files in the archive and the standards to which it itself adheres and the content types of those files.

Everything outside the xl/ folder is just meta data really. But observe docProps/core.xml contains author, modification and timestamp information - which you can replace in php when you recreate this file. Also everything that is pointed to say, docProps/core.xml can be renamed to your tastes, [Content_Types].xml can't.

Okay so now you understand this, you'll begin observing ids thrown around the place. They love to use this in the file format, everything refers to everything else by its index in a particular xml property list or similar. They also usually describe the quantity of items in such lists.

In xl/ you'll see themes.xml, styles.xml, workbook.xml, sharedStrings.xml, _rels/, worksheets/.

Styles is going to be inflated with a whole lot of unnecessary styles that excel builds by default if you used it. But you should be able to see how these styles work such that you can customise your own.

Themes to me is rather pointless so I delete it and its referenced ids throughout.

Next up you'll see workbook, that's the file containing information regarding the sheets which are inside of the spreadsheet document since you can have more than 1 obviously. It also contains some sheet metadata such as its size etc.

Now comes the first big hua you'll encounter. sharedStrings.xml is a weird file which stores all the information that will be inserted into cells in a static spreadsheet. They are indexed, but the engine reading the document figures out what their indexes are. Anything which repeats can be referred back to its old index in the sheet itself (inside worksheets folder) as to save on file size in large documents with repeated values. Not the attributes count and uniquecount in the sst element and what they obviously mean.

This is the stage in php where you populate an array of data containing what you want in your sheet, and dump it into an xml formatted list such as this file appears. Also note these files don't need to be jammed up without newlines or linefeed characters as with or without is still valid xml and they will work in readers regardless.

Check out the _rels folder, it's fairly obvious again.

Lastly is the sheet itself. The numbers in fields here refer to the indexed locations of strings in sharedStrings.xml. The attribute s is the style, t is the type of data in the field. R is the cell location though why it needs that is beyond me when it could really be figured out rather easily.

Producing this file in php shouldn't be too difficult either. Just use your indexes from your data array you used to make your sharedStrings.xml file.

Oh also sheet has column width information in it which you can figure out based on the font you used and automatically size them in php too if need be.

Lastly is the packaging of it all in php.

My code is in a class which receives data and specific saved files I created with excel to keep it simple.

$this->folder_structure_simple = Array(
    "_rels/.rels" => "_rels__rels",
    "docProps/app.xml" => "docProps_app_xml",
    "docProps/core.xml" => "docProps_core_xml",
    "xl/_rels/workbook.xml.rels",
        "xl/theme/theme1.xml",
        "xl/worksheets/sheet1.xml",
        "xl/sharedStrings.xml",
        "xl/styles.xml",
        "xl/workbook.xml",
    "[Content_Types].xml" => "Content_Types_xml"
);

$zip = new ZipArchive;
$res = $zip->open($this->file_name, ZipArchive::CREATE);
if($res === TRUE){
    foreach($this->folder_structure_simple as $file => $function){
            $zip->addFromString($file, $this->$funtion);
    }
    $zip->close();
    echo 'ok';
}else{
    return FALSE;
}

And functions produce the required data. Very fast, not very flexible.

What you have a CSV, not an XLSX file. XLSX is a ZIP-wrapped blob of XML. Change your MIME type to text/csv.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top