Laravel-excel: Le champ de date [BUG] n'est pas importé

Créé le 10 mars 2020  ·  14Commentaires  ·  Source: Maatwebsite/Laravel-Excel

Conditions préalables

  • [Х] Vérifié si votre version Laravel Excel est toujours prise en charge: https://docs.laravel-excel.com/3.1/getting-started/support.html#supported -versions
  • [Х] Capable de reproduire le comportement en dehors de votre code, le problème est isolé sur Laravel Excel.
  • [Х] Vérifié que votre problème n'est pas déjà classé.
  • [Х] Vérifié si aucun PR n'a été soumis pour résoudre ce problème.
  • [Х] Rempli le modèle de problème complet

Versions

  • Version PHP: 7.2.19
  • Version de Laravel: 6.17.1
  • Version du paquet: 3.1

La description

created_at champ

Étapes à suivre pour reproduire

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

Commentaire le plus utile

Pour obtenir Carbon lorsque la colonne de date est formatée en tant que date: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

Tous les 14 commentaires

Le fichier created_at est-il remplissable sur votre modèle?

Oui. J'ai tous les champs remplissables

Essayez de dd () et voyez ce qu'il y a dedans.

Désolé pour le retard. J'étais en vacances.
Je mets dd ici

            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);
            }

et je vois une sortie de date étrange sur la page

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

dans mon excel j'ai une date comme ça
date

une idée?

J'ai trouvé un problème.
Je mets dd($row) avant News::create et vérifie ce qui vient d'Excel.
Et j'ai revu 41767.
Ensuite, je vais à Excel et vérifie la mise en forme du champ created_at . C'était une date. Mais quand je change immédiatement le format de la date au texte, je vois 41767.
En faisant cela, j'ai compris qu'avant l'importation, toutes les dates dans Excel sont converties en texte.
J'ai donc converti ces champs en texte manuellement, mis des dates à l'intérieur et cela fonctionne maintenant.

Une fois seulement, j'ai pu effectuer l'importation avec succès et j'ai encore des problèmes que je ne comprends pas.
C'est un casse-tête d'importer des dates. Je ne vois pas la règle, qui fonctionne toujours.

J'ai testé quelques fois comment dois-je garder la date dans Excel avant l'importation et je ne vois pas de comportement stable.

Je fais tous les champs de date format = texte dans Excel.
Quand je mets la date 08-05-2014 et le met en forme sous forme de texte.
Quoi qu'il en soit, j'ai une erreur lors de l'importation

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

pointant sur \ vendor \ nesbot \ carbon \ src \ Carbon \ Traits \ Creator. php: 623

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

Mais quand je fais dd($row) je vois

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

Ce qui est faux?

Il semble que j'ai trouvé une solution.
La seule façon de travailler est de garder la date 2014-05-08 dans Excel et de la mettre en forme sous forme de texte.
Parce que dans cet ordre, il est stocké dans MySQL = AAAA-MM-JJ
L'un de ces éléments ne fonctionne pas
08-05-2014 - mauvais ordre
08.05.2014 - mauvais délimiteur et mauvais ordre
08/05/2014 - mauvais délimiteur

Si les champs de date formatés en tant que date dans Excel dans mon cas, la date du 08/05/2014 a toujours été convertie en 41767 avant l'importation. Je ne sais pas pourquoi.
J'ai essayé le convertisseur date-horodatage et cela me donne
08/05/2014 = 1399507200.
08-05-2014 = 1407182400

La seule façon dont je pourrais obtenir 41767 est d'essayer la formule Excel =text(08.05.2014;0)
Donc je suppose qu'il est converti par Excel.
Et il est converti même si j'ajuste le champ de date au format AAAA-MM-JJ.

La seule solution de travail est donc le format texte avec du texte AAAA-MM-JJ à l'intérieur.
Corrigez-moi si cette solution n'est pas tout à fait la bonne.

J'ai le même problème. Les champs «date» renvoient un nombre (une référence, je suppose?) Et non la valeur.

Pour obtenir Carbon lorsque la colonne de date est formatée en tant que date: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

Cela fonctionne pour les champs non vides. Mais lorsque le script d'importation atteint un champ vide, il s'arrête avec l'erreur suivante.
Ce problème n'apparaît que dans Laravel 7. Avec Laravel 6, je n'ai pas ce problème.

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 ...

Que faire?
La clause IF n'est pas possible dans l'importation

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

Cela donne l'erreur syntax error, unexpected 'if' (T_IF), expecting ']'

Mettez-le dans une variable temporaire

que voulez-vous dire par «variable temporaire»?

J'ai trouvé une solution acceptable

        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,
              ]);             

          }

        }
Cette page vous a été utile?
0 / 5 - 0 notes