Laravel-excel: El campo de fecha [BUG] no se importa

Creado en 10 mar. 2020  ·  14Comentarios  ·  Fuente: Maatwebsite/Laravel-Excel

Prerrequisitos

  • [Х] Verificó si su versión de Laravel Excel todavía es compatible: https://docs.laravel-excel.com/3.1/getting-started/support.html#supported -versions
  • [Х] Capaz de reproducir el comportamiento fuera de su código, el problema está aislado en Laravel Excel.
  • [Х] Verificó que su problema aún no se haya presentado.
  • [Х] Se verificó si no se envió ningún RP que solucione este problema.
  • [Х] Completado en toda la plantilla de problema

Versiones

  • Versión de PHP: 7.2.19
  • Versión de Laravel: 6.17.1
  • Versión del paquete: 3.1

Descripción

created_at no se importa en la base de datos. En cambio, veo 1970-01-01 en phpmyadmin

Pasos para reproducir

namespace App\Imports;

use App\NewsPost;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class NewsImport implements ToCollection, WithHeadingRow

{
    public $rowCount = null;

    public function collection(Collection $rows)
    {
        News::truncate();

        foreach ($rows as $row) 
        { 
          if( !empty($row['category_id'])) {  

            NewsPost::create([

               'category_id'=> $row['category_id'],
               'title'      => $row['title'], 
               'sef'        => $row['sef'], 
               'introtext'  => $row['introtext'], 
               'fulltext'   => $row['fulltext'], 
               'image'      => $row['image'], 
               'metatitle'  => $row['metatitle'], 
               'metakey'    => $row['metakey'], 
               'metadesc'   => $row['metadesc'], 
               'hits'       => $row['hits'], 
               'created_at' => $row['created_at'], 

            ]);
          }

        }

      $this->rowCount = $rows->count();

    }

}
namespace App\Admin\Controllers;

use Illuminate\Support\Facades\DB;
use App\Imports\NewsPostImport;
use Maatwebsite\Excel\Facades\Excel;

class SeedController extends BaseAdminController
{

    public function index(Content $content)
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Excel::import($newsPost     = new NewsPostImport,       'import/news_posts.xlsm');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');

        return $content
            ->title('Import & Export')
            ->description('Laravel excel')
            ->withSuccess('Импорт завершен успешно', 
               '<p>Импортировано '. $newsPost->rowCount.' новостей</p>');
    }

}
bug

Comentario más útil

Para obtener Carbon al tener la columna de fecha formateada como fecha: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

Todos 14 comentarios

¿Se puede rellenar created_at en su modelo?

Si. Tengo todos los campos rellenables

Intente dd () y vea qué hay allí.

lo siento por el retraso. Estaba de vacaciones.
Puse dd aqui

            if (empty($row['slug'])) {
              News::create([
                 'category_id'  => $row['category_id'],
                 'title'        => $row['title'],
                 'slug'         => Str::slug($row['title'], '-'),
                 'fulltext'     => $row['fulltext'],
                 'image'        => $row['image'],
                 'metatitle'    => $row['metatitle'],
                 'metakey'      => $row['metakey'],
                 'metadesc'     => $row['metadesc'],
                 'hits'         => $row['hits'],
                 'published_at' => $row['published_at'],
                 'created_at'   => $row['created_at'],
                 'updated_at'   => $row['updated_at'],
                 'deleted_at'   => $row['deleted_at'],
              ]);
              dd($row);
            }

y veo una salida de fecha extraña en la página

Illuminate\Support\Collection {#1986 ▼
  #items: array:14 [▼
    "category_id" => 4
    .......
    "published_at" => null
    "created_at" => 41767
  ]
}

en mi excel tengo cita asi
date

¿alguna idea?

Encontré un problema.
Pongo dd($row) antes de News::create y compruebo lo que viene de Excel.
Y vi 41767 de nuevo.
Luego voy a sobresalir y verifico el formato del campo
Al hacer eso, entendí que antes de importar todas las fechas en Excel se convierten en texto.
Así que convertí estos campos a texto manualmente, puse fechas dentro y ahora funciona.

Solo una vez pude realizar la importación con éxito y luego todavía tengo algunos problemas, que no puedo entender.
Es un dolor de cabeza importar dátiles. No puedo ver la regla, que funciona siempre.

