Intereting Posts
Ведение позиции полосы прокрутки после перезагрузки страницы Un-define константы с define / apc_define_constants в PHP Разрешение только определенных символов в PHP Как извлечь данные из csv-файла в PHP Подготовленный отчет PDO – синтаксис и дезинфекция нужно регулярное выражение для анализа файла csv с двойными кавычками в php Как добавить свойство к объекту в PHP> = 5.3 строгий режим без генерации ошибки Отменить загрузку больших загрузок после чтения заголовков PHP MVC / ORM Framework, которые являются Hyper PHP (HipHop) Ready Как удалить переменную $ _POST при нажатии кнопки «Обновить» в браузере с помощью PHP? Проверьте, закрыто ли соединение db – php Результаты группы после присоединения? Как обновить раскрывающийся список без обновления страницы? Изменение соединения базы данных во время выполнения в Codeigniter сгладить многомерный массив в текст csv с помощью PHP

PHPEXCEL получает форматированную дату, как видно в файле excel

Я пытаюсь импортировать файл excel, используя PhpExcel lib для всех других полей, getValue() работает, но когда он встречает поле с датой даты, установленной в ms-excel2013, поле даты в exel-файле находится в формате dmY, например, 16-11-2014 но когда я пытаюсь импортировать его значение, getValue() возвращает 11-16-14 который при передаче в strtotime далее returns false в свою очередь, заставляя date('Ym-d',strtotime($date)) возвращать 1970-01-01 .

Я искал всю сеть и stackoverflow, но ни одно решение не устранило мою проблему. В файле excel я вижу дату 16-11-2014 и хочу, чтобы она была импортирована как есть.

