Laravel Excel maatwebsite 3.1导入,excel单元格中的日期列返回为未知格式编号。如何解决呢?

时间:2019-03-28 04:58:49

标签: php laravel maatwebsite-excel

通过使用Maatwebsite / Laravel-Excel 3.1版导入excel工作表,在这里我面临Excel工作表的发布日期时间列返回未知数字的问题。如何解决呢?示例:考虑单元格值“ 29/07/1989”,并在导入时返回“ 32178”。

5 个答案:

答案 0 :(得分:2)

根据 Skyrem Brilliant 的 @skyrem-brilliant 回答,我是这样解决的:

<?php

//...

class YourExcelImport implements OnEachRow, WithValidation, WithHeadingRow
{
   // ...

    /**
     * Tweak the data slightly before sending it to the validator
     * @param $data
     * @param $index
     * @return mixed
     */
    public function prepareForValidation($data, $index)
    {
        //Fix that Excel's numeric date (counting in days since 1900-01-01)
        $data['your_date_column'] = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($data['your_date_column'])->format('Y-m-d');
        //...
    }

    /**
     * List the validation rules
     * @return array
     */
    public function rules(): array
    {
        return [
            'your_date_column'=>'required|date_format:Y-m-d',
            //..
        ];
    }
}
?>

成功了,验证通过了。

答案 1 :(得分:1)

  

数字来自excel本身,日期以数字形式存储在excel中   价值观。 http://www.cpearson.com/excel/datetime.htm

     

对于Laravel Framework 5.6和maatwebsite / excel软件包版本3.1,   要将日期从Excel数字转换为正常日期格式,这   功能   PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($dateFromExcel)   可以使用。它接受整数(excel日期)并返回DateTime   对象。

     

更多信息可以在这里找到   https://github.com/Maatwebsite/Laravel-Excel/issues/1832

从此答案开始:https://stackoverflow.com/a/55139981/9133724

答案 2 :(得分:0)

解决了!这是我用来解决问题的代码:

Carbon\Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value));

答案 3 :(得分:0)

我尝试了上述解决方案,但总是遇到非数值错误

我设法用

解决了这个问题

$date = intval($row['value]);

\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date)->format('d/m/Y')

答案 4 :(得分:0)

“未知数字”是一个Excel时间戳,因此它在内部存储了日期和时间数据。

例如:

123213.0: it's just a date
213233.1233: is a date and time
0.1233: it's one hour

如果您可以映射单元格,并且知道哪一列将始终具有日期/时间/日期时间,则可以使用映射的单元格或对其进行手动转换,请参见:https://stackoverflow.com/a/59049044

否则,如果您需要动态地解决datetime字段,我编写了一种方法,该方法负责自动检测该值是否为动态datetime(无论您是否知道该列中是否有datetime)或我尝试了各种数据类型,但效果很好

   /**
 * @param Cell $cell
 * @param $value
 * 
 * @return boolean;
 */
public function bindValue(Cell $cell, $value)
{
    $formatedCellValue = $this->formatDateTimeCell($value, $datetime_output_format = "d-m-Y H:i:s", $date_output_format = "d-m-Y", $time_output_format = "H:i:s" );
    if($formatedCellValue != false){
        $cell->setValueExplicit($formatedCellValue, DataType::TYPE_STRING);
        return true;
    }

    // else return default behavior
    return parent::bindValue($cell, $value);
}


/**
 * 
 * Convert excel-timestamp to Php-timestamp and again to excel-timestamp to compare both compare
 * By Leonardo J. Jauregui ( @Nanod10 | siskit dot com )
 * 
 * @param $value (cell value)
 * @param String $datetime_output_format
 * @param String $date_output_format
 * @param String $time_output_format
 * 
 * @return $formatedCellValue
 */
private function formatDateTimeCell( $value, $datetime_output_format = "Y-m-d H:i:s", $date_output_format = "Y-m-d", $time_output_format = "H:i:s" )
{

    // is only time flag
    $is_only_time = false;
    
    // Divide Excel-timestamp to know if is Only Date, Only Time or both of them
    $excel_datetime_exploded = explode(".", $value);

    // if has dot, maybe date has time or is only time
    if(strstr($value,".")){
        // Excel-timestamp to Php-DateTimeObject
        $dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
        // if Excel-timestamp > 0 then has Date and Time 
        if(intval($excel_datetime_exploded[0]) > 0){
            // Date and Time
            $output_format = $datetime_output_format;
            $is_only_time = false;
        }else{
            // Only time
            $output_format = $time_output_format;
            $is_only_time = true;
        }
    }else{
        // Only Date
        // Excel-timestamp to Php-DateTimeObject
        $dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
        $output_format = $date_output_format;
        $is_only_time = false;
    }
        
    // Php-DateTimeObject to Php-timestamp
    $phpTimestamp = $dateTimeObject->getTimestamp();

    // Php-timestamp to Excel-timestamp
    $excelTimestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $phpTimestamp );
        
    // if is only Time
    if($is_only_time){
        // 01-01-1970 = 25569
        // Substract to match PhpToExcel conversion
        $excelTimestamp = $excelTimestamp - 25569;
    }

    /* 
    // uncoment to debug manualy and see if working
    $debug_arr = [
            "value"=>$value,
            "value_float"=>floatval($value),
            "dateTimeObject"=>$dateTimeObject,
            "phpTimestamp"=>$phpTimestamp,
            "excelTimestamp"=>$excelTimestamp,
            "default_date_format"=>$dateTimeObject->format('Y-m-d H:i:s'),
            "custom_date_format"=>$dateTimeObject->format($output_format)
        ];
        
    if($cell->getColumn()=="Q"){
        if($cell->getRow()=="2"){
            if(floatval($value)===$excelTimestamp){
                dd($debug_arr);
            }
        }
    }

    */
    
    // if the values match
    if( floatval($value) === $excelTimestamp ){
        // is a fucking date! ;)
        $formatedCellValue = $dateTimeObject->format($output_format);
        return $formatedCellValue;
    }else{
        // return normal value
        return false;
    }
    
}