My column has the format of cell: dd / mm / yyyy hh: mm, when reading these worksheets, I need to get this value only the date and save in mysql.
By default, I'm reading the date, and giving exploits to save it, but the date comes in a weird format.
Column date in cell: 13/11/2017 00:01
My code:
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setReadDataOnly(true);
$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);
}
When reading the value directly is to give an echo: 43052.000717593
My code to just get the date in the format I need and save
$data_mailing_file = explode(" ", $value['field_date']);
$dataP = explode('/', $data_mailing_file[0]);
$data_save = $dataP[2].'-'.$dataP[1].'-'.$dataP[0];
The 43052.000717593 is an MS Excel serialized timestamp value, a count of the number of days since 1st January 1900 (or 1st January 1904 if the spreadsheet is using the Mac calendar).
MS Excel formats that value using the format mask, which you say is dd/mm/yyyy hh:mm and display that value as 13/11/2017 00:01, which is exactly what I'd expect from that format mask.
If you want to format the date differently; then you could change the format mask before calling rangeToArray(). An Excel format mask of yyyy-mm-dd will give you the date only in an appropriate format.
Alternatively get that serialized timestamp value, and then use the ExcelToPHP() or ExcelToPHPObject() methods of PHPExcel_Shared_Date to give a unix timestamp or a PHP DateTime object respectively, that you can then format however you want using PHP's date() function or the DateTime object's format() method.
Related
I have structure table like: name varchar(15), gender smallint(1), birth_date date().
Controller:
public function actionImport()
{
$profile = new Profile();
$inputFile = 'files/profile.xlsx';
try{
$inputFileType = \PHPExcel_IOFactory::identify($inputFile);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFile);
}catch(Exception $e){
die('error');
}
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for($row = 1; $row <= $highestRow; $row++)
{
$rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row, Null, TRUE, FALSE);
if($row == 1){
continue;
}
$profile->name = $rowData[0][0];
$profile->gender = $rowData[0][1];
$profile->birth_date = $rowData[0][2];
$profile->save();
}
}
File: profile.xlsx
Data import success, but birth_date still 0000-00-00.
I try to print_r display like this:
Data saved in table like this:
A getValue() call on a field containing a date should return a value like 41959.... that is, an MS Excel serialized datetime stamp based on the number of days since 1st January 1900 (or 1st January 1904 if the file was created using the Mac version of MS Excel), and (by default) rangeToArray() uses a getValue() call.
To get a formatted date string, you need to call getFormattedValue() instead; and PHPExcel then uses the number format mask for that cell to format the date according to that mask. You can set rangeToArray() to do this for you by setting the $formatData argument to true.
$rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row, Null, TRUE, TRUE);
This will format all cells as they appear in the spreadsheet in Excel itself.
Alternatively, PHPExcel does provide functions to convert date values between Excel timestamps and unix timestamps, or PHP DateTime objects, and you could use those instead:
$profile->birth_date = PHPExcel_Shared_Date::ExcelToPHPObject($rowData[0][2])
->format('Y-m-d');
Dependence of your image, you try to save int number in date
field...so that the error is gone....
To resolve issue, you need to change number to date like this Y-m-d such as: 1991-11-20, this is MySQL date format, or you need to change MySQL field type to int if you need to save this number in database.
In PHP:
echo date('Y-m-d');
And you can convert date from unix by this:
$unixtime = 1307595105;
echo $time = date("Y-m-d", $unixtime);
for your example:
$profile->birth_date = date("Y-m-d", ($rowData[0][2] - 25569) * 86400);
OR
$profile->birth_date = date('Y-m-d', PHPExcel_Shared_Date::ExcelToPHP($rowData[0][2]));
I am working on staff attendance. User can upload an attendance sheet and my system will give the view of attendance excel sheet to user and then he can save it to database. The values from excel sheet saving successfully in database.
The problem is user can add record in columns of excel sheet in any format but when I get in PHP the date format goes wrong.
e.g.
when user add attendance date in column, the format of column is date and when he can save in out time it may be number format and when user upload this excel sheet, the date preview gone in unix time stamp.
Here is examples in images
Date in Excel sheet
Time in and out in excel sheet
When user go to site and upload this excel sheet
Then a popup window open
Then user browses the excel sheet and then I show the excel sheet view, that viewing wrong
You can see in above image that the date is being converted in unix time stamp and time in and out in numeric.
I want this view when a user can upload an excel sheet.
So hope you understand my issue and what I want.
Here is my upload and view excel sheet code:
$excel_file = $_FILES['file']['name'];
$target = SERVERPATH . 'assets/attendance_excel/';
$ext = pathinfo($excel_file, PATHINFO_EXTENSION);
$filename = rand() . date("YmdHis");
move_uploaded_file($_FILES['file']['tmp_name'], $target . $filename . '.' . $ext);
include(EXCEL_CLASS);
$inputFileName = $target . $filename . '.' . $ext;
// chmod($inputFileName,0777);
try {
$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
} catch (Exception $e) {
die('Error loading file "' . pathinfo($inputFileName, PATHINFO_BASENAME) . '": ' . $e->getMessage());
}
$objWorksheet = $objPHPExcel->getActiveSheet();
// $objWorksheet->getStyle('A1:E433')->getNumberFormat()->setFormatCode('Text');
$highestRow = $objWorksheet->getHighestRow(); // e.g. 10
$highestColumn = $objWorksheet->getHighestDataRow();
$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F'
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5
$td_data = '';
$row_no = 0;
for ($row = 1; $row <= $highestRow; ++$row) {
$check_empty_column = 0;
for ($col = 0; $col <= $highestColumnIndex; ++$col) {
if ($objWorksheet->getCellByColumnAndRow($col, $row)->getValue() == null) {
$check_empty_column++;
}
}
if ($check_empty_column < $highestColumnIndex) {
for ($col = 0; $col < $highestColumnIndex; ++$col) {
$td_data .= '<td>' . $objWorksheet->getCellByColumnAndRow($col, $row)->getValue() . '</td>';
}
}
$tr_data[$row_no] = $td_data;
$td_data = '';
$row_no++;
}
$data_all = array(
'data' => $tr_data,
't_col' => $highestColumnIndex,
'name' => $filename . '.' . $ext
);
echo json_encode($data_all);
I also search a lot about this and found something like this setFormatCode, PHPExcel_Style_NumberFormat::FORMAT_GENERAL etc but its not working for me. I try my best.
So please give me solution for this problem.
Note: I can not restrict a user that he convert the columns and than add data.
Hope you understand my question
MS Excel stores dates as a float value, a serialized timestamp, the number of days since 1st January 1900 (or 1st January 1904 if the file is using the Mac Calendar), and it is the number format mask for the cell that displays it as a formatted date.
PHPExcel provides a series of methods for converting between that MS Exce serialized timestamp and unix timestamps or PHP DateTime objects
$unixTimestamp = PHPExcel_Shared_Date::ExcelToPHP($excelTimestampValue);
will convert the MS Excel timestamp to a Unix timestamp
$phpDateTimeObject = PHPExcel_Shared_Date::ExcelToPHPObject($excelTimestampValue);
will convert the MS Excel timestamp to a PHP DateTime object
And you can then use PHP's standard date() function or the DateTime object's format() method to format that value however you like.
$excelTimestamp = PHPExcel_Shared_Date::ExcelToPHPObject($phpDateTimeObject);
$excelTimestamp = PHPExcel_Shared_Date::ExcelToPHPObject($unixTimestamp);
will convert either a unix timestamp or a PHPP DateTime object to an MS Excel serialized timestamp value
If you want to change the way that an MS Excel serialized timestamp is displayed in a spreadsheet, then you need to use an Excel format mask that corresponds too a date/time mask.... PHPExcel_Style_NumberFormat::FORMAT_GENERAL is not a format mask for dates/times
I need to save a date to Excel file, it must be output in format "dd/mm/yyyy" (or the local date format of the user), and to be treated as a date so a column of them could be sorted correctly.
Here is the code:
<?php
include_once("../PHPExcel/Classes/PHPExcel.php");
date_default_timezone_set('Europe/London');
$objPHPExcel = new PHPExcel();
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
$objPHPExcel = new PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
//I didn't find dd/mm/yyyy format, so I used yyyy-mm-dd
$sheet->setCellValueByColumnAndRow(0, 1, "2014-10-16");
$sheet->getStyleByColumnAndRow(0, 1)
->getNumberFormat()->setFormatCode(
PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2
);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save("test.xlsx");
It creates a file, but instead of my local date format I see: "2014-10-16" and the format of the cell is "All formats" -> "yyyy-mm-dd". I wanted it to be parsed and output in my local date format.
I looked into the source code of PHPExcel/Classes/PHPExcel/Style/NumberFormat.php, and found many date formats:
const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd';
const FORMAT_DATE_YYYYMMDD = 'yy-mm-dd';
const FORMAT_DATE_DDMMYYYY = 'dd/mm/yy';
const FORMAT_DATE_DMYSLASH = 'd/m/y';
const FORMAT_DATE_DMYMINUS = 'd-m-y';
...
But I am not sure what to use. How can I achieve the desired goal?
$sheet->setCellValueByColumnAndRow(0, 1, "2014-10-16");
Sets a string value in the cell, not a date. Just because you interpret that as a date, doesn't mean that computer programs automagically interpret it as a date.
Look at the date Examples in the PHPExcel Documentation and Examples, and you'll see that you need to set the cell value to a MS Excel serialized timestamp (a float value of the number of days since 1st January 1900). You can use the PHPExcel functions like PHPExcel_Shared_Date::PHPToExcel() to convert human dates/PHP DateTime objects/Unix timestamps to MS Excel Serialized timestamps.
$sheet->setCellValueByColumnAndRow(0, 1, PHPExcel_Shared_Date::PHPToExcel( '2014-10-16' ));
Once you've stored the value as a timestamp, you can then apply whatever date format mask you want to that cell to get your desired formatting
This code generates 4 cells in date format.
<?php
include_once("../PHPExcel/Classes/PHPExcel.php");
date_default_timezone_set('Europe/London');
$objPHPExcel = new PHPExcel();
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
$objPHPExcel = new PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
$format = 'dd/mm/yyyy';
for ($i = 1; $i < 5; ++$i)
{
$date = new DateTime('2016-12-0'.$i);
$sheet->setCellValueByColumnAndRow(0, $i,
PHPExcel_Shared_Date::PHPToExcel( $date ));
$sheet->getStyleByColumnAndRow(0, $i)
->getNumberFormat()->setFormatCode($format);
}
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save("test.xlsx");
I am using phpexcel to import excel document to website. I have problem with getting Date format.
Date format is dd.mm.Y but after getting cellValue I get samo random numbers ( float(42391) )
This is my code:
$datum = $objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue();
this shoud get date?
$file_name = clean_uri($_FILES['excel']['name']);
$file_name = 'povijest_'.$file_name;
$folder_s = 'upload_data/excel';
move_uploaded_file($_FILES['excel']['tmp_name'], '../'.$folder_s.'/'.$file_name);
$objPHPExcel = PHPExcel_IOFactory::load('../'.$folder_s.'/'.$file_name);
$allDataInSheet = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
$highestColumm = $objPHPExcel->getActiveSheet()->getHighestColumn();
$colNumber = PHPExcel_Cell::columnIndexFromString($highestColumm);
$arrayCount = count($allDataInSheet);
for($i=4;$i<=$arrayCount;$i++){
$datum = $objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue();
$prva = $objPHPExcel->getActiveSheet()->getCell('C'.$i)->getValue();
$zadnja = $objPHPExcel->getActiveSheet()->getCell('D'.$i)->getValue();
$najvisa = $objPHPExcel->getActiveSheet()->getCell('E'.$i)->getValue();
$najniza = $objPHPExcel->getActiveSheet()->getCell('F'.$i)->getValue();
$prosjecna = $objPHPExcel->getActiveSheet()->getCell('G'.$i)->getValue();
$promjena = $objPHPExcel->getActiveSheet()->getCell('H'.$i)->getValue();
$broj_transakcija = $objPHPExcel->getActiveSheet()->getCell('I'.$i)->getValue();
$kolicina = $objPHPExcel->getActiveSheet()->getCell('J'.$i)->getValue();
$promet = $objPHPExcel->getActiveSheet()->getCell('K'.$i)->getValue();
var_dump($datum);
exit;
It does get the date..... that isn't a random number, that's an MS Excel serialized datetime stamp. In the same way that you might use a unix timestamp in PHP, and then use the date() function to format that, MS Excel uses its own timestamp value, which is a count of the number of days since 1st January 1900 (or 1st January 1904 if created on a Mac). To display it formatted, you need to apply a number format mask.
The Cell's getValue() method will return the raw value from the cell, but getFormattedValue() will return the value with the number format mask applied
There are also documented methods (e.g. PHPExcel_Shared_Date::ExcelToPHP($msExcelSerializedTimestamp)
) for converting between the MS Excel timestamp and unix timestamp or DateTime objects, and for checking whether a cell contains a date or not
I am trying to get Date from excel using PHPExcel. But I am not getting date, I am getting string value which is not seconds from 1970 .
Code I have tried is
$InvDate=trim($excel->getActiveSheet()->getCell('B' . $i)->getValue());
Try use
$cell = $excel->getActiveSheet()->getCell('B' . $i);
$InvDate= $cell->getValue();
if(PHPExcel_Shared_Date::isDateTime($cell)) {
$InvDate = date($format, PHPExcel_Shared_Date::ExcelToPHP($InvDate));
}
P.S.
#DiegoDD: Should mention that $format is the desired format for the date. e.g.:
$InvDate = date($format = "Y-m-d", PHPExcel_Shared_Date::ExcelToPHP($InvDate));
P.P.S.
2019
Look at answer #gabriel-lupu, with new version of PhpOffice
https://stackoverflow.com/a/45070205/426533
For a date, getValue() should return a float, which is the Excel serialized timestamp value for that date/time... I suspect it's your trim() that's casting it to string. The actual value is the number of days since 1/1/1900 (or 1/1/1904 depending on the calendar that the spreadsheet is using).
Calling getFormattedValue() or getCalculatedValue() instead of getValue() should return the date formatted as a human-readable string according to the numberformatmask of the cell.
Alternatively, Sergey's solution tests if the cell has a date/time numberformatmask and calls the appropriate helper method to convert that Excel serialized timestamp to a unix timestamp, then uses the normal PHP date function to format it as human readable according to the value of $format. There's a similar helper method PHPExcel_Shared_Date::ExcelToPHPObject() that will convert an Excel serialized timestamp to a PHP DateTime object
In the new version of the library, PhpOffice, the function that handles this is excelToDateTimeObject so the new code format should be:
$cell = $excel->getActiveSheet()->getCell('B' . $i);
$InvDate= $cell->getValue();
if (PhpOffice\PhpSpreadsheet\Shared\Date::isDateTime($cell)) {
$InvDate = PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($InvDate);
}
You can get the cell values as string (also the date values) this way:
$sheet = $objPHPExcel->getActiveSheet();
$lastRow = $sheet->getHighestRow();
$lastColumn = $sheet->getHighestColumn();
$rows = $sheet->rangetoArray('A2:'.$lastColumn . $lastRow, NULL, True, True, False);
foreach ($rows as $row => $cols) {
foreach($cols as $col => $cell) {
echo trim($cell).'<br>'; // Gives the value as string
}
}
$cell = $excel->getActiveSheet()->getCell('B' . $i);
$InvDate= $cell->getValue();
$InvDate= PHPExcel_Shared_Date::ExcelToPHPObject($InvDate)->format('Y-m-d H:i:s');
Try this