Laravel-excel: [バグ]日付フィールドがインポートされません

作成日 2020年03月10日  ·  14コメント  ·  ソース: Maatwebsite/Laravel-Excel

前提条件

  • [Х] Laravel Excelのバージョンがまだサポートされているかどうかを確認しました: https
  • [Х]コードの外部で動作を再現できるため、問題はLaravelExcelに限定されます。
  • [Х]問題がまだ提出されていないことを確認しました。
  • [Х]この問題を修正するPRが提出されていないかどうかを確認しました。
  • [Х]課題テンプレート全体に記入

バージョン

  • PHPバージョン:7.2.19
  • Laravelバージョン:6.17.1
  • パッケージバージョン:3.1

説明

created_atフィールドはデータベースにインポートされません。 代わりに、phpmyadminに1970-01-01が表示されます

再現する手順

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

最も参考になるコメント

日付列を日付としてフォーマットするときにCarbonを取得するには: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

全てのコメント14件

モデルでcreated_atを入力できますか?

はい。 すべてのフィールドに入力できます

dd()を試して、そこに何があるかを確認してください。

遅くなってすみません。 私は休暇中でした。
ここにddを入れます

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

ページに奇妙な日付の出力が表示されます

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

私のExcelではそのような日付があります
date

何か案が?

問題が見つかりました。
私は置くdd($row)前に、 News::createとExcelから何が来るのか確認してください。
そしてまた41767を見ました。
次に、Excelに移動し、 created_atフィールドのフォーマットを確認します。 日付でした。 しかし、フォーマットを日付からテキストにすぐに変更すると、41767が表示されます。
そうすることで、インポートする前に、Excelのすべての日付がテキストに変換されることを理解しました。
そこで、これらのフィールドを手動でテキストに変換し、中に日付を入れれば、機能するようになりました。

インポートに成功したのは一度だけで、それでもまだ問題があり、理解できません。
日付をインポートするのは頭痛の種です。 いつも効いているルールが見えません。

インポートする前にExcelで日付を保持する方法を数回テストしましたが、動作が安定していません。

私はすべての日付フィールドをフォーマット=テキストをExcelで作成します。
日付08-05-2014を入力し、テキストとしてフォーマットすると。
とにかくインポート中にエラーが発生しました

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

\ vendor \ nesbot \ carbon \ src \ Carbon \ Traits \ Creatorを指しています。 php:623

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

しかし、 dd($row)を実行すると、

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

なにが問題ですか?

私は解決策を見つけたようです。
唯一の有効な方法は、日付2014-05-08をExcelで保持し、テキストとしてフォーマットすることです。
この順序でMySQL = YYYY-MM-DDに保存されるため
これらのいずれも機能していません
2014年8月5日-間違った順序
2014年5月8日-区切り文字と順序が間違っています
2014.05.08-区切り文字が間違っています

私の場合、Excelで日付としてフォーマットされた日付フィールドの場合、日付2014-05-08はインポート前に常に41767に変換されていました。 理由はわかりません。
日付からタイムスタンプへのコンバーターを試しましたが、
2014-05-08 = 1399507200。
2014年8月5日= 1407182400

41767を取得できる唯一の方法は、Excelの数式=text(08.05.2014;0)を試したときです。
ですから、Excelで変換されていると思います。
また、日付フィールドをYYYY-MM-DD形式に調整しても変換されます。

したがって、有効な解決策は、YYYY-MM-DDテキストを含むテキスト形式のみです。
この解決策が完全に正しくない場合は、私を訂正してください。

私は同じ問題を抱えています。 'date'フィールドは、値ではなく数値(ref、私は推測しますか?)を返します。

日付列を日付としてフォーマットするときにCarbonを取得するには: Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date:: excelToDateTimeObject($row['created_at']))

空でないフィールドで機能します。 ただし、インポートスクリプトが空のフィールドに到達すると、次のエラーで停止します。
この問題はLaravel7でのみ発生します。Laravel6ではこの問題は発生しません。

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

何をすべきか?
インポート内でIF句を使用することはできません

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

エラーsyntax error, unexpected 'if' (T_IF), expecting ']'が発生します

それを一時変数に入れます

「一時変数」とはどういう意味ですか?

許容できる解決策を見つけました

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

          }

        }
このページは役に立ちましたか?
0 / 5 - 0 評価