Probé varias veces cómo debo mantener la fecha en Excel antes de la importación y no veo un comportamiento estable.

Hago que todos los campos de fecha tengan formato = texto en Excel.
Cuando pongo la fecha 08-05-2014 y el formato como texto.
De todos modos tengo un error durante la importación

Unexpected data found.
 Unexpected data found.
 Data missing
http://localhost.test/admin/seed

apuntando a \ vendor \ nesbot \ carbon \ src \ Carbon \ Traits \ Creator. php: 623

        if (static::isStrictModeEnabled()) {
            throw new InvalidArgumentException(implode(PHP_EOL, $lastErrors['errors']));
        }

Pero cuando lo hago dd($row) veo

 "created_at" => "08-05-2014"

¿Qué está mal?

Parece que encontré una solución.
La única forma de trabajo es mantener la fecha 2014-05-08 en Excel y formatearla como texto.
Porque en este orden se almacena en MySQL = YYYY-MM-DD
Cualquiera de estos no funciona
08-05-2014 - orden incorrecta
08.05.2014 - delimitador incorrecto y orden incorrecto
2014.05.08 - delimitador incorrecto

Si los campos de fecha formateados como fecha en Excel, en mi caso, la fecha 2014-05-08 siempre se convertía a 41767 antes de la importación. No sé por qué.
Probé el convertidor de fecha a marca de tiempo y me da
2014-05-08 = 1399507200.
08-05-2014 = 1407182400

La única forma en que pude obtener 41767 es cuando probé en la fórmula de Excel =text(08.05.2014;0)
Así que supongo que Excel lo convierte.
Y se convierte incluso si ajusto el campo de fecha al formato AAAA-MM-DD.

Entonces, la única solución que funciona es el formato de texto con texto YYYY-MM-DD adentro.
Corrígeme si esta solución no es del todo correcta.

Tengo el mismo problema. Los campos de 'fecha' devuelven un número (¿una referencia, supongo?) Y no el valor.

Para obtener Carbon al tener la columna de fecha formateada como fecha: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

Funciona para campos no vacíos. Pero cuando el script de importación llega a un campo vacío, se detiene con el siguiente error.
Este problema aparece solo en Laravel 7. Con Laravel 6 no tengo este problema.

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1970-01-01 00:00:00' for column 'published_at' at row 1 (SQL: insert into `news_posts` (`category_id`, `title`, `slug`, `fulltext`, `image`, `metatitle`, `metakey`, `metadesc`, `hits`, `is_published`, `published_at`, `created_at`, `updated_at`, `deleted_at`) values ...

¿Qué hacer?
La cláusula IF no es posible dentro de la importación

                if (empty($row['published_at'])) { 
                    'published_at' => $row['published_at'],
                } else {
                 'published_at' => Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['published_at'])),
                }

Da error syntax error, unexpected 'if' (T_IF), expecting ']'

Ponlo en una variable temporal

¿Qué quiere decir con "variable temporal"?

Encontré una solución aceptable

        foreach ($rows as $row) 
        {  
          if (!empty($row['category_id'])) {
            $slug = empty($row['slug']) ? Str::slug($row['title'], '-') : $row['slug'];
            $published_at = empty($row['published_at']) ? $row['published_at'] : Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['published_at']));
            $created_at = empty($row['created_at']) ? $row['created_at'] : Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['created_at']));
            $updated_at = empty($row['updated_at']) ? $row['updated_at'] : Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['updated_at']));
            $deleted_at = empty($row['deleted_at']) ? $row['deleted_at'] : Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['deleted_at']));

              NewsPost::create([
                 'category_id'  => $row['category_id'],
                 'title'        => $row['title'],
                 'slug'         => $slug,
                 'fulltext'     => $row['fulltext'],
                 'image'        => $row['image'],
                 'metatitle'    => $row['metatitle'],
                 'metakey'      => $row['metakey'],
                 'metadesc'     => $row['metadesc'],
                 'hits'         => $row['hits'],
                 'is_published' => $row['is_published'],
                 'published_at' => $published_at,
                 'created_at'   => $created_at,
                 'updated_at'   => $updated_at,
                 'deleted_at'   => $deleted_at,
              ]);             

          }

        }
¿Fue útil esta página
0 / 5 - 0 calificaciones