前一段需要项目中需要通过 Excel 导入用户,之前用过 phpexcel,总感觉太过繁琐,印象中 phpexcel 也很久没更新,看到项目中有使用 MaatwebsiteExcel
,便尝试使用一下。
安装
composer require maatwebsite/excel
导入
生成导入类
php artisan make:import AdminsImport --model=Admin
会看到 app 下面生成了 Imports 文件夹。
完善业务逻辑
<?php namespace AppImports; use AppModelsAdmin; use function EasyWeChatKernelSupportstr_random; use MaatwebsiteExcelConcernsToModel; class AdminsImport implements ToModel { /** * @param array $row * * @return IlluminateDatabaseEloquentModel|null */ public function model(array $row) { //过滤表头和空行,我这边表头的第一个单元格是id,具体自行调整 if (empty($row[0]) || $row[0] == 'id') { return null; } return new Admin([ 'username' => $row[2], 'password' => bcrypt($row[3]), 'api_token' => str_random(60), ]); } }
导入任务
<?php namespace AppConsoleCommands; use AppImportsAdminsImport; use IlluminateConsoleCommand; use MaatwebsiteExcelFacadesExcel; class ImportAdmin extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'importAdmin'; /** * The console command description. * * @var string */ protected $description = '导入admin'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { Excel::import(new AdminsImport(), storage_path('files/export.xlsx')); $this->info($this->description.'完成'); } }
其他逻辑
当然,可能业务必不仅仅是写入数据,可能有一些设计具体业务的操作,那么你可以这样操作。
<?php namespace AppImports; use AppModelsAdmin; use function EasyWeChatKernelSupportstr_random; use MaatwebsiteExcelConcernsToCollection; use IlluminateSupportCollection; class AdminsImport implements ToCollection { public function collection(Collection $rows) { //如果需要去除表头 unset($rows[0]); //$rows 是数组格式 return $this->createData($rows); } public function createData($rows) { $success = 0; foreach ($rows as $row) { $row[0] = (int) $row[0]; if (empty($row[0])) { continue; } (new Admin())->create( [ 'username' => $row[2], 'name' => $row[2], 'password' => bcrypt($row[3]), 'api_token' => str_random(60), ] ); // 其他业务代码 $success++; } return $success.'-'.count($rows); } }
执行
php7.2 artisan importAdmin
总的来说,使用起来还是简单明了的。
more
具体导入实现可以搜索 MaatwebsiteExcelExcel
查看,里面还有导出、以队列方式导入等,支持的格式也是多种多样,具体代码如下,功能还是很强大的,足够应付日常需求了。
<?php namespace MaatwebsiteExcel; use IlluminateSupportCollection; use MaatwebsiteExcelFilesFilesystem; use MaatwebsiteExcelFilesTemporaryFile; use IlluminateContractsQueueShouldQueue; use IlluminateFoundationBusPendingDispatch; use MaatwebsiteExcelHelpersFileTypeDetector; class Excel implements Exporter, Importer { use RegistersCustomConcerns; const XLSX = 'Xlsx'; const CSV = 'Csv'; const TSV = 'Csv'; const ODS = 'Ods'; const XLS = 'Xls'; const SLK = 'Slk'; const XML = 'Xml'; const GNUMERIC = 'Gnumeric'; const HTML = 'Html'; const MPDF = 'Mpdf'; const DOMPDF = 'Dompdf'; const TCPDF = 'Tcpdf'; /** * @var Writer */ protected $writer; /** * @var QueuedWriter */ protected $queuedWriter; /** * @var Filesystem */ protected $filesystem; /** * @var Reader */ private $reader; /** * @param Writer $writer * @param QueuedWriter $queuedWriter * @param Reader $reader * @param Filesystem $filesystem */ public function __construct( Writer $writer, QueuedWriter $queuedWriter, Reader $reader, Filesystem $filesystem ) { $this->writer = $writer; $this->reader = $reader; $this->filesystem = $filesystem; $this->queuedWriter = $queuedWriter; } /** * {@inheritdoc} */ public function download($export, string $fileName, string $writerType = null, array $headers = []) { return response()->download( $this->export($export, $fileName, $writerType)->getLocalPath(), $fileName, $headers )->deleteFileAfterSend(true); } /** * {@inheritdoc} */ public function store($export, string $filePath, string $diskName = null, string $writerType = null, $diskOptions = []) { if ($export instanceof ShouldQueue) { return $this->queue($export, $filePath, $diskName, $writerType, $diskOptions); } $temporaryFile = $this->export($export, $filePath, $writerType); $exported = $this->filesystem->disk($diskName, $diskOptions)->copy( $temporaryFile, $filePath ); $temporaryFile->delete(); return $exported; } /** * {@inheritdoc} */ public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { $writerType = FileTypeDetector::detectStrict($filePath, $writerType); return $this->queuedWriter->store( $export, $filePath, $disk, $writerType, $diskOptions ); } /** * {@inheritdoc} */ public function raw($export, string $writerType) { $temporaryFile = $this->writer->export($export, $writerType); $contents = $temporaryFile->contents(); $temporaryFile->delete(); return $contents; } /** * {@inheritdoc} */ public function import($import, $filePath, string $disk = null, string $readerType = null) { $readerType = FileTypeDetector::detect($filePath, $readerType); $response = $this->reader->read($import, $filePath, $readerType, $disk); if ($response instanceof PendingDispatch) { return $response; } return $this; } /** * {@inheritdoc} */ public function toArray($import, $filePath, string $disk = null, string $readerType = null): array { $readerType = FileTypeDetector::detect($filePath, $readerType); return $this->reader->toArray($import, $filePath, $readerType, $disk); } /** * {@inheritdoc} */ public function toCollection($import, $filePath, string $disk = null, string $readerType = null): Collection { $readerType = FileTypeDetector::detect($filePath, $readerType); return $this->reader->toCollection($import, $filePath, $readerType, $disk); } /** * {@inheritdoc} */ public function queueImport(ShouldQueue $import, $filePath, string $disk = null, string $readerType = null) { return $this->import($import, $filePath, $disk, $readerType); } /** * @param object $export * @param string|null $fileName * @param string $writerType * * @throws PhpOfficePhpSpreadsheetException * @return TemporaryFile */ protected function export($export, string $fileName, string $writerType = null): TemporaryFile { $writerType = FileTypeDetector::detectStrict($fileName, $writerType); return $this->writer->export($export, $writerType); } }
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持以下吧