rhuett / csvie
Csvie 是为 Laravel 开发的一个简单的 CSV 文件解析器。Csvie 基于 LeagueCSV,可以快速将数据导入 MySQL 数据库,也可以从数据库导出数据。它还提供了一个方便的抽象类,用于在插入之前快速清理和清洗 CSV 文件。
Requires
- doctrine/dbal: ^2.10
- illuminate/support: ~5|~6|~7
- league/csv: ^9.6
- spatie/laravel-collection-macros: ^6.1
Requires (Dev)
- matt-allan/laravel-code-style: ^0.5.1
- mockery/mockery: ^1.1
- orchestra/testbench: ~3|~4
- phpunit/phpunit: ^8.0
- sempro/phpunit-pretty-print: ^1.0
This package is auto-updated.
Last update: 2024-09-08 09:51:08 UTC
README
Csvie 是为 Laravel 7 开发的一个简单的 CSV 文件解析器。Csvie 基于 LeagueCSV,可以快速将数据导入 MySQL 数据库,也可以从数据库导出数据。它还提供了一个方便的抽象类,用于在插入之前快速清理和清洗 CSV 文件。
工作原理
Csvie 旨在快速将包含数千行数据的 CSV 文件加载到 MySQL 数据库中。这种工作原理背后的思想很简单
- 您将 CSV 文件上传到您的服务器。
- 使用 Csvie 将文件分块为更小的部分。分块将按数据行进行,而不是按文件全局。
- 编写一个自定义 CSV 清洗器以清理分块文件中的数据,然后在服务器上覆盖这些文件。
- 请注意,您不必使用包含的 HashCsvCleaner 实现。您可以使用 Rhuett\Csvie\Contracts\CsvieCleaner 接口编写自己的实现。
- 直接使用 Load Data 语句 将清理后的文件直接加载到您的 MySQL 数据库中。
安装
通过 Composer
$ composer require rhuett/csvie
$ php artisan vendor:publish --provider="Rhuett\Csvie\CsvieServiceProvider"
请确保将以下行添加到您的 app/config/database.php 文件中
'mysql' => [ 'driver' => 'mysql', // ... 'options' => extension_loaded('pdo_mysql') ? array_filter([ // ... PDO::MYSQL_ATTR_LOCAL_INFILE => true, ]) : [], ],
完成这些配置更改后,不要忘记运行
$ php artisan config:cache
请注意,如果您在客户端和服务器端都收到有关此功能未启用的错误,则可能还需要编辑 mysql.cnf
# File Location: /etc/mysql/mysql.conf.d/mysql.cnf
# Add the following to the bottom of the file:
[server]
local_infile=true
...然后运行
$ sudo systemctl restart mysql
用法
单个 CSV 文件导入示例,使用控制器的 store 方法
public function store(Request $request) { $csvie = new Csvie; // note: you can pass an array of config overrides if needed $modelInstance = new Model; $referenceData = 'Whatever I want'; // note: reference data is optional // Note: You can pass an array for both column and model UIDs if you need to verify against multiple columns $cleaner = new ModelCleaner( 'ID', // column name from CSV file to match 'model_id', // model ID to verify against column name $modelInstance, $referenceData ); $fileName = $request->file->store('/', 'uploads'); // move uploaded file from /temp into permanent storage $chunkedFiles = $csvie->chunkFiles( $csvie->getStorageDiskPath('uploads').$fileName ); foreach($chunkedFiles as $chunk) { $chunkData = $csvie->readCsvFile($chunk); $cleanData = $cleaner->scrub($chunkData); $cleanFile = $csvie->saveCsvFile($chunk, $cleanData); $csvie->importCSV($cleanFile, $modelInstance); } $csvie->clearStorageDisk(); // clear out leftover uploaded file along with its chunks return view('view.index')->with([ 'models' => Model::all() ]); }
制作自己的 Csvie 清洗器
只需运行
$ php artisan make:cleaner ModelNameCleaner
...您应该会在 App\Services\CsvCleaners 目录中获得一个类似下面的新文件。请注意,这里显示的额外注释将不会包含在新生成的文件中。
<?php namespace App\Services\CsvCleaners; use Illuminate\Support\Carbon; use Illuminate\Support\Collection; use Rhuett\Csvie\Cleaners\HashCsvCleaner; /** * Class ModelCleaner. * * An abstract CsvieCleaner implementation using a custom scrubbing technique based on your needs. */ class ModelCleaner extends HashCsvCleaner { /** * Custom made function used to clean CSV data. * * @param array $rowData - The current row of data pulled from your CSV. * @param ?\Illuminate\Support\Collection $foundModels - Matched model(s) based on your CSV, otherwise contains null. * @param array $newModel - An empty model indexed with appropriate keys based on your model. * @param \Illuminate\Support\Carbon $date - The current date used for timestamps. * @param mixed $optionalData - Any custom data that you want to reference in the scrubber. * @return array|null */ protected function scrubber(array $rowData, ?Collection $foundModels, array $newModel, Carbon $date, $optionalData) { // Run checks on $rowData here. Validate, cleanse or completely change! // Use parent::updateValue() if you have many possible ways to update a single value within $rowData. Check the function for more information. // Return any changes, otherwise return $rowData to make no changes. // Return null if you want to remove the data completely. // Note: Duplicated headers will be automatically renamed in $rowData. // Ex: Header -> Header-1 -> Header-2 ... // Note: Since we are not using Eloquent, we will need to manage our timestamps manually. // This is why a Carbon datetime instance is passed as a parameter. } }
注意:如果您想更改 CsvCleaner 目录,可以编辑应用配置目录中的 csvie 配置文件。
不要忘记将清理器目录添加到您的 composer.json 文件中(如果需要)
... "autoload": { ... "classmap": [ ... "app/Services" ] }, ...
制作自己的 CSV 清洗器
如果您需要一个完全定制的 CSV 清洗器,则可以根据 Rhuett\Csvie\Contracts\CsvieCleaner 合约制作自己的实现
use Illuminate\Support\Collection; use Rhuett\Csvie\Contracts\CsvieCleaner as CsvieCleanerContract; use Rhuett\Csvie\Traits\CsvieHelpers; /** * Class MyCsvCleaner. * * An abstract CsvieCleaner implementation using a custom scrubbing technique based on your needs. */ abstract class MyCsvCleaner implements CsvieCleanerContract { use CsvieHelpers; // Not needed, review trait to see if it will help you. /** * Cleans the data within a CSV record to match what's expected by the database. * * @param \Illuminate\Support\Collection $data * @return \Illuminate\Support\Collection */ public function scrub(Collection $data): Collection { // Clean all the data } }
变更日志
请参阅 changelog 了解最近更改的详细信息。
测试
$ composer test
贡献
请参阅 contributing.md 了解详细信息和一个待办事项列表。
安全
如果您发现任何安全相关的问题,请通过电子邮件 im.ryan@protonmail.com 而不是使用问题跟踪器。
鸣谢
- Ryan Huett:项目作者
- LeagueCSV:使其易于处理 CSV
- Laravel Collection Macros:他们的简洁的 filterMap 集合宏
许可
MPL-2.0。请参阅 license 文件 了解更多信息。