PHPEXCEL获取excel文件中可见的格式化日期

PHPEXCEL获取excel文件中可见的格式化日期,php,phpexcel,Php,Phpexcel,我正在尝试使用phpexcellib导入excel文件 对于所有其他字段,getValue()函数起作用,但当遇到ms-excel2013中设置了格式日期的字段时 exel文件中的日期字段采用d-m-Y格式,如2014年11月16日 但是当我尝试导入它的值时,getValue()返回11-16-14,当传递到strotime时,进一步返回false反过来导致日期('Y-m-d',strotime($date))返回1970-01-01 我搜索了整个web和stackoverflow,但没有一个解

我正在尝试使用phpexcellib导入excel文件 对于所有其他字段,
getValue()
函数起作用,但当遇到ms-excel2013中设置了格式日期的字段时 exel文件中的日期字段采用d-m-Y格式,如2014年11月16日 但是当我尝试导入它的值时,
getValue()
返回
11-16-14
,当传递到
strotime
时,进一步
返回false
反过来导致
日期('Y-m-d',strotime($date))
返回
1970-01-01

我搜索了整个web和stackoverflow,但没有一个解决方案解决了我的问题。 在excel文件中,我看到日期为2014年11月16日,希望按原样导入

这是代码

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(); // e.g. 10
            $highestColumn = $worksheet->getHighestColumn(); // e.g '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;
}
受保护的函数importExcel($filePath){
$excelData=array();
if($filePath){
$objPHPExcel=PHPExcel\u IOFactory::load($filePath);
$objPHPExcel->setReadDataOnly(true);
foreach($objPHPExcel->getWorksheetIterator()作为$worksheet){
$worksheetTitle=$worksheet->getTitle();
$highestRow=$worksheet->getHighestRow();//例如10
$highestColumn=$worksheet->getHighestColumn();//例如'F'
$highestColumnIndex=PHPExcel_单元::columnIndexFromString($highestColumn);
$nrColumns=ord($highestColumns)-64;
$data=array();
对于($row=1;$row getCellByColumnRow($col,$row);

if(PHPExcel_Shared_Date::isDateTime($cell)) 抛出新异常(“是日期时间”);//只是一个检查 $val=$cell->getValue(); 如果(isset($val)和&$val) $data[$row][$col]=$val; } } $excelData[$WORKSHEETTILE]=$data; } 返回$excelData; } 返回FALSE; }
A
getValue()
对包含日期的字段的调用应返回类似于
41959.00
的值,如果该字段确实包含MS Excel日期值……即,基于1900年1月1日起的天数的MS Excel序列化日期时间戳(或1904年1月1日,如果文件是使用Mac版MS Excel创建的)

要获取格式化的日期字符串,需要调用
getFormattedValue()
;然后PHPExcel使用该单元格的数字格式掩码根据该掩码格式化日期


要确定单元格是否包含MS序列化日期时间戳,可以先调用
PHPExcel\u Shared\u 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日期时间对象的形式返回日期,而不是返回格式化的数据值;然后,您可以使用PHP的内置日期函数或日期时间方法以任何方式对其进行格式化

if (PHPExcel_Shared_Date::isDateTime($cell)) {
    $unixTimeStamp = PHPExcel_Shared_Date::ExcelToPHP($cell->getValue());
    echo date('d-M-Y H:i:s', $unixTimeStamp), 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());
给予

因此(只要您已经从读卡器中删除了
setReadDataOnly(true)
调用,从读卡器中调用,您仍然可以将日期单元格标识为日期,并手动格式化,覆盖默认的区域设置格式

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

我找到了解决办法:

文件PHPExcel/Style/NumberFormat.php中的方法_formatAsDate

如果日期类似于2014年11月16日,当传递到
strotime
时,将导致
false
,因为日期应该是
strotime
的格式
m/d/Y
。因此,如果将格式更改为
m/d/Y
,如果是
d/m/Y
,那么解决方案将始终是正确的

早期的:
  • 2014年11月16日==1970-01-01(第1排)
  • 2014年11月16日==1970-01-01(第2排)
  • 2014年12月23日==1970-01-01(第3排)
  • 现在:
  • 2014年11月16日==2014-11-16(第1行)
  • 2014年11月16日==2014-11-16(第2排)
  • 2014年12月23日==2014-12-23(第三排)
  • 代码仍然相同,并且导入文件很简单:

    protected function importExcel($filePath) {
        $excelData = array();
        if ($filePath) {
            $objPHPExcel = PHPExcel_IOFactory::load($filePath);
            foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
                $worksheetTitle = $worksheet->getTitle();
                $highestRow = $worksheet->getHighestRow(); // e.g. 10
                $highestColumn = $worksheet->getHighestColumn(); // e.g '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;
    }
    
    受保护的函数importExcel($filePath){
    $excelData=array();
    if($filePath){
    $objPHPExcel=PHPExcel\u IOFactory::load($filePath);
    foreach($objPHPExcel->getWorksheetIterator()作为$worksheet){
    $worksheetTitle=$worksheet->getTitle();
    $highestRow=$worksheet->getHighestRow();//例如10
    $highestColumn=$worksheet->getHighestColumn();//例如'F'
    $highestColumnIndex=PHPExcel_单元::columnIndexFromString($highestColumn);
    $nrColumns=ord($highestColumns)-64;
    $data=array();
    对于($row=1;$row getCellByColumnRow($col,$row);
    $val=$cell->getValue();
    如果(isset($val)和&$val)
    $data[$row][$col]=$val;
    }
    }
    $excelData[$WORKSHEETTILE]=$data;
    }
    返回$excelData;
    }
    返回FALSE;
    }
    
    PHPExcel\u Shared\u Date::isDateTime($cell)返回false,因此上述建议无效getFormattedValue();该文件是使用windows和MS Excel 2013创建的。您没有使用
    setReadDataOnly(true)加载该文件。
    是吗?我确实加载了
    $objPHPExcel=PHPExcel\u IOFactory::load($filePath)$objPHPExcel->setReadDataOnly(true);
    我发布了上面的代码,请查看并提出建议,因为没有引发异常。@@
    PHPExc
    
    if (PHPExcel_Shared_Date::isDateTime($objPHPExcel->getActiveSheet()->getCell('I5'))) {
        $dateTimeObject = PHPExcel_Shared_Date::ExcelToPHPObject($objPHPExcel->getActiveSheet()->getCell('I5')->getValue());
        echo $dateTimeObject->format('d-m-Y'), PHP_EOL;
    }
    
    protected function importExcel($filePath) {
        $excelData = array();
        if ($filePath) {
            $objPHPExcel = PHPExcel_IOFactory::load($filePath);
            foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
                $worksheetTitle = $worksheet->getTitle();
                $highestRow = $worksheet->getHighestRow(); // e.g. 10
                $highestColumn = $worksheet->getHighestColumn(); // e.g '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;
    }