Вот код

 protected function importExcel($filePath) { $excelData = array(); if ($filePath) { $objPHPExcel = PHPExcel_IOFactory::load($filePath); $objPHPExcel->setReadDataOnly(true); foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { $worksheetTitle = $worksheet->getTitle(); $highestRow = $worksheet->getHighestRow(); // eg 10 $highestColumn = $worksheet->getHighestColumn(); // eg 'F' $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); $nrColumns = ord($highestColumn) - 64; $data = array(); for ($row = 1; $row <= $highestRow; ++$row) { $values = array(); for ($col = 0; $col < $highestColumnIndex; ++$col) { $cell = $worksheet->getCellByColumnAndRow($col, $row); if (PHPExcel_Shared_Date::isDateTime($cell)) throw new Exception("is date time"); // just a check $val = $cell->getValue(); if (isset($val) && $val) $data[$row][$col] = $val; } } $excelData[$worksheetTitle] = $data; } return $excelData; } return FALSE; } 

Вот файл
заранее спасибо

getValue() в поле, содержащем дату, должен возвращать значение, например, 41959.00 если это поле действительно содержит значение даты MS Excel …. то есть штамп даты и времени MS Excel, основанный на количестве дней с 1 января 1900 (или 1 января 1904 года, если файл был создан с использованием Mac версии MS Excel)

Чтобы получить форматированную строку даты, вам нужно вместо этого вызвать getFormattedValue() ; и PHPExcel затем использует маску формата номера для этой ячейки для форматирования даты в соответствии с этой маской.

Чтобы определить, содержит ли ячейка MS-сериализованную PHPExcel_Shared_Date::isDateTime() , вы можете сначала вызвать вызов PHPExcel_Shared_Date::isDateTime() .

 foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { echo 'Worksheet - ' , $worksheet->getTitle() , EOL; foreach ($worksheet->getRowIterator() as $row) { echo ' Row number - ' , $row->getRowIndex() , EOL; $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set foreach ($cellIterator as $cell) { if (!is_null($cell)) { echo ' Cell - ' , $cell->getCoordinate() , ' - '; if (PHPExcel_Shared_Date::isDateTime($cell)) { echo $cell->getFormattedValue() , EOL; } else { echo $cell->getValue() , EOL; } } } } } 

Вместо того, чтобы возвращать форматированное значение данных, вы также можете попросить PHPExcel вернуть дату как временную метку Unix или вместо объекта PHP DateTime; и тогда вы сможете отформатировать его, но вы хотите использовать встроенные функции даты PHP или методы DateTime.

 if (PHPExcel_Shared_Date::isDateTime($cell)) { $unixTimeStamp = PHPExcel_Shared_Date::ExcelToPHP($cell->getValue()); echo date('dMY H:i:s', $unixTimeStamp), PHP_EOL; } 

или

 if (PHPExcel_Shared_Date::isDateTime($cell)) { $dateTimeObject = PHPExcel_Shared_Date::ExcelToPHPObject($cell->getValue()); echo $dateTimeObject->format('dMY H:i:s'), PHP_EOL; } 

Я проверил файл, который вы предоставили, глядя на вопрос о дате.

Формат, который вы используете для этих дат в вашей таблице, представляет собой формат даты, соответствующий значению даты, помеченный MS Excel звездочкой (*), если вы посмотрите на формат ячейки

Это означает (цитирование из заметок Excel на дисплее маски формата):

Форматы даты, начинающиеся со звездочки (*), реагируют на изменения региональных настроек даты и времени, которые указаны для операционной системы.

Поскольку PHPExcel не является локальным, но распознает маску формата как значение даты, он использует общее форматирование.


Выполнение следующего кода

 var_dump($objPHPExcel->getActiveSheet()->getCell('I5')->getValue()); var_dump(PHPExcel_Shared_Date::isDateTime($objPHPExcel->getActiveSheet()->getCell('I5'))); var_dump($objPHPExcel->getActiveSheet()->getCell('I5')->getStyle()->getNumberFormat()->getFormatCode()); var_dump($objPHPExcel->getActiveSheet()->getCell('I5')->getFormattedValue()); 

дает

 float(42062) bool(true) string(8) "mm-dd-yy" string(8) "02-27-15" 

Таким образом (пока вы удалили setReadDataOnly(true) из Reader, позвоните из Reader, вы все равно можете определить ячейки даты как даты и отформатировать их вручную, переопределяя стандартное языковое форматирование

 if (PHPExcel_Shared_Date::isDateTime($objPHPExcel->getActiveSheet()->getCell('I5'))) { $dateTimeObject = PHPExcel_Shared_Date::ExcelToPHPObject($objPHPExcel->getActiveSheet()->getCell('I5')->getValue()); echo $dateTimeObject->format('dm-Y'), PHP_EOL; } 

Я нашел решение:

Метод _formatAsDate в файле PHPExcel / Style / NumberFormat.php

Метод _formatAsDate в NumberFormat.php

если дата подобна 16/11/2014 , при передаче в strtotime результат будет false как дата должна быть в формате m/d/Y по strtotime . Поэтому, если вы измените формат на m/d/Y если это d/m/Y тогда решение всегда будет правильным.

Ранее:

  1. 16/11/2014 == 1970-01-01 (строка: 1)
  2. 16/11/2014 == 1970-01-01 (строка: 2)
  3. 23/12/2014 == 1970-01-01 (строка: 3).

Теперь:

  1. 11/16/2014 == 2014-11-16 (строка: 1)
  2. 11/16/2014 == 2014-11-16 (строка: 2)
  3. 12/23/2014 == 2014-12-23 (строка: 3)

Код все тот же и простой для импорта файла:

 protected function importExcel($filePath) { $excelData = array(); if ($filePath) { $objPHPExcel = PHPExcel_IOFactory::load($filePath); foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { $worksheetTitle = $worksheet->getTitle(); $highestRow = $worksheet->getHighestRow(); // eg 10 $highestColumn = $worksheet->getHighestColumn(); // eg 'F' $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); $nrColumns = ord($highestColumn) - 64; $data = array(); for ($row = 1; $row <= $highestRow; ++$row) { $values = array(); for ($col = 0; $col < $highestColumnIndex; ++$col) { $cell = $worksheet->getCellByColumnAndRow($col, $row); $val = $cell->getValue(); if (isset($val) && $val) $data[$row][$col] = $val; } } $excelData[$worksheetTitle] = $data; } return $excelData; } return FALSE; }