created_at
campo não é importado no banco de dados. Em vez disso, vejo 01/01/1970 no phpmyadmin
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>');
}
}
O created_at pode ser preenchido no seu modelo?
sim. Eu tenho todos os campos preenchíveis
Tente dd () e veja o que está lá.
Desculpe pelo atraso. Eu estava de férias.
Eu coloquei 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);
}
e vejo saída de data estranha na página
Illuminate\Support\Collection {#1986 ▼
#items: array:14 [▼
"category_id" => 4
.......
"published_at" => null
"created_at" => 41767
]
}
no meu excel eu tenho data assim
qualquer ideia?
Eu encontrei o problema.
Eu coloco dd($row)
antes de News::create
e verifico o que vem do Excel.
E eu vi 41767 novamente.
Então eu vou para o Excel e verifico a formatação do campo created_at . Era um encontro. Mas quando mudo o formato da data para o texto, vejo imediatamente 41767.
Fazendo isso entendi que antes de importar todas as datas no excel são convertidas em texto.
Então, converti esses campos em texto manualmente, coloquei as datas dentro e agora funciona.
Só uma vez consegui fazer a importação com sucesso e ainda tenho alguns problemas, que não consigo entender.
É dor de cabeça importar datas. Não consigo ver regra, que funciona sempre.
Testei algumas vezes como devo manter a data no Excel antes de importar e não vejo um comportamento estável.
Eu faço todos os campos de data format = text no excel.
Quando coloco a data 08-05-2014
e o formato como texto.
De qualquer forma, tenho erro durante a importação
Unexpected data found.
Unexpected data found.
Data missing
http://localhost.test/admin/seed
apontando para \ vendor \ nesbot \ carbon \ src \ Carbon \ Traits \ Creator. php: 623
if (static::isStrictModeEnabled()) {
throw new InvalidArgumentException(implode(PHP_EOL, $lastErrors['errors']));
}
Mas quando faço dd($row)
vejo
"created_at" => "08-05-2014"
O que está errado?
Parece que encontrei solução.
A única maneira de trabalhar é manter a data 2014-05-08
no Excel e formatar como texto.
Porque nesta ordem ele é armazenado em MySQL = YYYY-MM-DD
Qualquer um desses não está funcionando
08-05-2014 - pedido errado
08/05/2014 - delimitador errado e ordem errada
08/05/2014 - delimitador incorreto
Se os campos de data formatados como data no Excel, no meu caso, a data 2014-05-08 sempre foi convertida para 41767 antes da importação. Não sei por quê.
Eu tentei conversor de data para carimbo de data / hora e ele me deu
08/05/2014 = 1399507200.
05/08/2014 = 1407182400
A única maneira de obter 41767 é quando experimentei a fórmula do Excel =text(08.05.2014;0)
Suponho que seja convertido pelo Excel.
E é convertido mesmo se eu ajustar o campo de data para o formato AAAA-MM-DD.
Portanto, a única solução que funciona é o formato de texto com o texto AAAA-MM-DD dentro.
Corrija-me se esta solução não estiver totalmente certa.
Estou tendo o mesmo problema. Os campos de 'data' estão retornando um número (a ref, eu acho?) E não o valor.
Para obter Carbon ao ter a coluna de data formatada como uma data: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))
Funciona para campos não vazios. Mas quando o script de importação atinge o campo vazio, ele para com o seguinte erro.
Este problema só aparece no Laravel 7. Com o Laravel 6 não tenho esse 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 ...
O que fazer?
A cláusula IF não é possível dentro da importação
if (empty($row['published_at'])) {
'published_at' => $row['published_at'],
} else {
'published_at' => Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['published_at'])),
}
Ele dá o erro syntax error, unexpected 'if' (T_IF), expecting ']'
Coloque-o em uma variável temporária
o que você quer dizer com "variável temporária"?
Eu encontrei uma solução aceitável
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,
]);
}
}
Comentários muito úteis
Para obter Carbon ao ter a coluna de data formatada como uma data:
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))