coreproc / nova-data-sync
一款用于从CSV或Excel文件导入和导出数据的Laravel Nova工具。
Requires
- php: ^7.3|^8.0
- anourvalar/eloquent-serialize: ^1.0
- ebess/advanced-nova-media-library: ^4.1
- flatroy/nova-progressbar-field: ^0.0.6
- laravel/horizon: ^5.21
- spatie/laravel-medialibrary: ^10.0|^11.0
- spatie/simple-excel: ^3.3
README
这是一个提供导入和导出CSV文件功能的Laravel Nova工具。
安装
您可以使用Composer将此包安装到使用Nova的Laravel应用程序中。
composer require coreproc/nova-data-sync
发布包的配置和迁移
php artisan vendor:publish --provider="Coreproc\NovaDataSync\ToolServiceProvider"
此包需要Laravel Horizon,并且包含在此包中。如果您尚未完成Horizon的安装过程,可以通过运行以下命令来安装它:
php artisan horizon:install
请确保在config/horizon.php
中配置Horizon的环境进程。
您还应迁移作业批次表
php artisan queue:batches-table php artisan migrate
此包还需要spatie/laravel-media-library,并且包含在此包中。如果您尚未完成Media Library的安装过程,应发布其迁移文件。
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations" php artisan migrate
发布Media Library的配置文件
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-config"
此外,运行以下命令以发布ebess/advanced-nova-media-library的配置文件
php artisan vendor:publish --tag=nova-media-library
用法
将工具添加到您的NovaServiceProvider.php
public function tools() { return [ // ... new \Coreproc\NovaDataSync\NovaDataSync(), ]; }
现在,Nova数据同步工具应出现在Nova的侧边栏中。
使用Nova操作导入数据
要从头开始创建导入功能,您需要创建两个扩展以下类的类:
- 一个包含导入CSV文件每一行验证规则和处理逻辑的
ImportProcess
类。 - 以及一个本质上是Nova操作的
ImportNovaAction
类。
以下是一个ImportProcessor
的示例:
<?php namespace App\Nova\Imports\TestImport; use Coreproc\NovaDataSync\Import\Jobs\ImportProcessor;use Illuminate\Support\Facades\Log; class TestImportProcessor extends ImportProcessor { public static function expectedHeaders(): array { return ['field1', 'field2']; } protected function rules(array $row, int $rowIndex): array { // Use Laravel validation rules to validate the values in each row. return [ 'field1' => ['required'], 'field2' => ['required'], ]; } protected function process(array $row, int $rowIndex): void { Log::info('processing row ' . $rowIndex); // Put the logic to process each row in your imported CSV here } /** * Optional: The number of rows to process per chunk. If not defined, it will use the * default chunk size defined in the config file. */ public static function chunkSize(): int { return 100; } }
rules()
方法用于定义CSV文件每一行的验证规则。它将传递$row
和$rowIndex
参数。$row
参数是CSV行数据的数组。$rowIndex
参数是索引。返回Laravel验证规则的数组。
expectedHeaders()
方法定义了预期的头信息。这用于验证CSV的头信息。
process()
方法用于定义CSV文件每一行的逻辑。它将传递$row
和$rowIndex
参数。$row
参数是CSV行数据的数组。$rowIndex
参数是索引。
如果在process()
方法内部抛出Exception
,则该行将被标记为失败,并且异常消息将显示在导入失败的报告中。
接下来,创建一个ImportNovaAction
类并定义您刚刚创建的$processor
类。
<?php namespace App\Nova\Imports\TestImport; use Coreproc\NovaDataSync\Import\Nova\Actions\ImportNovaAction; class TestImportAction extends ImportNovaAction { // A sample processor will be shown below public string $processor = TestImportProcessor::class; }
然后,将您的ImportNovaAction
放入您的一个Nova资源类的actions()
方法中
public function actions(Request $request) { return [ new TestImportAction(), ]; }
它看起来可能像这样
不使用Nova操作使用导入功能
如果您想在没有任何Nova操作的情况下使用导入功能,您仍然可以使用您的ImportProcessor类。以下是从S3获取文件并导入的示例:
use Coreproc\NovaDataSync\Import\Actions\ImportAction; // Get the file from s3 $file = Storage::disk('s3')->get('file-for-import.csv'); // Put it in your local storage Storage::disk('local')->put('file-for-import.csv', $file); // Get the filepath of the file we just saved $filePath = Storage::disk('local')->path('file-for-import.csv'); try { // Use ImportAction::make() to dispatch the jobs necessary to handle the import ImportAction::make(TestImportProcessor::class, $filePath); } catch (Exception $e) { // Handle exception \Log::error($e->getMessage()); }
这将调度处理导入所需的作业。您还可以在Nova数据同步工具中查看导入的进度。
导入配置
您可以在config/nova-data-sync.php
中找到导入功能的配置选项。
'imports' => [ 'disk' => env('MEDIA_DISK', 'public'), 'chunk_size' => 1000, 'queue' => 'default', ],
使用Nova操作导出数据
要创建导出功能,您需要创建两个扩展自 ExportProcessor
和 ExportNovaAction
的类。
下面是一个示例 ExportProcessor
namespace App\Nova\Exports; use App\Models\User; use Coreproc\NovaDataSync\Export\Jobs\ExportProcessor; use Illuminate\Contracts\Database\Query\Builder; class UserExportProcessor extends ExportProcessor { public function query(): Builder { return User::query(); } }
您还可以定义 query()
方法以返回查询构建器。如果您想从数据库表导出数据,这将非常有用。
namespace App\Nova\Exports; use Coreproc\NovaDataSync\Export\Jobs\ExportProcessor; use DB; use Illuminate\Contracts\Database\Query\Builder; class UserExportProcessor extends ExportProcessor { public function query(): Builder { return \DB::query()->from('users') ->select([ 'id', 'email', ]); } }
接下来,创建一个 ExportNovaAction
类,并创建一个 processor()
函数,该函数返回您刚刚创建的处理器类。
namespace App\Nova\Exports; use Coreproc\NovaDataSync\Export\Jobs\ExportProcessor; use Coreproc\NovaDataSync\Export\Nova\Action\ExportNovaAction; class UserExportAction extends ExportNovaAction { protected function processor(ActionFields $fields, Collection $models): ExportProcessor { return new UserExportProcessor(); } }
如果您想向导出功能添加额外的字段,您可以在 fields()
方法中定义它们,并通过 $fields
属性访问它们。
现在,您可以将 ExportNovaAction
添加到您的 Nova 资源中
public function actions(Request $request) { return [ new UserExportAction(), ]; }
用户配置
每个导入和导出都有一个可变形态的 user()
关系。这用于确定谁导入了或导出了数据。您需要为要用于导入和导出功能的每个用户类型定义 Nova 资源。这可以在 config/nova-data-sync.php
文件中完成。
'nova_resources' => [ /** * Since users are defined as morphable, we need to specify the Nova resource * associated with the users we want. */ 'users' => [ \App\Nova\User::class, ], ],
默认情况下,这已经包含了 App\Nova\User::class
资源。根据需要,您可以添加更多用户资源,如 App\Nova\BackendUser
。