6
votes

Importation de Laravel Excel maatwebsite 3.1, la colonne de date dans la cellule Excel renvoie un numéro de format inconnu. Comment résoudre ça?

En utilisant Maatwebsite / Laravel-Excel version 3.1 pour importer une feuille Excel, je me suis retrouvé ici face à une colonne de date et heure de problème de la feuille Excel renvoie un nombre inconnu. Comment résoudre ça? Exemple: considérez la valeur de cellule "29/07/1989" et renvoie la valeur "32178" lors de l'importation.


1 commentaires

s'il vous plaît voir cette réponse stackoverflow.com/questions/37044353/...


4 Réponses :


17
votes

Les nombres proviennent d'Excel lui-même, des dates stockées dans Excel sous forme de valeurs numériques. http://www.cpearson.com/excel/datetime.htm

Pour le framework Laravel 5.6 et le package maatwebsite / excel version 3.1, pour convertir la date des nombres Excel au format de date normal, cette fonction PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($dateFromExcel) peut être utilisée. Il accepte un entier (date excel) et renvoie un objet DateTime.

Plus d'informations peuvent être trouvées ici https://github.com/Maatwebsite/Laravel-Excel/issues/1832

De cette réponse: https://stackoverflow.com/a/55139981/9133724


2 commentaires

merci, j'utilise ce code pour résoudre le problème Carbon \ Carbon :: instance (\ PhpOffice \ PhpSpreadsheet \ Shared \ Dat‌ e :: excelToDateTimeOb‌ ject ($ value));


ne fonctionne pas si votre première ligne dans Excel ou CSV est le nom de la colonne



12
votes

Résolu! Voici le code que j'ai utilisé pour résoudre mon problème:

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


0 commentaires

0
votes

J'ai essayé la solution ci-dessus mais je reste toujours bloqué avec une erreur de valeur non numérique

J'arrive à résoudre ce problème en utilisant


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

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


0 commentaires

0
votes

Ce "nombre inconnu" est un horodatage Excel, de cette façon, il stocke les données de date et d'heure en interne.

par exemple:

   /**
 * @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;
    }
    
}

Si vous pouvez mapper la cellule et que vous savez quelle colonne aura toujours une date / heure / date-heure, vous pouvez utiliser des cellules mappées ou la convertir manuellement, voir: https://stackoverflow.com/a/59049044

Sinon, si votre besoin implique la résolution dynamique des champs datetime, j'ai écrit une méthode qui est responsable de la détection automatique si la valeur est une datetime dynamiquement (que vous sachiez ou non s'il y aura un datetime dans cette colonne) ou j'ai essayé différents types de données et cela fonctionne bien

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


0 commentaires