created_at
champ
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>');
}
}
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
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,
]);
}
}
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']))