Export to ExCel shows some columns empty - php

I am trying to export the data from PHP & MySql. I am getting Empty value for Fields which are having huge data(around 1000 chars). Except those fields everything is working fine.
This is the code which i am using right now. Please check once and let me know if any modifications. I searched in google, so many said its cache/memory problem.
<?php
function xlsBOF() {
echo pack("ssssss", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
return;
}
function xlsEOF() {
echo pack("ss", 0x0A, 0x00);
return;
}
function xlsWriteNumber($Row, $Col, $Value) {
echo pack("sssss", 0x203, 14, $Row, $Col, 0x0);
echo pack("d", $Value);
return;
}
function xlsWriteLabel($Row, $Col, $Value ) {
$L = strlen($Value);
echo pack("ssssss", 0x204, 8 + $L, $Row, $Col, 0x0, $L);
echo $Value;
return;
}
$sel_sql=mysql_query("select desc from table");
$myFile = date("m-d-Y").'_users.xls';
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/vnd.ms-excel");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=".$myFile);
header("Content-Transfer-Encoding: binary ");
// XLS Data Cell
xlsBOF();
xlsWriteLabel(0,1,"desc");
$xlsRow = 1;
while(list($desc)=mysql_fetch_row($sel_sql)) {
xlsWriteLabel($xlsRow,1,"$desc");
$xlsRow++;
}
xlsEOF();
?>

Assuming you're using an xls file output: in a BIFF format file, a cell is limited to 32,767 characters; but only 1,024 characters are displayed in the cell. All 32,767 characters are display in the formula bar.
EDIT
Reading the code that you've actually posted:
Excel has limits on the amount of data a cell can hold: for Excel BIFF 8 files, that limit is 32,767 characters. However, for long strings, this data is maintained in the BIFF file across several blocks with continuation records, For BIFF 5 files (Excel 95) the limit is 2084 bytes per block; in BIFF 8 files (Excel 97 and above) the limit is 8228 bytes. Records that are longer than these limits must be split up into CONTINUE blocks.
This relatively simplistic writer isn't written to handle splitting the record into multiple continuation records: it doesn't even use the BIFF 8 shared string table, or indicate what BIFF version it is writing (which means Excel will open it using lowest common denominator parameters). It simply tries to store the entire contents of the cell into a standard label block. To fix this, you'd need to fix your code to handle splitting the string values with continuation blocks (via a shared string table); or switch to using a library that does handle splitting the shared strings across multiple blocks already.

Related

fwrite() can display number_format() in PHP [duplicate]

This question already has answers here:
Is there a way to include commas in CSV columns without breaking the formatting?
(17 answers)
Closed 1 year ago.
I'm doing function to export CSV file in PHP. but when i do an export, i need to add information about total in number_format().. but display is wrong.
Here is my code
header('Content-Type: text/csv; charset=utf-8');
header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
header('Content-Disposition: attachment; filename=' . $fileName );
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
$file = fopen("report.csv", "w");
fwrite($file, "Generate Report \r\n");
fwrite($file, "Total Sales, ".number_format($total)."\r\n");
fwrite($file, " "."\r\n");
the result is this
and that is wrong.
How do i can display the correct format number like "5,485" or maybe "5,485.00" in 1 cell on CSV file?
please help
fwrite(resource $handle, string $string, int $length = ?):
fwrite($file, "Total Sales, \"".number_format($total)."\"\r\n");
int fwrite() writes the contents of string to the file stream pointed to by handle.
Return Values fwrite() returns the number of bytes written, or false on error.

I can't display "11e5" as it is on Excel spreadsheet using PHP

