vitorccs / laravel-csv
PHP Laravel 包,以内存优化方式创建 CSV 文件
Requires
- php: >=8.0
Requires (Dev)
- ext-sqlite3: *
- laravel/legacy-factories: 1.x-dev
- orchestra/testbench: ^5.0 || ^6.0 || ^7.0 || ^8.0
- phpunit/phpunit: ^9.5
Suggests
- league/flysystem-aws-s3-v3: Required to use the Flysystem S3 driver (^1.0).
This package is not auto-updated.
Last update: 2024-09-24 18:20:47 UTC
README
PHP Laravel 包,以内存优化方式导出和导入 CSV 文件。
描述
从 PHP 数组、Laravel 集合 或 Laravel 查询 导出 CSV 文件,并可选择提示用户下载文件、将其存储在 Laravel 磁盘或作为 Laravel Job 在后台创建文件。
从 Laravel 磁盘、本地文件、字符串 或 资源 导入 CSV 文件,并可选择检索完整内容或小部分内容。
该项目通过使用 PHP 流 优化内存使用,将内容放置在临时文件中(而不是 PHP 线程内存),并逐行读取/写入内容。
注意:此项目受到 https://github.com/maatwebsite/Laravel-Excel 的启发,这是一个伟大的项目,可以处理许多格式(Excel、PDF、OpenOffice 和 CSV)。但由于它使用 PhpSpreadsheet,因此不适合处理大型 CSV 文件(数千条记录),导致 PHP 内存耗尽。
从 v1.0 升级到 v2.0
版本 2.0 添加了导入功能,因此唯一需要执行的操作是更改导入命名空间。
// v1.0 (old) use Vitorccs\LaravelCsv\Concerns\Exportable; use Vitorccs\LaravelCsv\Concerns\FromArray; use Vitorccs\LaravelCsv\Concerns\FromCollection; use Vitorccs\LaravelCsv\Concerns\FromQuery;
// v2.0 (new) use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromArray; use Vitorccs\LaravelCsv\Concerns\Exportables\FromCollection; use Vitorccs\LaravelCsv\Concerns\Exportables\FromQuery;
要求
- PHP >= 8.0
- Laravel >= 6.x
安装
步骤 1) 添加 composer 依赖项
composer require vitorccs/laravel-csv
步骤 2) 发布配置文件
php artisan vendor:publish --provider="Vitorccs\LaravelCsv\ServiceProviders\CsvServiceProvider" --tag=config
步骤 3) 根据项目偏好编辑本地 config\csv.php
文件
如何导出
步骤 1) 创建一个如下的导出类文件
注意:您可以实现 FromArray、FromCollection 或 FromQuery
namespace App\Exports; use App\User; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromQuery; class UsersExport implements FromQuery { use Exportable; public function query() { return User::query() ->where('created_at', '>=', '2024-01-01 00:00:00'); } }
现在可以通过一行代码生成文件
# prompt the client browser to download the file return (new UsersExport)->download('users.csv');
如果要将文件存储在磁盘上
# will save the file in 's3' disk return (new UsersExport)->store('users.csv', 's3');
您也可以获取内容流以更好地控制输出
# will get the content in a stream (content placed in a temporary file) return (new UsersExport)->stream();
对于大型文件,您可能希望将其作为 Laravel Job 在后台生成
use App\Jobs\NotifyCsvCreated; # generate a {uuid-v4}.csv filename $filename = CsvHelper::filename(); # will create a job to create and store the file in disk # and afterwards notify the user (new BillsExport()) ->queue($filename, 's3') ->allOnQueue('default') ->chain([ // You must create the Laravel Job below new NotifyCsvCreated($filename) ]);
导出 - 数据源
注意:只有 FromQuery
可以从配置文件中的 chunk_size
参数按块大小分割结果。
Laravel Eloquent 查询构建器
namespace App\Exports; use App\User; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromQuery; class MyQueryExport implements FromQuery { use Exportable; public function query() { return User::query(); } }
Laravel 数据库查询构建器
namespace App\Exports; use App\User; use Illuminate\Support\Facades\DB; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromQuery; class MyQueryExport implements FromQuery { use Exportable; public function query() { return DB::table('users'); } }
Laravel 集合
namespace App\Exports; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromCollection; class MyCollectionExport implements FromCollection { use Exportable; public function collection() { return collect([ ['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3'] ]); } }
Laravel 懒集合
namespace App\Exports; use App\User; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromCollection; class MyQueryExport implements FromCollection { use Exportable; public function collection() { return User::cursor(); } }
PHP 数组
namespace App\Exports; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromArray; class MyArrayExport implements FromArray { use Exportable; public function array(): array { return [ ['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3'] ]; } }
如何导入
步骤 1) 创建一个如下的导入类文件
注意:您可以实现 FromDisk、FromFile、FromResource 或 FromContents
namespace App\Exports; use Vitorccs\LaravelCsv\Concerns\Importables\Importable; use Vitorccs\LaravelCsv\Concerns\Importables\FromDisk; class UsersImport implements FromDisk { use Importable; public function disk(): ?string { return 's3'; } public function filename(): string { return 'users.csv'; } }
现在可以通过一行代码检索内容
# get the records in array format return (new UsersImport)->getArray();
# in case the result is too large, you may receive small chunk of results # at a time in your callback function, preventing memory exhaustion. (new UsersImport)->chunkArray(function(array $rows, int $index) { // do something with the rows echo "Chunk $index has the following records:"; print_r($rows); });
导入 - 数据源
字符串
namespace App\Imports; use Vitorccs\LaravelCsv\Concerns\Importables\Importable; use Vitorccs\LaravelCsv\Concerns\Importables\FromContents; class MyContents implements FromContents { use Importable; public function contents(): string { return "A1,B1,C1\nA2,B2,C2\n,A3,B3,C3"; } }
本地文件
namespace App\Imports; use Vitorccs\LaravelCsv\Concerns\Importables\Importable; use Vitorccs\LaravelCsv\Concerns\Importables\FromFile; class MyFileImport implements FromFile { use Importable; public function filename(): string; { return storage_path() . '/users.csv'; } }
资源
namespace App\Imports; use Vitorccs\LaravelCsv\Concerns\Importables\Importable; use Vitorccs\LaravelCsv\Concerns\Importables\FromResource; class MyResourceImport implements FromResource { use Importable; public function resource() { $contents = "A1,B1,C1\nA2,B2,C2\n,A3,B3,C3"; $resource = fopen('php://memory', 'w+'); fputs($resource, $contents); return $resource; } }
Laravel 磁盘
namespace App\Exports; use Vitorccs\LaravelCsv\Concerns\Importables\Importable; use Vitorccs\LaravelCsv\Concerns\Importables\FromDisk; class UsersImport implements FromDisk { use Importable; public function disk(): ?string { return 'local'; } public function filename(): string { return 'my_imports/users.csv'; } }
实现
以下实现适用于导出和导入模式。
标题
实现 WithHeadings
为 CSV 文件设置标题。
use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromArray; use Vitorccs\LaravelCsv\Concerns\WithHeadings; class UsersExport implements FromArray, WithHeadings { use Exportable; public function headings(): array { return ['ID', 'Name', 'Email']; } }
映射行
实现 WithMapping
如果您需要设置每列的值或应用一些自定义格式化。
use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromArray; use Vitorccs\LaravelCsv\Concerns\WithMapping; class UsersExport implements FromArray, WithMapping { use Exportable; public function map($user): array { return [ $user->id, $user->name, $user->email ?: 'N/A' ]; } }
格式化列
实现 WithColumnFormatting
格式化日期和数字字段。
在导出模式下,日期必须是 Carbon 或 Datetime 对象,数字必须是任何类型的数字数据(数字字符串、整数或浮点数)。
在导入模式下,字符串内容必须与设置的格式匹配(例如:日期为 yyyy-mm-dd)。
格式化首选项在配置文件 csv.php
中设置。
use Carbon\Carbon; use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromArray; use Vitorccs\LaravelCsv\Concerns\WithColumnFormatting; use Vitorccs\LaravelCsv\Enum\CellFormat; class UsersExport implements FromArray, WithColumnFormatting { use Exportable; public function array(): array { return [ [ Carbon::now(), Carbon::now(), 2.50, 1.00 ], [ new DateTime(), new DateTime(), 3, 2.00 ] ]; } public function columnFormats(): array { return [ 'A' => CellFormat::DATE, 'B' => CellFormat::DATETIME, 'C' => CellFormat::DECIMAL, 'D' => CellFormat::INTEGER, ]; } }
限制结果
如果需要限制导出/导入的结果数量,请实现以下方法。
use Vitorccs\LaravelCsv\Concerns\Exportables\Exportable; use Vitorccs\LaravelCsv\Concerns\Exportables\FromQuery; class UsersExport implements FromQuery { use Exportable; public function limit(): ?int { return 5000; } }
许可证
在MIT许可证下发布。