I am using PHPExcel to save a multidimensional array data in a xls file
This is my code:
$arr = array(
array("01", "02", "03"),
array("04", "05", "06"),
);
// include PHPExcel library
$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->fromArray($arr);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save("file.xls");
My problem is that starting nulls are removed in my xls file. For example is saved not as 01, but as 1.
How to solve this problem?
If you want a string with a numeric value to retain leading zeroes, then you have two choices:
Write it as a string using
$objPHPExcel->getActiveSheet()->getCell('A1')
->setValueExplicit(
'01',
PHPExcel_Cell_DataType::TYPE_STRING
);
(PHPExcel_Cell_DataType::TYPE_STRING is the default, so you don't actually have to specify that argument)
or allow it to be written as a number, and then set a format mask to display it with leading zeroes
$objPHPExcel->getActiveSheet()->getStyle('A1')
->getNumberFormat()
->setFormatCode("00");
EDIT
You can apply a style to a range of cells, not just to individual cells
$arr = array(
array("01", "02", "03"),
array("04", "05", "06"),
);
// include PHPExcel library
$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->fromArray($arr);
$objPHPExcel->getActiveSheet()->getStyle('A1:C2')
->getNumberFormat()
->setFormatCode("00");
There seems to be a solution on the forum:
http://phpexcel.codeplex.com/discussions/31240
you need to set the row's attribute like this
$objPHPExcel->getActiveSheet()->getStyle('A0')->getNumberFormat()->setFormatCode("#");
but i don't know what format you need ,just look for the mannul
Related
I want to calculate difference between 2 datetimes in hours with PHPSpreadsheet. This is how Excel does it:
A1 and A2 cells format is:
This is the result on web:
When I change value through PHPSpreadsheet, I get #VALUE! and different value formatting.
$reader = PhpSpreadsheet\IOFactory::createReader("Xlsx");
$target_file = __DIR__ . '/test.xlsx';
$spreadsheet = $reader->load($target_file);
$spreadsheet->getActiveSheet()->setCellValue('A1', '24.6.2020 12:30');
$writer = new PhpSpreadsheet\Writer\Html($spreadsheet);
$output = $writer->generateHTMLHeader();
$output .= $writer->generateStyles(true);
$output .= $writer->generateSheetData();
$output .= $writer->generateHTMLFooter();
$doc = new DOMDocument();
#$doc->loadHTML($output);
echo $doc->saveHTML();
I also tried with formatting like this 6/24/2020 14:30 but the result was same (#VALUE!)
$spreadsheet->getActiveSheet()->setCellValue('A1', '6/24/2020 14:30');
Anyone got any idea on how this should be done?
In an Excel document, dates are stored as numbers, not strings. So you need to pass the correct number to setCellValue().
PhpSpreadsheet provides the utility method Date::stringToExcel() to convert strings to Excel dates. You can use it like this:
$date = PhpSpreadsheet\Shared\Date::stringToExcel('2020-06-24 12:30');
$spreadsheet->getActiveSheet()->setCellValue('A1', $date);
I'm having difficulty with PHPSpreadsheet when creating an XLSX file and attempting to write large numbers of decimal places to numerical values.
PHPSpreadsheet is rounding my 14 decimal place numbers, but I need them stored exactly as presented.
I'm using setFormatCode('0.00000000000000') as described in the documentation, but it's not working as I would expect.
Here's my test code:
<?php
require __DIR__ . '/vendor/autoload.php'; // Installed via composer
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$array = [
0.03790728347833,
1345.28748532874927,
121345.18248762894914, // all 14 DP
];
$format = '0.00000000000000'; // 14 DP
// write the data
$spreadsheet->getActiveSheet()
->fromArray($array, null, 'A1');
// Format the cells
$spreadsheet->getActiveSheet()->getStyle('A1:C1')->getNumberFormat()->setFormatCode($format);
// Column sizing
foreach(range('A','C') as $columnID)
{
$spreadsheet->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
}
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("test.xlsx");
// A1 = 0.03790728347833 - same
// A2 = 1345.28748532870000 - rounded
// A3 = 121345.18248763000000 - rounded
Could anyone provide a way to store this many decimal places without rounding?
This appears to be a limitation of Excel rather than PHPSpreadsheet.
Excel is limited to 15 significant figures according to Wikipedia.
I am using the excelToArray function found here: https://gist.github.com/calvinchoy/5821235
function excelToArray($filePath, $header = true) {
require_once("./PHPExcel/Classes/PHPExcel.php"));
//Create excel reader after determining the file type
$inputFileName = $filePath;
/** Identify the type of $inputFileName **/
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
/** Create a new Reader of the type that has been identified **/
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/** Set read type to read cell data onl **/
$objReader->setReadDataOnly(true);
/** Load $inputFileName to a PHPExcel Object **/
$objPHPExcel = $objReader->load($inputFileName);
//Get worksheet and built array with first row as header
$objWorksheet = $objPHPExcel->getActiveSheet();
//excel with first row header, use header as key
if($header){
$highestRow = $objWorksheet->getHighestRow();
$highestColumn = $objWorksheet->getHighestColumn();
$headingsArray = $objWorksheet->rangeToArray('A1:'.$highestColumn.'1',null, true, true, true);
$headingsArray = $headingsArray[1];
$r = -1;
$namedDataArray = array();
for ($row = 2; $row <= $highestRow; ++$row) {
$dataRow = $objWorksheet->rangeToArray('A'.$row.':'.$highestColumn.$row,null, true, true, true);
if ((isset($dataRow[$row]['A'])) && ($dataRow[$row]['A'] > '')) {
++$r;
foreach($headingsArray as $columnKey => $columnHeading) {
$namedDataArray[$r][$columnHeading] = $dataRow[$row][$columnKey];
}
}
}
}
else{
//excel sheet with no header
$namedDataArray = $objWorksheet->toArray(null,true,true,true);
}
return $namedDataArray;
}
I have two versions of a spreadsheet, one in CSV and one in Excel. Here they are:
CSV: https://drive.google.com/open?id=0B2GilRTNrTzKd3V3aEVET1NqSW8
XLSX: https://drive.google.com/open?id=0B2GilRTNrTzKdzJNZnh0cmhpa1E
When I upload the CSV using this function and var_dump the results I get
array (size=58)
0 =>
array (size=4)
'PD' => string '11/10/2016' (length=10)
'Pt' => string '9:12' (length=4)
'fd' => string '11/10/2017' (length=10)
'ft' => string '9:12' (length=4)
1 =>
array (size=4)...
But when I upload the XLSX I get:
array (size=58)
0 =>
array (size=5)
'PD' => float 42684
'Pt' => float 0.38333333333333
'fd' => float 43049
'ft' => float 0.38333333333333
'' => null
1 =>
array (size=5)
Notice that the PD goes from 11/10/2016 to 42684, and Pt from 9:12 to 0.38333...
What is causing the XLSX file to not be read in as it displays?
I have already read other stack questions, but I appear to be passing toArray the correct values. Not sure what I' missing...
MS Excel stores dates as a serialized timestamp, the number of days since 1t January 1900 (or 1st January 1904, depending on whether it is using the Windows or the Mac calendar). PHPExcel does likewise, so all dates/times are loaded to store in the spreadsheet object in exactly the way that MS Excel works with them.
So when you load a file with a human format date, it reads that as an MS Excel serialized timestamp. Ordinarily, it would also store the number format mask telling PHPExcel that this cell contains a timestamp value that shoud be formatted as a date, but you're telling PHPExcel's loader not to take this additional action by using $objReader->setReadDataOnly(true); which means store only the data, and not the formatting information.
Because PHPExcel desn't hve this additional formatting information, it cannot know that the cell contains something that should be dispayed as a date, so it can only dispay the serialized tiemstamp, which is really just a float.
In other words, don't do $objReader->setReadDataOnly(true); if you want dates to be treated as dates, or unless you want to do all the date handling yourself
I'm trying to change the datatype for a whole column (for eg: i need to change for "M" Column to general format). Its displaying as 2.00 in quantity field,I need to change this whole column to general format ie. display as "2". But its not changing the datatype.
Here is the code:
$objPHPExcel->getActiveSheet()
->setCellValue(
$aCells[$eExcelColumn] . $eExcelRow,
$sCellData ,
PHPExcel_Cell_DataType::TYPE_NUMERIC
);
$objPHPExcel->getActiveSheet()->getStyle('M1:M97')
->getNumberFormat()
->setFormatCode('0');
How to do for the whole column "M" as general format
PHPExcel doesn't support column or row styling: you need to set the style for a range of cells, exactly as you are doing with
$objPHPExcel->getActiveSheet()->getStyle('M1:M97')
->getNumberFormat()
->setFormatCode('0');
if you want General format rather than '0', then set it to General Instead:
$objPHPExcel->getActiveSheet()->getStyle('M1:M97')
->getNumberFormat()
->setFormatCode('General');
or
$objPHPExcel->getActiveSheet()->getStyle('M1:M97')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
You can do a column like this:
$objPHPExcel->getActiveSheet()->getStyle('M:M')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
A complete working example. The result in column A has two 2, column B two 2.00
$sheet = $objPHPExcel->getActiveSheet();
$sheet->getStyle('A:A')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
$sheet->getStyle('B:B')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00);
$sheet->setCellValue('A1', 2);
$sheet->setCellValue('A2', 2.0);
$sheet->setCellValue('B1', 2);
$sheet->setCellValue('B2', 2.0);
A few more examples for column and row selections that I pulled from my actual base:
$objPHPExcel->getActiveSheet()->getStyle('1:1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('A:A')->getNumberFormat()->setFormatCode('yyyy/mm');
$objPHPExcel->getActiveSheet()->getStyle('D:D')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('E:E')->getNumberFormat()->setFormatCode('$#,###');
$mfisinArr = $this->isObject->getAllDataMfisinQuery();
if(isset($mfisinArr) && !empty($mfisinArr))
{
$excel_row = 2;
foreach ($mfisinArr as $key => $value)
{
// PHPExcel Style getting default number format
$object->getActiveSheet()->getStyle('A'.$excel_row)->getNumberFormat()->setFormatCode('0');
$object->getActiveSheet()->setCellValueByColumnAndRow(0, $excel_row, sprintf('%09d',$value['security']));
$object->getActiveSheet()->setCellValueByColumnAndRow(1, $excel_row, $value['name']);
$object->getActiveSheet()->setCellValueByColumnAndRow(2, $excel_row, $value['mf_isin']);
$object->getActiveSheet()->setCellValueByColumnAndRow(3, $excel_row, empty($value['mat_dt'])?'':date('d-m-Y',strtotime($value['mat_dt'])));
$excel_row++;
}
}
I'm loading an Excel file that has cells with time data, e.g. 08:00:00. But when I try to read those cells with getValue(), it returns some floating point numbers instead of the actual time (in case of 08:00:00, it returns 0.3333333). Here's my code:
$objPHPExcel = PHPExcel_IOFactory::load($filename);
$objWorksheet = $objPHPExcel->getActiveSheet();
echo $objWorksheet->getCellByColumnAndRow(3, 5)->getValue();
How do I bypass this weird conversion?
PHPExcel 1.7.6 and Excel 2003 Worksheet (.xls)
You need to apply cell format for this:
$cell = $objWorksheet->getCellByColumnAndRow(3, 5);
$cell_value = PHPExcel_Style_NumberFormat::toFormattedString($cell->getCalculatedValue(), 'hh:mm:ss');
echo $cell_value;