I am exporting data to a CSV file, but there is a value "11e5" that is getting interpreted as a number by Excel. Instead of the text, it shows 1.10E+06 on the Excel spreadsheet.
I've tried prefixing the value with an apostrophe, but then it shows up as 1100000 in Excel.
Here is the code I'm using to test, the live code gets data from MySQL.
function array2csv(array &$array)
{
if (count($array) == 0) {
return null;
}
ob_start();
$df = fopen("php://output", 'w');
fputcsv($df, array_keys(reset($array)));
foreach ($array as $row) {
fputcsv($df, $row);
}
fclose($df);
return ob_get_clean();
}
function download_send_headers($filename){
$now = gmdate("D, d M Y H:i:s");
header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
header("Last-Modified: {$now} GMT");
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");
}
$row1 = array ('Assignment name', 'tet4' );
$row2 = array ('Class name','11e5' );
$row3 = array ('Name', 'Target', 'Start grade', 'End Grade', 'Avarage grade', 'May', 'June', 'July', 'August','06th Aug', '13th Aug', '20th Aug', '27th Aug', '03rd Sep', 'Last 7 days', 'Last 24 hours', 'Total points' );
$row4 = array ('Maan Roy', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 32 );
$row5 = array ( 'mac mac', 0, 1, 2, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 98 );
$response = array();
array_push($response, $row1);
array_push($response, $row2);
array_push($response, $row3);
array_push($response, $row4);
array_push($response, $row5);
download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo array2csv($response);
11e5 (11 × 105) represents a number around 1100000.
Excel chooses for a different way to represent the same number. 1.10E+06 (1.10 × 106) indeed represents the same number.
If you make the column holding the cell wider, it might even show 1100000 in Excel.
But for you 11e5 is a string indicating the name of the class. So as per CSV try putting the value in double quotes " to indicate the value is a string. Or as per Excel, try putting an apostrophe ' in front of the value, to indicate the value is a string.
Edit your code to output the value like ="11e5" and it should work fine. Tested with Excel 2016 on a Mac, but behaviour should be the same on Windows.
See this post on SU.
The CSV file format does not explicitly support meta-data, and MSExcel has a very annoying habit of assuming that anything which looks like a number is a number (it also strips off leading zeros and may insert commas). And to add insult to injury, it changes the data rather than just rendering it differently.
In a manual import, you can override this behaviour by specifying a type of 'TEXT' for the column - but that's not a great solution.
If you want a seamless user experience then you'll need to use a different format than CSV (or not use MSExcel?). You can write XML using the standard tools and there are libs for generating a file similar to an xlsx (although IME, MSExcel usually complains the latter are still in the wrong format even though it will load and render the data as intended).

PHP export to binary Excel file - UTF-8 character encoding

I am using this simple function (taken from here) to export PHP array into simple binary Excel file. Writing binary Excel file was my requirement.
public static function array_to_excel($input)
{
$ret = pack('ssssss', 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
foreach (array_values($input) as $lineNumber => $row)
{
foreach (array_values($row) as $colNumber => $data)
{
if (is_numeric($data))
{
$ret .= pack('sssssd', 0x203, 14, $lineNumber, $colNumber, 0x0, $data);
}
else
{
$len = strlen($data);
$ret .= pack('ssssss', 0x204, 8 + $len, $lineNumber, $colNumber, 0x0, $len) . $data;
}
}
}
$ret .= pack('ss', 0x0A, 0x00);
return $ret;
}
Then to call this is pretty much simple simple:
Model_Utilities::array_to_excel($my_2d_array);
Function itself works great and is super simple to create simple binary PHP file. The problem I have is with UTF-8 characters. I get strange characters like Ä¡ instead of right characters... Is there a way to set character encoding in my to excel function?
EDIT:
After wading through hundreds of obfuscated Microsoft docs before locating the OpenOffice version of the XLS format spec, I managed to do something.
However, it relies on the BIFF8 format since, as far as I can tell, BIFF5 (the format used by Excel95) has no direct UTF-16 support.
function array_to_excel($input)
{
$cells = '';
foreach (array_values($input) as $lineNumber => $row)
{
foreach (array_values($row) as $colNumber => $data)
{
if (is_numeric($data))
{
$cells .= pack('sssssd', 0x203, 14, $lineNumber, $colNumber, 0x0, $data);
}
else
{
$data = mb_convert_encoding ($data, "UTF-16LE", "UTF-8");
$len = mb_strlen($data, "UTF-16LE");
$cells .= pack('ssssssC', 0x204, 9+2*$len, $lineNumber, $colNumber, 0x0, $len, 0x1).$data;
}
}
}
return pack('s4', 0x809, 0x0004, 0x0600, // <- this selects BIFF8 format
0x10) . $cells . pack('ss', 0x0A, 0x00);
}
$table = Array (
Array ("Добрый день", "Bonne journée"),
Array ("tschüß", "こんにちは。"),
Array (30, 40));
$xls = array_to_excel($table);
file_put_contents ("sample.xls", $xls);
My (French) PC version of Excel 2007 managed to open the sample file in compatibility mode, Russian and Japanese included. There is no telling how this hack would work on other variants, though.
EDIT (bis) : from the file specs linked above:
Byte Strings (BIFF2-BIFF5)
All Excel file formats up to BIFF5 contain simple byte strings. The byte string consists of the length of the string
followed by the character array. The length is stored either as 8bit value or as 16bit value, depending on the current record. The string is not zero-terminated.
The encoding of the character array is dependent on the current record.
Record LABEL, BIFF3-BIFF5:
Offset Size Contents
0 2 Index to row
2 2 Index to column
4 2 Index to XF record
6 var. Byte string, 16-bit string length
Unless you generate a much more complex file, I'm afraid BIFF5 is a no go.

Problem downloading data to Excel using PHP "pack" function

I have a PHP application that downloads MySQL table data to a spreadsheet on the client machine. I found some code in numerous places on the web that works fine for Open Office Scalc on a machine running Redhat. The problem I ran into was when I tried to download to an MS Excel on a Windows PC rather than to an Open Office spreadsheet. The problem seems to be associated with the length of the string inserted into a cell. If it is too long, Excel thinks the file is corrupt and won't load it. "Too long" seems to be about 255 characters, even though the MS Excel specs say 32,000 is the maximum length.
To investigate the problem further, I tried downloading the same data as a tab-separated values file and let Excel convert it to a spreadsheet. Using that method, there was no problem loading very long strings into the spreadsheet cells. So strings much longer than 255 characters can in fact be inserted into Excel cells, but just not with the code I am using, even though that code works with Open Office. Using tsv files would not solve our problem, because the long strings have carriage returns that we want to retain, and carriage returns are interpreted as row separators when a tsv file is loaded into a spreadsheet.
The PHP function that writes a string to a spreadsheet cell is:
function xlsWriteLabel($Row, $Col, $Value ) {
$L = strlen($Value);
echo pack("ssssss", 0x204, 8 + $L, $Row, $Col, 0x0, $L);
echo $Value;
return;
}
The other necessary code for transfers to spreadsheets in addition to the above function can be found at:
http://www.appservnetwork.com/modules.php?name=News&file=article&sid=8
I haven't found any explanations as to the meanings of the various arguments passed to the "pack" function in the above code, and I'm wondering if changing one the arguments in the function above could solve the problem.
So, if anyone has a solution to this problem, I'd be interested in hearing it.
...unless your text has double quotes.
What you should use is proper delimiters from the ASCII char set.
Seq Dec Hex Acro Name
^\ 28 1C FS File Separator
^] 29 1D GS Group separator
^^ 30 1E RS Record Separator
^_ 31 1F US Unit separator
I don't know php but in perl a print statement might look like:
print chr(30), "Field1", chr(30), "Field2", chr(30), "Field3", chr(31);
I have written a simple approach to generate absolute excel file.
A simple function.
First you convert your contents to an Array (it is very simple and everybody know.). Then pass the array to my function given below.
<?php
//array to excel
function arrayToExcel($array, $filename='List')
{
if (!is_array($array) or !is_array($array[0])) return false;
$xl = pack("ssssss", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0); //begining of excel file
$i = 0;
foreach ($array as $key => $val)
{
$j=0;
foreach ($val as $cell_key => $cell_val)
{
$cell_val = trim($cell_val);
$length = strlen($cell_val);
//checking cell value is a number and the length not equal to zero
if(preg_match('/^[0-9]*(\.[0-9]+)?$/', $cell_val) && $length!=0) {
$xl .= pack("sssss", 0x203, 14, $i, $j, 0x0); //writing number column
$xl .= pack("d", $cell_val);
}
else {
$xl .= pack("ssssss", 0x204, 8 + $length, $i, $j, 0x0, $length); //writing string column
$xl .= $cell_val;
}
$j++;
} //end of 2nd foreach
$i++;
} //end of first foreach
$xl .= pack("ss", 0x0A, 0x00); //end of excel file
$filename = $filename.".xls";
header("Pragma: public");
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=$filename");
header("Cache-Control: no-cache");
echo $xl;
} //end of arrayToExcel function
//eg: arrayToExcel($myarray, "contact_list");
?>
Surround your cell values with double quotes "", it will allow you to import the data in a tsv or csv format without having to worry about the carriage returns being interpreted as a new row. You could also use the fputcsv function from PHP to export a tsv or csv file that excel can read.
This is the slightly more efficient version of their functions thank you linked too, but I don't know if the format they output is actually correct for excel or not.
function xlsBOF(){
echo pack("s6", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
}
function xlsEOF(){
echo pack("ss", 0x0A, 0x00);
}
function xlsWriteNumber($Row, $Col, $Value){
echo pack("s5d", 0x203, 14, $Row, $Col, 0x0, $Value);
}
function xlsWriteLabel($Row, $Col, $Value){
$L = strlen($Value);
echo pack("s6A*", 0x204, 8 + $L, $Row, $Col, 0x0, $L, $Value);
}

PHP export to Excel results in wrong format and unwanted signs

I try to export data out of my Microsoft SQL Server 2008 Database to an Excel Spreadsheet.
I am using this tutorial:
http://www.appservnetwork.com/modules.php?name=News&file=article&sid=8
My header looks like this:
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.xls ");
header("Content-Transfer-Encoding: binary ");
The XLS Data Cell looks like this:
xlsBOF();
xlsWriteString(0,0,"$lng_report_age_title");
xlsWriteString(0,4,"$lng_report_sex_title");
xlsWriteString(0,6,"$lng_report_referredfrom_title");
xlsWriteString(0,8,"$lng_report_selfreferred_title");
xlsWriteString(1,0,"$lng_report_age04");
xlsWriteString(1,1,"$lng_report_age514");
xlsWriteString(1,2,"$lng_report_age1549");
xlsWriteString(1,3,"$lng_report_age50");
xlsWriteString(1,4,"$lng_report_sexm");
xlsWriteString(1,5,"$lng_report_sexf");
xlsWriteString(1,6,"$lng_report_referredfrom_indistrict");
xlsWriteString(1,7,"$lng_report_referredfrom_outdistrict");
xlsWriteString(1,8,"$lng_report_selfreferred_indistrict");
xlsWriteString(1,10,"$lng_report_selfreferred_outdistrict");
xlsWriteString(2,6,"$lng_report_referredfrom_new");
xlsWriteString(2,7,"$lng_report_referredfrom_new");
xlsWriteString(2,8,"$lng_report_selfreferred_new");
xlsWriteString(2,9,"$lng_report_selfreferred_old");
xlsWriteString(2,10,"$lng_report_selfreferred_new");
xlsWriteString(2,11,"$lng_report_selfreferred_old");
xlsWriteNumber(3,0,"$searchresultsage04");
xlsWriteNumber(3,1,"$searchresultsage514");
xlsWriteNumber(3,2,"$searchresultsage1549");
xlsWriteNumber(3,3,"$searchresultsage50");
xlsWriteNumber(3,4,"$searchresultssexm");
xlsWriteNumber(3,5,"$searchresultssexf");
xlsWriteNumber(3,6,"$searchresultsreferredfrom01");
xlsWriteNumber(3,7,"$searchresultsreferredfrom02");
xlsWriteNumber(3,8,"$searchresultsselfreferred03");
xlsWriteNumber(3,9,"$searchresultsselfreferred04");
xlsWriteNumber(3,10,"$searchresultsselfreferred05");
xlsWriteNumber(3,11,"$searchresultsselfreferred06");
xlsEOF();
exit();
And the create XLS functions look like this:
function xlsBOF() {
echo pack("ssssss", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
return;
}
function xlsEOF() {
echo pack("ss", 0x0A, 0x00);
return;
}
function xlsWriteNumber($Row, $Col, $Value) {
echo pack("sssss", 0x203, 14, $Row, $Col, 0x0);
echo pack("d", $Value);
return;
}
function xlsWriteString( $Row , $Col , $Value ) {
$L = strlen( $Value );
echo pack( "sssss" , 0x204 , 8 + $L , $Row , $Col , 0x0 , $L );
echo $Value;
return;
}
Problem Nr. 1:
In the Excel Sheet there will be several unwanted special characters around the text that I want to display (Maybe because I'm using UTF-8? (tried to utf8_decode the string first; didn't help)Maybe because I'm using Excel 2007?)
Problem Nr. 2:
The Values are not getting written into the row/column I want them to be in.
The result looks like this (the special chars get automatically removed by the stackoverflow editor, so I replace them with Xs):
XXXXXXXAgeXXXXXSexXXXX
Referred FromXXXX
Self ReferredXXX 0-4 YearsXXX
5-14 YearsXXXX 15-49 YearsXXX X
=50 YearsXXX XXMaleXXX XXFemaleXXXX XXIn DistrictXXX XXOut DistrictXXXX XXIn DistrictXXX
XOut DistrictXXXXXXNewXXXXXXNewXXXXXXNewXXXXXOldXXXX
XNewXXXXXXOldXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXX
All this data is in column A and in rows 1-8.
One more point I would like to know, once it works, is:
How can I format the cells (Borders, Fonts, etc)?
Thanks in advance.
As an indirect solution to your question, I'd recommend the classes at http://phpexcel.codeplex.com/.
I've used it in the past with good results. The learning curve isn't too bad, the documentation is OK, it's a small package, it has good support in the forums, and I'm reasonably sure it can answer everything you asked.
I had the same problem.
ob_end_clean(); $objWriter->save('php://output');
This will remove unwanted characters from excel.

Categories