Файловый менеджер - Редактировать - /home/easybachat/hisabat365.com/4a7891/maatwebsite.tar
Ðазад
excel/CODE_OF_CONDUCT.md 0000644 00000006220 15060131672 0010444 0 ustar 00 # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at patrick@spartner.nl. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ excel/src/Writer.php 0000644 00000020051 15060131672 0010417 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Support\Arr; use Maatwebsite\Excel\Concerns\WithBackgroundColor; use Maatwebsite\Excel\Concerns\WithCustomValueBinder; use Maatwebsite\Excel\Concerns\WithDefaultStyles; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Concerns\WithProperties; use Maatwebsite\Excel\Concerns\WithTitle; use Maatwebsite\Excel\Events\BeforeExport; use Maatwebsite\Excel\Events\BeforeWriting; use Maatwebsite\Excel\Factories\WriterFactory; use Maatwebsite\Excel\Files\RemoteTemporaryFile; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Files\TemporaryFileFactory; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\Fill; /** @mixin Spreadsheet */ class Writer { use DelegatedMacroable, HasEventBus; /** * @var Spreadsheet */ protected $spreadsheet; /** * @var object */ protected $exportable; /** * @var TemporaryFileFactory */ protected $temporaryFileFactory; /** * @param TemporaryFileFactory $temporaryFileFactory */ public function __construct(TemporaryFileFactory $temporaryFileFactory) { $this->temporaryFileFactory = $temporaryFileFactory; $this->setDefaultValueBinder(); } /** * @param object $export * @param string $writerType * @return TemporaryFile * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function export($export, string $writerType): TemporaryFile { $this->open($export); $sheetExports = [$export]; if ($export instanceof WithMultipleSheets) { $sheetExports = $export->sheets(); } foreach ($sheetExports as $sheetExport) { $this->addNewSheet()->export($sheetExport); } return $this->write($export, $this->temporaryFileFactory->makeLocal(null, strtolower($writerType)), $writerType); } /** * @param object $export * @return $this */ public function open($export) { $this->exportable = $export; if ($export instanceof WithEvents) { $this->registerListeners($export->registerEvents()); } $this->exportable = $export; $this->spreadsheet = new Spreadsheet; $this->spreadsheet->disconnectWorksheets(); if ($export instanceof WithCustomValueBinder) { Cell::setValueBinder($export); } $this->handleDocumentProperties($export); if ($export instanceof WithBackgroundColor) { $defaultStyle = $this->spreadsheet->getDefaultStyle(); $backgroundColor = $export->backgroundColor(); if (is_string($backgroundColor)) { $defaultStyle->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setRGB($backgroundColor); } if (is_array($backgroundColor)) { $defaultStyle->applyFromArray(['fill' => $backgroundColor]); } if ($backgroundColor instanceof Color) { $defaultStyle->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor($backgroundColor); } } if ($export instanceof WithDefaultStyles) { $defaultStyle = $this->spreadsheet->getDefaultStyle(); $styles = $export->defaultStyles($defaultStyle); if (is_array($styles)) { $defaultStyle->applyFromArray($styles); } } $this->raise(new BeforeExport($this, $this->exportable)); return $this; } /** * @param TemporaryFile $tempFile * @param string $writerType * @return Writer * * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function reopen(TemporaryFile $tempFile, string $writerType) { $reader = IOFactory::createReader($writerType); $this->spreadsheet = $reader->load($tempFile->sync()->getLocalPath()); return $this; } /** * @param object $export * @param TemporaryFile $temporaryFile * @param string $writerType * @return TemporaryFile * * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function write($export, TemporaryFile $temporaryFile, string $writerType): TemporaryFile { $this->exportable = $export; $this->spreadsheet->setActiveSheetIndex(0); $this->raise(new BeforeWriting($this, $this->exportable)); $writer = WriterFactory::make( $writerType, $this->spreadsheet, $export ); if ($temporaryFile instanceof RemoteTemporaryFile && !$temporaryFile->existsLocally()) { $temporaryFile = resolve(TemporaryFileFactory::class) ->makeLocal(Arr::last(explode('/', $temporaryFile->getLocalPath()))); } $writer->save( $temporaryFile->getLocalPath() ); if ($temporaryFile instanceof RemoteTemporaryFile) { $temporaryFile->updateRemote(); $temporaryFile->deleteLocalCopy(); } $this->clearListeners(); $this->spreadsheet->disconnectWorksheets(); unset($this->spreadsheet); return $temporaryFile; } /** * @param int|null $sheetIndex * @return Sheet * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function addNewSheet(int $sheetIndex = null) { return new Sheet($this->spreadsheet->createSheet($sheetIndex)); } /** * @return Spreadsheet */ public function getDelegate() { return $this->spreadsheet; } /** * @return $this */ public function setDefaultValueBinder() { Cell::setValueBinder( app(config('excel.value_binder.default', DefaultValueBinder::class)) ); return $this; } /** * @param int $sheetIndex * @return Sheet * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function getSheetByIndex(int $sheetIndex) { return new Sheet($this->getDelegate()->getSheet($sheetIndex)); } /** * @param string $concern * @return bool */ public function hasConcern($concern): bool { return $this->exportable instanceof $concern; } /** * @param object $export */ protected function handleDocumentProperties($export) { $properties = config('excel.exports.properties', []); if ($export instanceof WithProperties) { $properties = array_merge($properties, $export->properties()); } if ($export instanceof WithTitle) { $properties = array_merge($properties, ['title' => $export->title()]); } $props = $this->spreadsheet->getProperties(); foreach (array_filter($properties) as $property => $value) { switch ($property) { case 'title': $props->setTitle($value); break; case 'description': $props->setDescription($value); break; case 'creator': $props->setCreator($value); break; case 'lastModifiedBy': $props->setLastModifiedBy($value); break; case 'subject': $props->setSubject($value); break; case 'keywords': $props->setKeywords($value); break; case 'category': $props->setCategory($value); break; case 'manager': $props->setManager($value); break; case 'company': $props->setCompany($value); break; } } } } excel/src/SettingsProvider.php 0000644 00000001077 15060131672 0012465 0 ustar 00 <?php namespace Maatwebsite\Excel; use Maatwebsite\Excel\Cache\CacheManager; use PhpOffice\PhpSpreadsheet\Settings; class SettingsProvider { /** * @var CacheManager */ private $cache; public function __construct(CacheManager $cache) { $this->cache = $cache; } /** * Provide PhpSpreadsheet settings. */ public function provide() { $this->configureCellCaching(); } protected function configureCellCaching() { Settings::setCache( $this->cache->driver() ); } } excel/src/Transactions/TransactionHandler.php 0000644 00000000315 15060131672 0015377 0 ustar 00 <?php namespace Maatwebsite\Excel\Transactions; interface TransactionHandler { /** * @param callable $callback * @return mixed */ public function __invoke(callable $callback); } excel/src/Transactions/DbTransactionHandler.php 0000644 00000001176 15060131672 0015653 0 ustar 00 <?php namespace Maatwebsite\Excel\Transactions; use Illuminate\Database\ConnectionInterface; class DbTransactionHandler implements TransactionHandler { /** * @var ConnectionInterface */ private $connection; /** * @param ConnectionInterface $connection */ public function __construct(ConnectionInterface $connection) { $this->connection = $connection; } /** * @param callable $callback * @return mixed * * @throws \Throwable */ public function __invoke(callable $callback) { return $this->connection->transaction($callback); } } excel/src/Transactions/TransactionManager.php 0000644 00000001251 15060131672 0015374 0 ustar 00 <?php namespace Maatwebsite\Excel\Transactions; use Illuminate\Support\Facades\DB; use Illuminate\Support\Manager; class TransactionManager extends Manager { /** * @return string */ public function getDefaultDriver() { return config('excel.transactions.handler'); } /** * @return NullTransactionHandler */ public function createNullDriver() { return new NullTransactionHandler(); } /** * @return DbTransactionHandler */ public function createDbDriver() { return new DbTransactionHandler( DB::connection(config('excel.transactions.db.connection')) ); } } excel/src/Transactions/NullTransactionHandler.php 0000644 00000000422 15060131672 0016231 0 ustar 00 <?php namespace Maatwebsite\Excel\Transactions; class NullTransactionHandler implements TransactionHandler { /** * @param callable $callback * @return mixed */ public function __invoke(callable $callback) { return $callback(); } } excel/src/Exporter.php 0000644 00000002675 15060131672 0010767 0 ustar 00 <?php namespace Maatwebsite\Excel; interface Exporter { /** * @param object $export * @param string|null $fileName * @param string $writerType * @param array $headers * @return \Symfony\Component\HttpFoundation\BinaryFileResponse * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ public function download($export, string $fileName, string $writerType = null, array $headers = []); /** * @param object $export * @param string $filePath * @param string|null $diskName * @param string $writerType * @param mixed $diskOptions * @return bool * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []); /** * @param object $export * @param string $filePath * @param string|null $disk * @param string $writerType * @param mixed $diskOptions * @return \Illuminate\Foundation\Bus\PendingDispatch */ public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []); /** * @param object $export * @param string $writerType * @return string */ public function raw($export, string $writerType); } excel/src/Middleware/TrimCellValue.php 0000644 00000000774 15060131672 0013742 0 ustar 00 <?php namespace Maatwebsite\Excel\Middleware; class TrimCellValue extends CellMiddleware { /** * @param mixed $value * @return mixed */ public function __invoke($value, callable $next) { if (!is_string($value)) { return $next($value); } // Remove whitespace, BOM and zero width spaces. $cleaned = preg_replace('~^[\s\x{FEFF}\x{200B}]+|[\s\x{FEFF}\x{200B}]+$~u', '', $value) ?? trim($value); return $next($cleaned); } } excel/src/Middleware/ConvertEmptyCellValuesToNull.php 0000644 00000000474 15060131672 0017004 0 ustar 00 <?php namespace Maatwebsite\Excel\Middleware; class ConvertEmptyCellValuesToNull extends CellMiddleware { /** * @param mixed $value * @return mixed */ public function __invoke($value, callable $next) { return $next( $value === '' ? null : $value ); } } excel/src/Middleware/CellMiddleware.php 0000644 00000000323 15060131672 0014075 0 ustar 00 <?php namespace Maatwebsite\Excel\Middleware; abstract class CellMiddleware { /** * @param mixed $value * @return mixed */ abstract public function __invoke($value, callable $next); } excel/src/ExcelServiceProvider.php 0000644 00000010716 15060131672 0013246 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; use Illuminate\Support\ServiceProvider; use Laravel\Lumen\Application as LumenApplication; use Maatwebsite\Excel\Cache\CacheManager; use Maatwebsite\Excel\Console\ExportMakeCommand; use Maatwebsite\Excel\Console\ImportMakeCommand; use Maatwebsite\Excel\Files\Filesystem; use Maatwebsite\Excel\Files\TemporaryFileFactory; use Maatwebsite\Excel\Mixins\DownloadCollectionMixin; use Maatwebsite\Excel\Mixins\DownloadQueryMacro; use Maatwebsite\Excel\Mixins\ImportAsMacro; use Maatwebsite\Excel\Mixins\ImportMacro; use Maatwebsite\Excel\Mixins\StoreCollectionMixin; use Maatwebsite\Excel\Mixins\StoreQueryMacro; use Maatwebsite\Excel\Transactions\TransactionHandler; use Maatwebsite\Excel\Transactions\TransactionManager; class ExcelServiceProvider extends ServiceProvider { /** * {@inheritdoc} */ public function boot() { if ($this->app->runningInConsole()) { $this->publishes([ __DIR__ . '/Console/stubs/export.model.stub' => base_path('stubs/export.model.stub'), __DIR__ . '/Console/stubs/export.plain.stub' => base_path('stubs/export.plain.stub'), __DIR__ . '/Console/stubs/export.query.stub' => base_path('stubs/export.query.stub'), __DIR__ . '/Console/stubs/export.query-model.stub' => base_path('stubs/export.query-model.stub'), __DIR__ . '/Console/stubs/import.collection.stub' => base_path('stubs/import.collection.stub'), __DIR__ . '/Console/stubs/import.model.stub' => base_path('stubs/import.model.stub'), ], 'stubs'); if ($this->app instanceof LumenApplication) { $this->app->configure('excel'); } else { $this->publishes([ $this->getConfigFile() => config_path('excel.php'), ], 'config'); } } if ($this->app instanceof \Illuminate\Foundation\Application) { // Laravel $this->app->booted(function ($app) { $app->make(SettingsProvider::class)->provide(); }); } else { // Lumen $this->app->make(SettingsProvider::class)->provide(); } } /** * {@inheritdoc} */ public function register() { $this->mergeConfigFrom( $this->getConfigFile(), 'excel' ); $this->app->bind(CacheManager::class, function ($app) { return new CacheManager($app); }); $this->app->singleton(TransactionManager::class, function ($app) { return new TransactionManager($app); }); $this->app->bind(TransactionHandler::class, function ($app) { return $app->make(TransactionManager::class)->driver(); }); $this->app->bind(TemporaryFileFactory::class, function () { return new TemporaryFileFactory( config('excel.temporary_files.local_path', config('excel.exports.temp_path', storage_path('framework/laravel-excel'))), config('excel.temporary_files.remote_disk') ); }); $this->app->bind(Filesystem::class, function ($app) { return new Filesystem($app->make('filesystem')); }); $this->app->bind('excel', function ($app) { return new Excel( $app->make(Writer::class), $app->make(QueuedWriter::class), $app->make(Reader::class), $app->make(Filesystem::class) ); }); $this->app->alias('excel', Excel::class); $this->app->alias('excel', Exporter::class); $this->app->alias('excel', Importer::class); Collection::mixin(new DownloadCollectionMixin); Collection::mixin(new StoreCollectionMixin); Builder::macro('downloadExcel', (new DownloadQueryMacro)()); Builder::macro('storeExcel', (new StoreQueryMacro())()); Builder::macro('import', (new ImportMacro())()); Builder::macro('importAs', (new ImportAsMacro())()); $this->commands([ ExportMakeCommand::class, ImportMakeCommand::class, ]); } /** * @return string */ protected function getConfigFile(): string { return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'excel.php'; } } excel/src/HasEventBus.php 0000644 00000002515 15060131672 0011337 0 ustar 00 <?php namespace Maatwebsite\Excel; trait HasEventBus { /** * @var array */ protected static $globalEvents = []; /** * @var array */ protected $events = []; /** * Register local event listeners. * * @param array $listeners */ public function registerListeners(array $listeners) { foreach ($listeners as $event => $listener) { $this->events[$event][] = $listener; } } public function clearListeners() { $this->events = []; } /** * Register a global event listener. * * @param string $event * @param callable $listener */ public static function listen(string $event, callable $listener) { static::$globalEvents[$event][] = $listener; } /** * @param object $event */ public function raise($event) { foreach ($this->listeners($event) as $listener) { $listener($event); } } /** * @param object $event * @return callable[] */ public function listeners($event): array { $name = \get_class($event); $localListeners = $this->events[$name] ?? []; $globalListeners = static::$globalEvents[$name] ?? []; return array_merge($globalListeners, $localListeners); } } excel/src/DelegatedMacroable.php 0000644 00000001324 15060131672 0012631 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Support\Traits\Macroable; trait DelegatedMacroable { use Macroable { __call as __callMacro; } /** * Dynamically handle calls to the class. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { if (method_exists($this->getDelegate(), $method)) { return call_user_func_array([$this->getDelegate(), $method], $parameters); } array_unshift($parameters, $this); return $this->__callMacro($method, $parameters); } /** * @return object */ abstract public function getDelegate(); } excel/src/HeadingRowImport.php 0000644 00000001670 15060131672 0012373 0 ustar 00 <?php namespace Maatwebsite\Excel; use Maatwebsite\Excel\Concerns\Importable; use Maatwebsite\Excel\Concerns\WithLimit; use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithStartRow; use Maatwebsite\Excel\Imports\HeadingRowFormatter; class HeadingRowImport implements WithStartRow, WithLimit, WithMapping { use Importable; /** * @var int */ private $headingRow; /** * @param int $headingRow */ public function __construct(int $headingRow = 1) { $this->headingRow = $headingRow; } /** * @return int */ public function startRow(): int { return $this->headingRow; } /** * @return int */ public function limit(): int { return 1; } /** * @param mixed $row * @return array */ public function map($row): array { return HeadingRowFormatter::format($row); } } excel/src/ChunkReader.php 0000644 00000011017 15060131672 0011340 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Bus\Queueable; use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Jobs\SyncJob; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ShouldQueueWithoutChain; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\WithLimit; use Maatwebsite\Excel\Concerns\WithProgressBar; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Imports\HeadingRowExtractor; use Maatwebsite\Excel\Jobs\AfterImportJob; use Maatwebsite\Excel\Jobs\QueueImport; use Maatwebsite\Excel\Jobs\ReadChunk; use Throwable; class ChunkReader { /** * @var Container */ protected $container; public function __construct(Container $container) { $this->container = $container; } /** * @param WithChunkReading $import * @param Reader $reader * @param TemporaryFile $temporaryFile * @return PendingDispatch|Collection|null */ public function read(WithChunkReading $import, Reader $reader, TemporaryFile $temporaryFile) { if ($import instanceof WithEvents) { $reader->beforeImport($import); } $chunkSize = $import->chunkSize(); $totalRows = $reader->getTotalRows(); $worksheets = $reader->getWorksheets($import); $queue = property_exists($import, 'queue') ? $import->queue : null; $delayCleanup = property_exists($import, 'cleanupInterval') ? $import->cleanupInterval : 60; if ($import instanceof WithProgressBar) { $import->getConsoleOutput()->progressStart(array_sum($totalRows)); } $jobs = new Collection(); foreach ($worksheets as $name => $sheetImport) { $startRow = HeadingRowExtractor::determineStartRow($sheetImport); if ($sheetImport instanceof WithLimit) { $limit = $sheetImport->limit(); if ($limit <= $totalRows[$name]) { $totalRows[$name] = $sheetImport->limit(); } } for ($currentRow = $startRow; $currentRow <= $totalRows[$name]; $currentRow += $chunkSize) { $jobs->push(new ReadChunk( $import, $reader->getPhpSpreadsheetReader(), $temporaryFile, $name, $sheetImport, $currentRow, $chunkSize )); } } $afterImportJob = new AfterImportJob($import, $reader); if ($import instanceof ShouldQueueWithoutChain) { $afterImportJob->setInterval($delayCleanup); $afterImportJob->setDependencies($jobs); $jobs->push($afterImportJob->delay($delayCleanup)); return $jobs->each(function ($job) use ($queue) { dispatch($job->onQueue($queue)); }); } $jobs->push($afterImportJob); if ($import instanceof ShouldQueue) { return new PendingDispatch( (new QueueImport($import))->chain($jobs->toArray()) ); } $jobs->each(function ($job) { try { function_exists('dispatch_now') ? dispatch_now($job) : $this->dispatchNow($job); } catch (Throwable $e) { if (method_exists($job, 'failed')) { $job->failed($e); } throw $e; } }); if ($import instanceof WithProgressBar) { $import->getConsoleOutput()->progressFinish(); } unset($jobs); return null; } /** * Dispatch a command to its appropriate handler in the current process without using the synchronous queue. * * @param object $command * @param mixed $handler * @return mixed */ protected function dispatchNow($command, $handler = null) { $uses = class_uses_recursive($command); if (in_array(InteractsWithQueue::class, $uses) && in_array(Queueable::class, $uses) && !$command->job ) { $command->setJob(new SyncJob($this->container, json_encode([]), 'sync', 'sync')); } $method = method_exists($command, 'handle') ? 'handle' : '__invoke'; return $this->container->call([$command, $method]); } } excel/src/Imports/HeadingRowFormatter.php 0000644 00000004475 15060131672 0014527 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports; use Illuminate\Support\Collection; use Illuminate\Support\Str; use InvalidArgumentException; class HeadingRowFormatter { /** * @const string */ const FORMATTER_NONE = 'none'; /** * @const string */ const FORMATTER_SLUG = 'slug'; /** * @var string */ protected static $formatter; /** * @var callable[] */ protected static $customFormatters = []; /** * @var array */ protected static $defaultFormatters = [ self::FORMATTER_NONE, self::FORMATTER_SLUG, ]; /** * @param array $headings * @return array */ public static function format(array $headings): array { return (new Collection($headings))->map(function ($value, $key) { return static::callFormatter($value, $key); })->toArray(); } /** * @param string $name */ public static function default(string $name = null) { if (null !== $name && !isset(static::$customFormatters[$name]) && !in_array($name, static::$defaultFormatters, true)) { throw new InvalidArgumentException(sprintf('Formatter "%s" does not exist', $name)); } static::$formatter = $name; } /** * @param string $name * @param callable $formatter */ public static function extend(string $name, callable $formatter) { static::$customFormatters[$name] = $formatter; } /** * Reset the formatter. */ public static function reset() { static::default(); } /** * @param mixed $value * @return mixed */ protected static function callFormatter($value, $key=null) { static::$formatter = static::$formatter ?? config('excel.imports.heading_row.formatter', self::FORMATTER_SLUG); // Call custom formatter if (isset(static::$customFormatters[static::$formatter])) { $formatter = static::$customFormatters[static::$formatter]; return $formatter($value, $key); } if (empty($value)) { return $key; } if (static::$formatter === self::FORMATTER_SLUG) { return Str::slug($value, '_'); } // No formatter (FORMATTER_NONE) return $value; } } excel/src/Imports/ModelImporter.php 0000644 00000010070 15060131672 0013362 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithBatchInserts; use Maatwebsite\Excel\Concerns\WithCalculatedFormulas; use Maatwebsite\Excel\Concerns\WithColumnLimit; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\WithFormatData; use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithProgressBar; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Events\AfterBatch; use Maatwebsite\Excel\HasEventBus; use Maatwebsite\Excel\Row; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class ModelImporter { use HasEventBus; /** * @var ModelManager */ private $manager; /** * @param ModelManager $manager */ public function __construct(ModelManager $manager) { $this->manager = $manager; } /** * @param Worksheet $worksheet * @param ToModel $import * @param int|null $startRow * @param string|null $endColumn * * @throws \Maatwebsite\Excel\Validators\ValidationException */ public function import(Worksheet $worksheet, ToModel $import, int $startRow = 1) { if ($startRow > $worksheet->getHighestRow()) { return; } if ($import instanceof WithEvents) { $this->registerListeners($import->registerEvents()); } $headingRow = HeadingRowExtractor::extract($worksheet, $import); $headerIsGrouped = HeadingRowExtractor::extractGrouping($headingRow, $import); $batchSize = $import instanceof WithBatchInserts ? $import->batchSize() : 1; $endRow = EndRowFinder::find($import, $startRow, $worksheet->getHighestRow()); $progessBar = $import instanceof WithProgressBar; $withMapping = $import instanceof WithMapping; $withCalcFormulas = $import instanceof WithCalculatedFormulas; $formatData = $import instanceof WithFormatData; $withValidation = $import instanceof WithValidation && method_exists($import, 'prepareForValidation'); $endColumn = $import instanceof WithColumnLimit ? $import->endColumn() : null; $this->manager->setRemembersRowNumber(method_exists($import, 'rememberRowNumber')); $i = 0; $batchStartRow = $startRow; foreach ($worksheet->getRowIterator($startRow, $endRow) as $spreadSheetRow) { $i++; $row = new Row($spreadSheetRow, $headingRow, $headerIsGrouped); if (!$import instanceof SkipsEmptyRows || !$row->isEmpty($withCalcFormulas)) { $rowArray = $row->toArray(null, $withCalcFormulas, $formatData, $endColumn); if ($import instanceof SkipsEmptyRows && method_exists($import, 'isEmptyWhen') && $import->isEmptyWhen($rowArray)) { continue; } if ($withValidation) { $rowArray = $import->prepareForValidation($rowArray, $row->getIndex()); } if ($withMapping) { $rowArray = $import->map($rowArray); } $this->manager->add( $row->getIndex(), $rowArray ); // Flush each batch. if (($i % $batchSize) === 0) { $this->flush($import, $batchSize, $batchStartRow); $batchStartRow += $i; $i = 0; if ($progessBar) { $import->getConsoleOutput()->progressAdvance($batchSize); } } } } if ($i > 0) { // Flush left-overs. $this->flush($import, $batchSize, $batchStartRow); } } private function flush(ToModel $import, int $batchSize, int $startRow) { $this->manager->flush($import, $batchSize > 1); $this->raise(new AfterBatch($this->manager, $import, $batchSize, $startRow)); } } excel/src/Imports/Persistence/CascadePersistManager.php 0000644 00000005477 15060131672 0017273 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports\Persistence; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Support\Collection; use Maatwebsite\Excel\Transactions\TransactionHandler; /** @todo */ class CascadePersistManager { /** * @var TransactionHandler */ private $transaction; /** * @param TransactionHandler $transaction */ public function __construct(TransactionHandler $transaction) { $this->transaction = $transaction; } /** * @param Model $model * @return bool */ public function persist(Model $model): bool { return ($this->transaction)(function () use ($model) { return $this->save($model); }); } /** * @param Model $model * @return bool */ private function save(Model $model): bool { if (!$model->save()) { return false; } foreach ($model->getRelations() as $relationName => $models) { $models = array_filter( $models instanceof Collection ? $models->all() : [$models] ); $relation = $model->{$relationName}(); if ($relation instanceof BelongsTo) { if (!$this->persistBelongsTo($relation, $models)) { return false; } } if ($relation instanceof BelongsToMany) { if (!$this->persistBelongsToMany($relation, $models)) { return false; } } } // We need to save the model again to // make sure all updates are performed. $model->save(); return true; } /** * @param BelongsTo $relation * @param array $models * @return bool */ private function persistBelongsTo(BelongsTo $relation, array $models): bool { // With belongs to, we first need to save all relations, // so we can use their foreign key to attach to the relation. foreach ($models as $model) { // Cascade any relations that this child model may have. if (!$this->save($model)) { return false; } $relation->associate($model); } return true; } /** * @param BelongsToMany $relation * @param array $models * @return bool */ private function persistBelongsToMany(BelongsToMany $relation, array $models): bool { foreach ($models as $model) { $relation->save($model); // Cascade any relations that this child model may have. if (!$this->save($model)) { return false; } } return true; } } excel/src/Imports/HeadingRowExtractor.php 0000644 00000004765 15060131672 0014541 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports; use Maatwebsite\Excel\Concerns\WithColumnLimit; use Maatwebsite\Excel\Concerns\WithGroupedHeadingRow; use Maatwebsite\Excel\Concerns\WithHeadingRow; use Maatwebsite\Excel\Concerns\WithStartRow; use Maatwebsite\Excel\Row; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class HeadingRowExtractor { /** * @const int */ const DEFAULT_HEADING_ROW = 1; /** * @param WithHeadingRow|mixed $importable * @return int */ public static function headingRow($importable): int { return method_exists($importable, 'headingRow') ? $importable->headingRow() : self::DEFAULT_HEADING_ROW; } /** * @param WithHeadingRow|mixed $importable * @return int */ public static function determineStartRow($importable): int { if ($importable instanceof WithStartRow) { return $importable->startRow(); } // The start row is the row after the heading row if we have one! return $importable instanceof WithHeadingRow ? self::headingRow($importable) + 1 : self::DEFAULT_HEADING_ROW; } /** * @param Worksheet $worksheet * @param WithHeadingRow|mixed $importable * @return array */ public static function extract(Worksheet $worksheet, $importable): array { if (!$importable instanceof WithHeadingRow) { return []; } $headingRowNumber = self::headingRow($importable); $rows = iterator_to_array($worksheet->getRowIterator($headingRowNumber, $headingRowNumber)); $headingRow = head($rows); $endColumn = $importable instanceof WithColumnLimit ? $importable->endColumn() : null; return HeadingRowFormatter::format((new Row($headingRow))->toArray(null, false, false, $endColumn)); } /** * @param array $headingRow * @param WithGroupedHeadingRow|mixed $importable * @return array */ public static function extractGrouping($headingRow, $importable) { $headerIsGrouped = array_fill(0, count($headingRow), false); if (!$importable instanceof WithGroupedHeadingRow) { return $headerIsGrouped; } array_walk($headerIsGrouped, function (&$value, $key) use ($headingRow) { if (array_count_values($headingRow)[$headingRow[$key]] > 1) { $value = true; } }); return $headerIsGrouped; } } excel/src/Imports/EndRowFinder.php 0000644 00000001464 15060131672 0013135 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports; use Maatwebsite\Excel\Concerns\WithLimit; class EndRowFinder { /** * @param object|WithLimit $import * @param int $startRow * @param int|null $highestRow * @return int|null */ public static function find($import, int $startRow = null, int $highestRow = null) { if (!$import instanceof WithLimit) { return null; } $limit = $import->limit(); if ($limit > $highestRow) { return null; } // When no start row given, // use the first row as start row. $startRow = $startRow ?? 1; // Subtract 1 row from the start row, so a limit // of 1 row, will have the same start and end row. return ($startRow - 1) + $limit; } } excel/src/Imports/ModelManager.php 0000644 00000014257 15060131672 0013146 0 ustar 00 <?php namespace Maatwebsite\Excel\Imports; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\PersistRelations; use Maatwebsite\Excel\Concerns\SkipsOnError; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithUpsertColumns; use Maatwebsite\Excel\Concerns\WithUpserts; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Exceptions\RowSkippedException; use Maatwebsite\Excel\Imports\Persistence\CascadePersistManager; use Maatwebsite\Excel\Validators\RowValidator; use Maatwebsite\Excel\Validators\ValidationException; use Throwable; class ModelManager { /** * @var array */ private $rows = []; /** * @var RowValidator */ private $validator; /** * @var bool */ private $remembersRowNumber = false; /** * @var CascadePersistManager */ private $cascade; /** * @param RowValidator $validator */ public function __construct(RowValidator $validator, CascadePersistManager $cascade) { $this->validator = $validator; $this->cascade = $cascade; } /** * @param int $row * @param array $attributes */ public function add(int $row, array $attributes) { $this->rows[$row] = $attributes; } /** * @param bool $remembersRowNumber */ public function setRemembersRowNumber(bool $remembersRowNumber) { $this->remembersRowNumber = $remembersRowNumber; } /** * @param ToModel $import * @param bool $massInsert * * @throws ValidationException */ public function flush(ToModel $import, bool $massInsert = false) { if ($import instanceof WithValidation) { $this->validateRows($import); } if ($massInsert) { $this->massFlush($import); } else { $this->singleFlush($import); } $this->rows = []; } /** * @param ToModel $import * @param array $attributes * @param int|null $rowNumber * @return Model[]|Collection */ public function toModels(ToModel $import, array $attributes, $rowNumber = null): Collection { if ($this->remembersRowNumber) { $import->rememberRowNumber($rowNumber); } return Collection::wrap($import->model($attributes)); } /** * @param ToModel $import */ private function massFlush(ToModel $import) { $this->rows() ->flatMap(function (array $attributes, $index) use ($import) { return $this->toModels($import, $attributes, $index); }) ->mapToGroups(function ($model) { return [\get_class($model) => $this->prepare($model)->getAttributes()]; }) ->each(function (Collection $models, string $model) use ($import) { try { /* @var Model $model */ if ($import instanceof WithUpserts) { $model::query()->upsert( $models->toArray(), $import->uniqueBy(), $import instanceof WithUpsertColumns ? $import->upsertColumns() : null ); return; } $model::query()->insert($models->toArray()); } catch (Throwable $e) { $this->handleException($import, $e); } }); } /** * @param ToModel $import */ private function singleFlush(ToModel $import) { $this ->rows() ->each(function (array $attributes, $index) use ($import) { $this->toModels($import, $attributes, $index)->each(function (Model $model) use ($import) { try { if ($import instanceof WithUpserts) { $model->upsert( $model->getAttributes(), $import->uniqueBy(), $import instanceof WithUpsertColumns ? $import->upsertColumns() : null ); return; } if ($import instanceof PersistRelations) { $this->cascade->persist($model); } else { $model->saveOrFail(); } } catch (Throwable $e) { $this->handleException($import, $e); } }); }); } /** * @param Model $model * @return Model */ private function prepare(Model $model): Model { if ($model->usesTimestamps()) { $time = $model->freshTimestamp(); $updatedAtColumn = $model->getUpdatedAtColumn(); // If model has updated at column and not manually provided. if ($updatedAtColumn && null === $model->{$updatedAtColumn}) { $model->setUpdatedAt($time); } $createdAtColumn = $model->getCreatedAtColumn(); // If model has created at column and not manually provided. if ($createdAtColumn && null === $model->{$createdAtColumn}) { $model->setCreatedAt($time); } } return $model; } /** * @param WithValidation $import * * @throws ValidationException */ private function validateRows(WithValidation $import) { try { $this->validator->validate($this->rows, $import); } catch (RowSkippedException $e) { foreach ($e->skippedRows() as $row) { unset($this->rows[$row]); } } } /** * @return Collection */ private function rows(): Collection { return new Collection($this->rows); } private function handleException(ToModel $import, Throwable $e): void { if (!$import instanceof SkipsOnError) { throw $e; } $import->onError($e); } } excel/src/Concerns/WithStartRow.php 0000644 00000000221 15060131672 0013333 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithStartRow { /** * @return int */ public function startRow(): int; } excel/src/Concerns/WithUpserts.php 0000644 00000000224 15060131672 0013216 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithUpserts { /** * @return string|array */ public function uniqueBy(); } excel/src/Concerns/WithGroupedHeadingRow.php 0000644 00000000151 15060131672 0015125 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithGroupedHeadingRow extends WithHeadingRow { } excel/src/Concerns/SkipsErrors.php 0000644 00000000727 15060131672 0013213 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Support\Collection; use Throwable; trait SkipsErrors { /** * @var Throwable[] */ protected $errors = []; /** * @param Throwable $e */ public function onError(Throwable $e) { $this->errors[] = $e; } /** * @return Throwable[]|Collection */ public function errors(): Collection { return new Collection($this->errors); } } excel/src/Concerns/WithMappedCells.php 0000644 00000000227 15060131672 0013745 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithMappedCells { /** * @return array */ public function mapping(): array; } excel/src/Concerns/WithHeadingRow.php 0000644 00000000113 15060131672 0013575 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithHeadingRow { } excel/src/Concerns/WithProgressBar.php 0000644 00000000321 15060131672 0014000 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Console\OutputStyle; interface WithProgressBar { /** * @return OutputStyle */ public function getConsoleOutput(): OutputStyle; } excel/src/Concerns/ShouldQueueWithoutChain.php 0000644 00000000225 15060131672 0015510 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Contracts\Queue\ShouldQueue; interface ShouldQueueWithoutChain extends ShouldQueue { } excel/src/Concerns/WithEvents.php 0000644 00000000231 15060131672 0013013 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithEvents { /** * @return array */ public function registerEvents(): array; } excel/src/Concerns/WithProperties.php 0000644 00000000164 15060131672 0013710 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithProperties { public function properties(): array; } excel/src/Concerns/Exportable.php 0000644 00000006277 15060131672 0013040 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Foundation\Bus\PendingDispatch; use Maatwebsite\Excel\Exceptions\NoFilenameGivenException; use Maatwebsite\Excel\Exceptions\NoFilePathGivenException; use Maatwebsite\Excel\Exporter; trait Exportable { /** * @param string $fileName * @param string|null $writerType * @param array $headers * @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\BinaryFileResponse * * @throws NoFilenameGivenException */ public function download(string $fileName = null, string $writerType = null, array $headers = null) { $headers = $headers ?? $this->headers ?? []; $fileName = $fileName ?? $this->fileName ?? null; $writerType = $writerType ?? $this->writerType ?? null; if (null === $fileName) { throw new NoFilenameGivenException(); } return $this->getExporter()->download($this, $fileName, $writerType, $headers); } /** * @param string $filePath * @param string|null $disk * @param string|null $writerType * @param mixed $diskOptions * @return bool|PendingDispatch * * @throws NoFilePathGivenException */ public function store(string $filePath = null, string $disk = null, string $writerType = null, $diskOptions = []) { $filePath = $filePath ?? $this->filePath ?? null; if (null === $filePath) { throw NoFilePathGivenException::export(); } return $this->getExporter()->store( $this, $filePath, $disk ?? $this->disk ?? null, $writerType ?? $this->writerType ?? null, $diskOptions ?: $this->diskOptions ?? [] ); } /** * @param string|null $filePath * @param string|null $disk * @param string|null $writerType * @param mixed $diskOptions * @return PendingDispatch * * @throws NoFilePathGivenException */ public function queue(string $filePath = null, string $disk = null, string $writerType = null, $diskOptions = []) { $filePath = $filePath ?? $this->filePath ?? null; if (null === $filePath) { throw NoFilePathGivenException::export(); } return $this->getExporter()->queue( $this, $filePath, $disk ?? $this->disk ?? null, $writerType ?? $this->writerType ?? null, $diskOptions ?: $this->diskOptions ?? [] ); } /** * @param string|null $writerType * @return string */ public function raw($writerType = null) { $writerType = $writerType ?? $this->writerType ?? null; return $this->getExporter()->raw($this, $writerType); } /** * Create an HTTP response that represents the object. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response * * @throws NoFilenameGivenException */ public function toResponse($request) { return $this->download(); } /** * @return Exporter */ private function getExporter(): Exporter { return app(Exporter::class); } } excel/src/Concerns/WithCalculatedFormulas.php 0000644 00000000123 15060131672 0015321 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithCalculatedFormulas { } excel/src/Concerns/WithReadFilter.php 0000644 00000000327 15060131672 0013576 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Reader\IReadFilter; interface WithReadFilter { /** * @return IReadFilter */ public function readFilter(): IReadFilter; } excel/src/Concerns/WithUpsertColumns.php 0000644 00000000230 15060131672 0014371 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithUpsertColumns { /** * @return array */ public function upsertColumns(); } excel/src/Concerns/WithHeadings.php 0000644 00000000225 15060131672 0013274 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithHeadings { /** * @return array */ public function headings(): array; } excel/src/Concerns/PersistRelations.php 0000644 00000000115 15060131672 0014226 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface PersistRelations { } excel/src/Concerns/FromGenerator.php 0000644 00000000257 15060131672 0013475 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Generator; interface FromGenerator { /** * @return Generator */ public function generator(): Generator; } excel/src/Concerns/SkipsEmptyRows.php 0000644 00000000113 15060131672 0013675 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface SkipsEmptyRows { } excel/src/Concerns/WithValidation.php 0000644 00000000224 15060131672 0013643 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithValidation { /** * @return array */ public function rules(): array; } excel/src/Concerns/OnEachRow.php 0000644 00000000260 15060131672 0012542 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Maatwebsite\Excel\Row; interface OnEachRow { /** * @param Row $row */ public function onRow(Row $row); } excel/src/Concerns/ToModel.php 0000644 00000000341 15060131672 0012260 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Database\Eloquent\Model; interface ToModel { /** * @param array $row * @return Model|Model[]|null */ public function model(array $row); } excel/src/Concerns/ToCollection.php 0000644 00000000334 15060131672 0013315 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Support\Collection; interface ToCollection { /** * @param Collection $collection */ public function collection(Collection $collection); } excel/src/Concerns/RemembersChunkOffset.php 0000644 00000000651 15060131672 0015002 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; trait RemembersChunkOffset { /** * @var int|null */ protected $chunkOffset; /** * @param int $chunkOffset */ public function setChunkOffset(int $chunkOffset) { $this->chunkOffset = $chunkOffset; } /** * @return int|null */ public function getChunkOffset() { return $this->chunkOffset; } } excel/src/Concerns/HasReferencesToOtherSheets.php 0000644 00000000127 15060131672 0016115 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface HasReferencesToOtherSheets { } excel/src/Concerns/FromQuery.php 0000644 00000000565 15060131672 0012656 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Query\Builder; use Laravel\Scout\Builder as ScoutBuilder; interface FromQuery { /** * @return Builder|EloquentBuilder|Relation|ScoutBuilder */ public function query(); } excel/src/Concerns/ShouldAutoSize.php 0000644 00000000113 15060131672 0013634 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface ShouldAutoSize { } excel/src/Concerns/WithCharts.php 0000644 00000000275 15060131672 0013003 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Chart\Chart; interface WithCharts { /** * @return Chart|Chart[] */ public function charts(); } excel/src/Concerns/WithMapping.php 0000644 00000000326 15060131672 0013147 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; /** * @template RowType of mixed */ interface WithMapping { /** * @param RowType $row * @return array */ public function map($row): array; } excel/src/Concerns/FromCollection.php 0000644 00000000273 15060131672 0013640 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Support\Collection; interface FromCollection { /** * @return Collection */ public function collection(); } excel/src/Concerns/FromIterator.php 0000644 00000000252 15060131672 0013333 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Iterator; interface FromIterator { /** * @return Iterator */ public function iterator(): Iterator; } excel/src/Concerns/WithDrawings.php 0000644 00000000327 15060131672 0013333 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; interface WithDrawings { /** * @return BaseDrawing|BaseDrawing[] */ public function drawings(); } excel/src/Concerns/RegistersEventListeners.php 0000644 00000002565 15060131672 0015571 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Maatwebsite\Excel\Events\AfterBatch; use Maatwebsite\Excel\Events\AfterChunk; use Maatwebsite\Excel\Events\AfterImport; use Maatwebsite\Excel\Events\AfterSheet; use Maatwebsite\Excel\Events\BeforeExport; use Maatwebsite\Excel\Events\BeforeImport; use Maatwebsite\Excel\Events\BeforeSheet; use Maatwebsite\Excel\Events\BeforeWriting; use Maatwebsite\Excel\Events\ImportFailed; trait RegistersEventListeners { /** * @return array */ public function registerEvents(): array { $listenersClasses = [ BeforeExport::class => 'beforeExport', BeforeWriting::class => 'beforeWriting', BeforeImport::class => 'beforeImport', AfterImport::class => 'afterImport', AfterBatch::class => 'afterBatch', AfterChunk::class => 'afterChunk', ImportFailed::class => 'importFailed', BeforeSheet::class => 'beforeSheet', AfterSheet::class => 'afterSheet', ]; $listeners = []; foreach ($listenersClasses as $class => $name) { // Method names are case insensitive in php if (method_exists($this, $name)) { // Allow methods to not be static $listeners[$class] = [$this, $name]; } } return $listeners; } } excel/src/Concerns/WithCustomValueBinder.php 0000644 00000000230 15060131672 0015141 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Cell\IValueBinder; interface WithCustomValueBinder extends IValueBinder { } excel/src/Concerns/WithDefaultStyles.php 0000644 00000000333 15060131672 0014342 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Style\Style; interface WithDefaultStyles { /** * @return array|void */ public function defaultStyles(Style $defaultStyle); } excel/src/Concerns/WithPreCalculateFormulas.php 0000644 00000000125 15060131672 0015626 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithPreCalculateFormulas { } excel/src/Concerns/WithStyles.php 0000644 00000000250 15060131672 0013033 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; interface WithStyles { public function styles(Worksheet $sheet); } excel/src/Concerns/WithMultipleSheets.php 0000644 00000000231 15060131672 0014516 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithMultipleSheets { /** * @return array */ public function sheets(): array; } excel/src/Concerns/WithStrictNullComparison.php 0000644 00000000125 15060131672 0015707 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithStrictNullComparison { } excel/src/Concerns/FromView.php 0000644 00000000260 15060131672 0012453 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Contracts\View\View; interface FromView { /** * @return View */ public function view(): View; } excel/src/Concerns/WithColumnWidths.php 0000644 00000000170 15060131672 0014171 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithColumnWidths { public function columnWidths(): array; } excel/src/Concerns/ToArray.php 0000644 00000000232 15060131672 0012275 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface ToArray { /** * @param array $array */ public function array(array $array); } excel/src/Concerns/WithChunkReading.php 0000644 00000000226 15060131672 0014115 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithChunkReading { /** * @return int */ public function chunkSize(): int; } excel/src/Concerns/WithCustomCsvSettings.php 0000644 00000000244 15060131672 0015222 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithCustomCsvSettings { /** * @return array */ public function getCsvSettings(): array; } excel/src/Concerns/WithColumnLimit.php 0000644 00000000165 15060131672 0014011 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithColumnLimit { public function endColumn(): string; } excel/src/Concerns/Importable.php 0000644 00000007504 15060131672 0013023 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Console\OutputStyle; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; use InvalidArgumentException; use Maatwebsite\Excel\Exceptions\NoFilePathGivenException; use Maatwebsite\Excel\Importer; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\HttpFoundation\File\UploadedFile; trait Importable { /** * @var OutputStyle|null */ protected $output; /** * @param string|UploadedFile|null $filePath * @param string|null $disk * @param string|null $readerType * @return Importer|PendingDispatch * * @throws NoFilePathGivenException */ public function import($filePath = null, string $disk = null, string $readerType = null) { $filePath = $this->getFilePath($filePath); return $this->getImporter()->import( $this, $filePath, $disk ?? $this->disk ?? null, $readerType ?? $this->readerType ?? null ); } /** * @param string|UploadedFile|null $filePath * @param string|null $disk * @param string|null $readerType * @return array * * @throws NoFilePathGivenException */ public function toArray($filePath = null, string $disk = null, string $readerType = null): array { $filePath = $this->getFilePath($filePath); return $this->getImporter()->toArray( $this, $filePath, $disk ?? $this->disk ?? null, $readerType ?? $this->readerType ?? null ); } /** * @param string|UploadedFile|null $filePath * @param string|null $disk * @param string|null $readerType * @return Collection * * @throws NoFilePathGivenException */ public function toCollection($filePath = null, string $disk = null, string $readerType = null): Collection { $filePath = $this->getFilePath($filePath); return $this->getImporter()->toCollection( $this, $filePath, $disk ?? $this->disk ?? null, $readerType ?? $this->readerType ?? null ); } /** * @param string|UploadedFile|null $filePath * @param string|null $disk * @param string|null $readerType * @return PendingDispatch * * @throws NoFilePathGivenException * @throws InvalidArgumentException */ public function queue($filePath = null, string $disk = null, string $readerType = null) { if (!$this instanceof ShouldQueue) { throw new InvalidArgumentException('Importable should implement ShouldQueue to be queued.'); } return $this->import($filePath, $disk, $readerType); } /** * @param OutputStyle $output * @return $this */ public function withOutput(OutputStyle $output) { $this->output = $output; return $this; } /** * @return OutputStyle */ public function getConsoleOutput(): OutputStyle { if (!$this->output instanceof OutputStyle) { $this->output = new OutputStyle(new StringInput(''), new NullOutput()); } return $this->output; } /** * @param UploadedFile|string|null $filePath * @return UploadedFile|string * * @throws NoFilePathGivenException */ private function getFilePath($filePath = null) { $filePath = $filePath ?? $this->filePath ?? null; if (null === $filePath) { throw NoFilePathGivenException::import(); } return $filePath; } /** * @return Importer */ private function getImporter(): Importer { return app(Importer::class); } } excel/src/Concerns/RemembersRowNumber.php 0000644 00000000627 15060131672 0014506 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; trait RemembersRowNumber { /** * @var int */ protected $rowNumber; /** * @param int $rowNumber */ public function rememberRowNumber(int $rowNumber) { $this->rowNumber = $rowNumber; } /** * @return int|null */ public function getRowNumber() { return $this->rowNumber; } } excel/src/Concerns/FromArray.php 0000644 00000000217 15060131672 0012621 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface FromArray { /** * @return array */ public function array(): array; } excel/src/Concerns/WithTitle.php 0000644 00000000221 15060131672 0012627 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithTitle { /** * @return string */ public function title(): string; } excel/src/Concerns/SkipsFailures.php 0000644 00000001055 15060131672 0013504 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Support\Collection; use Maatwebsite\Excel\Validators\Failure; trait SkipsFailures { /** * @var Failure[] */ protected $failures = []; /** * @param Failure ...$failures */ public function onFailure(Failure ...$failures) { $this->failures = array_merge($this->failures, $failures); } /** * @return Failure[]|Collection */ public function failures(): Collection { return new Collection($this->failures); } } excel/src/Concerns/WithConditionalSheets.php 0000644 00000001406 15060131672 0015173 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; trait WithConditionalSheets { /** * @var array */ protected $conditionallySelectedSheets = []; /** * @param string|array $sheets * @return $this */ public function onlySheets($sheets) { $this->conditionallySelectedSheets = is_array($sheets) ? $sheets : func_get_args(); return $this; } /** * @return array */ public function sheets(): array { return \array_filter($this->conditionalSheets(), function ($name) { return \in_array($name, $this->conditionallySelectedSheets, false); }, ARRAY_FILTER_USE_KEY); } /** * @return array */ abstract public function conditionalSheets(): array; } excel/src/Concerns/WithCustomChunkSize.php 0000644 00000000231 15060131672 0014645 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithCustomChunkSize { /** * @return int */ public function chunkSize(): int; } excel/src/Concerns/WithBatchInserts.php 0000644 00000000226 15060131672 0014144 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithBatchInserts { /** * @return int */ public function batchSize(): int; } excel/src/Concerns/MapsCsvSettings.php 0000644 00000004215 15060131672 0014016 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Illuminate\Support\Arr; trait MapsCsvSettings { /** * @var string */ protected static $delimiter = ','; /** * @var string */ protected static $enclosure = '"'; /** * @var string */ protected static $lineEnding = PHP_EOL; /** * @var bool */ protected static $useBom = false; /** * @var bool */ protected static $includeSeparatorLine = false; /** * @var bool */ protected static $excelCompatibility = false; /** * @var string */ protected static $escapeCharacter = '\\'; /** * @var bool */ protected static $contiguous = false; /** * @var string */ protected static $inputEncoding = 'UTF-8'; /** * @var string */ protected static $outputEncoding = ''; /** * @var bool */ protected static $testAutoDetect = true; /** * @param array $config */ public static function applyCsvSettings(array $config) { static::$delimiter = Arr::get($config, 'delimiter', static::$delimiter); static::$enclosure = Arr::get($config, 'enclosure', static::$enclosure); static::$lineEnding = Arr::get($config, 'line_ending', static::$lineEnding); static::$useBom = Arr::get($config, 'use_bom', static::$useBom); static::$includeSeparatorLine = Arr::get($config, 'include_separator_line', static::$includeSeparatorLine); static::$excelCompatibility = Arr::get($config, 'excel_compatibility', static::$excelCompatibility); static::$escapeCharacter = Arr::get($config, 'escape_character', static::$escapeCharacter); static::$contiguous = Arr::get($config, 'contiguous', static::$contiguous); static::$inputEncoding = Arr::get($config, 'input_encoding', static::$inputEncoding); static::$outputEncoding = Arr::get($config, 'output_encoding', static::$outputEncoding); static::$testAutoDetect = Arr::get($config, 'test_auto_detect', static::$testAutoDetect); } } excel/src/Concerns/WithFormatData.php 0000644 00000000113 15060131672 0013570 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithFormatData { } excel/src/Concerns/SkipsOnError.php 0000644 00000000261 15060131672 0013316 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Throwable; interface SkipsOnError { /** * @param Throwable $e */ public function onError(Throwable $e); } excel/src/Concerns/SkipsUnknownSheets.php 0000644 00000000265 15060131672 0014547 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface SkipsUnknownSheets { /** * @param string|int $sheetName */ public function onUnknownSheet($sheetName); } excel/src/Concerns/WithCustomStartCell.php 0000644 00000000237 15060131672 0014645 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithCustomStartCell { /** * @return string */ public function startCell(): string; } excel/src/Concerns/WithLimit.php 0000644 00000000213 15060131672 0012625 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithLimit { /** * @return int */ public function limit(): int; } excel/src/Concerns/WithCustomQuerySize.php 0000644 00000001245 15060131672 0014710 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithCustomQuerySize { /** * Queued exportables are processed in chunks; each chunk being a job pushed to the queue by the QueuedWriter. * In case of exportables that implement the FromQuery concern, the number of jobs is calculated by dividing the $query->count() by the chunk size. * Depending on the implementation of the query() method (eg. When using a groupBy clause), this calculation might not be correct. * * When this is the case, you should use this method to provide a custom calculation of the query size. * * @return int */ public function querySize(): int; } excel/src/Concerns/WithBackgroundColor.php 0000644 00000000324 15060131672 0014630 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use PhpOffice\PhpSpreadsheet\Style\Color; interface WithBackgroundColor { /** * @return string|array|Color */ public function backgroundColor(); } excel/src/Concerns/WithColumnFormatting.php 0000644 00000000242 15060131672 0015041 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; interface WithColumnFormatting { /** * @return array */ public function columnFormats(): array; } excel/src/Concerns/SkipsOnFailure.php 0000644 00000000337 15060131672 0013620 0 ustar 00 <?php namespace Maatwebsite\Excel\Concerns; use Maatwebsite\Excel\Validators\Failure; interface SkipsOnFailure { /** * @param Failure[] $failures */ public function onFailure(Failure ...$failures); } excel/src/Helpers/CellHelper.php 0000644 00000000437 15060131672 0012572 0 ustar 00 <?php namespace Maatwebsite\Excel\Helpers; class CellHelper { /** * @param string $coordinate * @return string */ public static function getColumnFromCoordinate(string $coordinate): string { return preg_replace('/[0-9]/', '', $coordinate); } } excel/src/Helpers/ArrayHelper.php 0000644 00000001170 15060131672 0012764 0 ustar 00 <?php namespace Maatwebsite\Excel\Helpers; class ArrayHelper { /** * @param array $array * @return array */ public static function ensureMultipleRows(array $array): array { if (static::hasMultipleRows($array)) { return $array; } return [$array]; } /** * Only have multiple rows, if each * element in the array is an array itself. * * @param array $array * @return bool */ public static function hasMultipleRows(array $array): bool { return count($array) === count(array_filter($array, 'is_array')); } } excel/src/Helpers/FileTypeDetector.php 0000644 00000002455 15060131672 0013770 0 ustar 00 <?php namespace Maatwebsite\Excel\Helpers; use Maatwebsite\Excel\Exceptions\NoTypeDetectedException; use Symfony\Component\HttpFoundation\File\UploadedFile; class FileTypeDetector { /** * @param $filePath * @param string|null $type * @return string|null * * @throws NoTypeDetectedException */ public static function detect($filePath, string $type = null) { if (null !== $type) { return $type; } if (!$filePath instanceof UploadedFile) { $pathInfo = pathinfo($filePath); $extension = $pathInfo['extension'] ?? ''; } else { $extension = $filePath->getClientOriginalExtension(); } if (null === $type && trim($extension) === '') { throw new NoTypeDetectedException(); } return config('excel.extension_detector.' . strtolower($extension)); } /** * @param string $filePath * @param string|null $type * @return string * * @throws NoTypeDetectedException */ public static function detectStrict(string $filePath, string $type = null): string { $type = static::detect($filePath, $type); if (!$type) { throw new NoTypeDetectedException(); } return $type; } } excel/src/Reader.php 0000644 00000033452 15060131672 0010356 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Support\Collection; use InvalidArgumentException; use Maatwebsite\Excel\Concerns\HasReferencesToOtherSheets; use Maatwebsite\Excel\Concerns\SkipsUnknownSheets; use Maatwebsite\Excel\Concerns\WithCalculatedFormulas; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithCustomValueBinder; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\WithFormatData; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Events\AfterImport; use Maatwebsite\Excel\Events\BeforeImport; use Maatwebsite\Excel\Events\ImportFailed; use Maatwebsite\Excel\Exceptions\NoTypeDetectedException; use Maatwebsite\Excel\Exceptions\SheetNotFoundException; use Maatwebsite\Excel\Factories\ReaderFactory; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Files\TemporaryFileFactory; use Maatwebsite\Excel\Transactions\TransactionHandler; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Reader\Exception; use PhpOffice\PhpSpreadsheet\Reader\IReader; use PhpOffice\PhpSpreadsheet\Spreadsheet; use Symfony\Component\HttpFoundation\File\UploadedFile; use Throwable; /** @mixin Spreadsheet */ class Reader { use DelegatedMacroable, HasEventBus; /** * @var Spreadsheet */ protected $spreadsheet; /** * @var object[] */ protected $sheetImports = []; /** * @var TemporaryFile */ protected $currentFile; /** * @var TemporaryFileFactory */ protected $temporaryFileFactory; /** * @var TransactionHandler */ protected $transaction; /** * @var IReader */ protected $reader; /** * @param TemporaryFileFactory $temporaryFileFactory * @param TransactionHandler $transaction */ public function __construct(TemporaryFileFactory $temporaryFileFactory, TransactionHandler $transaction) { $this->setDefaultValueBinder(); $this->transaction = $transaction; $this->temporaryFileFactory = $temporaryFileFactory; } public function __sleep() { return ['spreadsheet', 'sheetImports', 'currentFile', 'temporaryFileFactory', 'reader']; } public function __wakeup() { $this->transaction = app(TransactionHandler::class); } /** * @param object $import * @param string|UploadedFile $filePath * @param string|null $readerType * @param string|null $disk * @return \Illuminate\Foundation\Bus\PendingDispatch|$this * * @throws NoTypeDetectedException * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws Exception */ public function read($import, $filePath, string $readerType = null, string $disk = null) { $this->reader = $this->getReader($import, $filePath, $readerType, $disk); if ($import instanceof WithChunkReading) { return app(ChunkReader::class)->read($import, $this, $this->currentFile); } try { $this->loadSpreadsheet($import); ($this->transaction)(function () use ($import) { $sheetsToDisconnect = []; foreach ($this->sheetImports as $index => $sheetImport) { if ($sheet = $this->getSheet($import, $sheetImport, $index)) { $sheet->import($sheetImport, $sheet->getStartRow($sheetImport)); // when using WithCalculatedFormulas we need to keep the sheet until all sheets are imported if (!($sheetImport instanceof HasReferencesToOtherSheets)) { $sheet->disconnect(); } else { $sheetsToDisconnect[] = $sheet; } } } foreach ($sheetsToDisconnect as $sheet) { $sheet->disconnect(); } }); $this->afterImport($import); } catch (Throwable $e) { $this->raise(new ImportFailed($e)); $this->garbageCollect(); throw $e; } return $this; } /** * @param object $import * @param string|UploadedFile $filePath * @param string $readerType * @param string|null $disk * @return array * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws NoTypeDetectedException * @throws Exceptions\SheetNotFoundException */ public function toArray($import, $filePath, string $readerType = null, string $disk = null): array { $this->reader = $this->getReader($import, $filePath, $readerType, $disk); $this->loadSpreadsheet($import); $sheets = []; $sheetsToDisconnect = []; foreach ($this->sheetImports as $index => $sheetImport) { $calculatesFormulas = $sheetImport instanceof WithCalculatedFormulas; $formatData = $sheetImport instanceof WithFormatData; if ($sheet = $this->getSheet($import, $sheetImport, $index)) { $sheets[$index] = $sheet->toArray($sheetImport, $sheet->getStartRow($sheetImport), null, $calculatesFormulas, $formatData); // when using WithCalculatedFormulas we need to keep the sheet until all sheets are imported if (!($sheetImport instanceof HasReferencesToOtherSheets)) { $sheet->disconnect(); } else { $sheetsToDisconnect[] = $sheet; } } } foreach ($sheetsToDisconnect as $sheet) { $sheet->disconnect(); } $this->afterImport($import); return $sheets; } /** * @param object $import * @param string|UploadedFile $filePath * @param string $readerType * @param string|null $disk * @return Collection * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws NoTypeDetectedException * @throws Exceptions\SheetNotFoundException */ public function toCollection($import, $filePath, string $readerType = null, string $disk = null): Collection { $this->reader = $this->getReader($import, $filePath, $readerType, $disk); $this->loadSpreadsheet($import); $sheets = new Collection(); $sheetsToDisconnect = []; foreach ($this->sheetImports as $index => $sheetImport) { $calculatesFormulas = $sheetImport instanceof WithCalculatedFormulas; $formatData = $sheetImport instanceof WithFormatData; if ($sheet = $this->getSheet($import, $sheetImport, $index)) { $sheets->put($index, $sheet->toCollection($sheetImport, $sheet->getStartRow($sheetImport), null, $calculatesFormulas, $formatData)); // when using WithCalculatedFormulas we need to keep the sheet until all sheets are imported if (!($sheetImport instanceof HasReferencesToOtherSheets)) { $sheet->disconnect(); } else { $sheetsToDisconnect[] = $sheet; } } } foreach ($sheetsToDisconnect as $sheet) { $sheet->disconnect(); } $this->afterImport($import); return $sheets; } /** * @return Spreadsheet */ public function getDelegate() { return $this->spreadsheet; } /** * @return $this */ public function setDefaultValueBinder(): self { Cell::setValueBinder( app(config('excel.value_binder.default', DefaultValueBinder::class)) ); return $this; } /** * @param object $import */ public function loadSpreadsheet($import) { $this->sheetImports = $this->buildSheetImports($import); $this->readSpreadsheet(); // When no multiple sheets, use the main import object // for each loaded sheet in the spreadsheet if (!$import instanceof WithMultipleSheets) { $this->sheetImports = array_fill(0, $this->spreadsheet->getSheetCount(), $import); } $this->beforeImport($import); } public function readSpreadsheet() { $this->spreadsheet = $this->reader->load( $this->currentFile->getLocalPath() ); } /** * @param object $import */ public function beforeImport($import) { $this->raise(new BeforeImport($this, $import)); } /** * @param object $import */ public function afterImport($import) { $this->raise(new AfterImport($this, $import)); $this->garbageCollect(); } /** * @return IReader */ public function getPhpSpreadsheetReader(): IReader { return $this->reader; } /** * @param object $import * @return array */ public function getWorksheets($import): array { // Csv doesn't have worksheets. if (!method_exists($this->reader, 'listWorksheetNames')) { return ['Worksheet' => $import]; } $worksheets = []; $worksheetNames = $this->reader->listWorksheetNames($this->currentFile->getLocalPath()); if ($import instanceof WithMultipleSheets) { $sheetImports = $import->sheets(); foreach ($sheetImports as $index => $sheetImport) { // Translate index to name. if (is_numeric($index)) { $index = $worksheetNames[$index] ?? $index; } // Specify with worksheet name should have which import. $worksheets[$index] = $sheetImport; } // Load specific sheets. if (method_exists($this->reader, 'setLoadSheetsOnly')) { $this->reader->setLoadSheetsOnly( collect($worksheetNames)->intersect(array_keys($worksheets))->values()->all() ); } } else { // Each worksheet the same import class. foreach ($worksheetNames as $name) { $worksheets[$name] = $import; } } return $worksheets; } /** * @return array */ public function getTotalRows(): array { $info = $this->reader->listWorksheetInfo($this->currentFile->getLocalPath()); $totalRows = []; foreach ($info as $sheet) { $totalRows[$sheet['worksheetName']] = $sheet['totalRows']; } return $totalRows; } /** * @param $import * @param $sheetImport * @param $index * @return Sheet|null * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws SheetNotFoundException */ protected function getSheet($import, $sheetImport, $index) { try { return Sheet::make($this->spreadsheet, $index); } catch (SheetNotFoundException $e) { if ($import instanceof SkipsUnknownSheets) { $import->onUnknownSheet($index); return null; } if ($sheetImport instanceof SkipsUnknownSheets) { $sheetImport->onUnknownSheet($index); return null; } throw $e; } } /** * @param object $import * @return array */ private function buildSheetImports($import): array { $sheetImports = []; if ($import instanceof WithMultipleSheets) { $sheetImports = $import->sheets(); // When only sheet names are given and the reader has // an option to load only the selected sheets. if ( method_exists($this->reader, 'setLoadSheetsOnly') && count(array_filter(array_keys($sheetImports), 'is_numeric')) === 0 ) { $this->reader->setLoadSheetsOnly(array_keys($sheetImports)); } } return $sheetImports; } /** * @param object $import * @param string|UploadedFile $filePath * @param string|null $readerType * @param string $disk * @return IReader * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws NoTypeDetectedException * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception * @throws InvalidArgumentException */ private function getReader($import, $filePath, string $readerType = null, string $disk = null): IReader { $shouldQueue = $import instanceof ShouldQueue; if ($shouldQueue && !$import instanceof WithChunkReading) { throw new InvalidArgumentException('ShouldQueue is only supported in combination with WithChunkReading.'); } if ($import instanceof WithEvents) { $this->registerListeners($import->registerEvents()); } if ($import instanceof WithCustomValueBinder) { Cell::setValueBinder($import); } $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION); $temporaryFile = $shouldQueue ? $this->temporaryFileFactory->make($fileExtension) : $this->temporaryFileFactory->makeLocal(null, $fileExtension); $this->currentFile = $temporaryFile->copyFrom( $filePath, $disk ); return ReaderFactory::make( $import, $this->currentFile, $readerType ); } /** * Garbage collect. */ private function garbageCollect() { $this->clearListeners(); $this->setDefaultValueBinder(); // Force garbage collecting unset($this->sheetImports, $this->spreadsheet); $this->currentFile->delete(); } } excel/src/Events/AfterBatch.php 0000644 00000002105 15060131672 0012412 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Imports\ModelManager; class AfterBatch extends Event { /** * @var ModelManager */ public $manager; /** * @var int */ private $batchSize; /** * @var int */ private $startRow; /** * @param ModelManager $manager * @param object $importable * @param int $batchSize * @param int $startRow */ public function __construct(ModelManager $manager, $importable, int $batchSize, int $startRow) { $this->manager = $manager; $this->batchSize = $batchSize; $this->startRow = $startRow; parent::__construct($importable); } public function getManager(): ModelManager { return $this->manager; } /** * @return mixed */ public function getDelegate() { return $this->manager; } public function getBatchSize(): int { return $this->batchSize; } public function getStartRow(): int { return $this->startRow; } } excel/src/Events/ImportFailed.php 0000644 00000000604 15060131672 0012770 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Throwable; class ImportFailed { /** * @var Throwable */ public $e; /** * @param Throwable $e */ public function __construct(Throwable $e) { $this->e = $e; } /** * @return Throwable */ public function getException(): Throwable { return $this->e; } } excel/src/Events/BeforeExport.php 0000644 00000001175 15060131672 0013021 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Writer; class BeforeExport extends Event { /** * @var Writer */ public $writer; /** * @param Writer $writer * @param object $exportable */ public function __construct(Writer $writer, $exportable) { $this->writer = $writer; parent::__construct($exportable); } /** * @return Writer */ public function getWriter(): Writer { return $this->writer; } /** * @return mixed */ public function getDelegate() { return $this->writer; } } excel/src/Events/AfterImport.php 0000644 00000001174 15060131672 0012650 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Reader; class AfterImport extends Event { /** * @var Reader */ public $reader; /** * @param Reader $reader * @param object $importable */ public function __construct(Reader $reader, $importable) { $this->reader = $reader; parent::__construct($importable); } /** * @return Reader */ public function getReader(): Reader { return $this->reader; } /** * @return mixed */ public function getDelegate() { return $this->reader; } } excel/src/Events/BeforeSheet.php 0000644 00000001160 15060131672 0012602 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Sheet; class BeforeSheet extends Event { /** * @var Sheet */ public $sheet; /** * @param Sheet $sheet * @param object $exportable */ public function __construct(Sheet $sheet, $exportable) { $this->sheet = $sheet; parent::__construct($exportable); } /** * @return Sheet */ public function getSheet(): Sheet { return $this->sheet; } /** * @return mixed */ public function getDelegate() { return $this->sheet; } } excel/src/Events/BeforeImport.php 0000644 00000001175 15060131672 0013012 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Reader; class BeforeImport extends Event { /** * @var Reader */ public $reader; /** * @param Reader $reader * @param object $importable */ public function __construct(Reader $reader, $importable) { $this->reader = $reader; parent::__construct($importable); } /** * @return Reader */ public function getReader(): Reader { return $this->reader; } /** * @return mixed */ public function getDelegate() { return $this->reader; } } excel/src/Events/AfterChunk.php 0000644 00000001225 15060131672 0012443 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Sheet; class AfterChunk extends Event { /** * @var Sheet */ private $sheet; /** * @var int */ private $startRow; public function __construct(Sheet $sheet, $importable, int $startRow) { $this->sheet = $sheet; $this->startRow = $startRow; parent::__construct($importable); } public function getSheet(): Sheet { return $this->sheet; } public function getDelegate() { return $this->sheet; } public function getStartRow(): int { return $this->startRow; } } excel/src/Events/AfterSheet.php 0000644 00000001156 15060131672 0012446 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Sheet; class AfterSheet extends Event { /** * @var Sheet */ public $sheet; /** * @param Sheet $sheet * @param object $exportable */ public function __construct(Sheet $sheet, $exportable) { $this->sheet = $sheet; parent::__construct($exportable); } /** * @return Sheet */ public function getSheet(): Sheet { return $this->sheet; } /** * @return mixed */ public function getDelegate() { return $this->sheet; } } excel/src/Events/BeforeWriting.php 0000644 00000001273 15060131672 0013162 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; use Maatwebsite\Excel\Writer; class BeforeWriting extends Event { /** * @var Writer */ public $writer; /** * @var object */ private $exportable; /** * @param Writer $writer * @param object $exportable */ public function __construct(Writer $writer, $exportable) { $this->writer = $writer; parent::__construct($exportable); } /** * @return Writer */ public function getWriter(): Writer { return $this->writer; } /** * @return mixed */ public function getDelegate() { return $this->writer; } } excel/src/Events/Event.php 0000644 00000001311 15060131672 0011466 0 ustar 00 <?php namespace Maatwebsite\Excel\Events; /** * @internal */ abstract class Event { /** * @var object */ protected $concernable; /** * @param object $concernable */ public function __construct($concernable) { $this->concernable = $concernable; } /** * @return object */ public function getConcernable() { return $this->concernable; } /** * @return mixed */ abstract public function getDelegate(); /** * @param string $concern * @return bool */ public function appliesToConcern(string $concern): bool { return $this->getConcernable() instanceof $concern; } } excel/src/Fakes/fake_file 0000644 00000000000 15060131672 0011303 0 ustar 00 excel/src/Fakes/ExcelFake.php 0000644 00000024124 15060131672 0012030 0 ustar 00 <?php namespace Maatwebsite\Excel\Fakes; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Queue; use Maatwebsite\Excel\Exporter; use Maatwebsite\Excel\Importer; use Maatwebsite\Excel\Reader; use PHPUnit\Framework\Assert; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\File\UploadedFile; class ExcelFake implements Exporter, Importer { /** * @var array */ protected $downloads = []; /** * @var array */ protected $stored = []; /** * @var array */ protected $queued = []; /** * @var array */ protected $raws = []; /** * @var array */ protected $imported = []; /** * @var bool */ protected $matchByRegex = false; /** * @var object|null */ protected $job; /** * {@inheritdoc} */ public function download($export, string $fileName, string $writerType = null, array $headers = []) { $this->downloads[$fileName] = $export; return new BinaryFileResponse(__DIR__ . '/fake_file'); } /** * {@inheritdoc} * * @param string|null $diskName Fallback for usage with named properties */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [], string $diskName = null) { if ($export instanceof ShouldQueue) { return $this->queue($export, $filePath, $disk ?: $diskName, $writerType); } $this->stored[$disk ?: $diskName ?: 'default'][$filePath] = $export; return true; } /** * {@inheritdoc} */ public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { Queue::fake(); $this->stored[$disk ?? 'default'][$filePath] = $export; $this->queued[$disk ?? 'default'][$filePath] = $export; $this->job = new class { use Queueable; public function handle() { // } }; Queue::push($this->job); return new PendingDispatch($this->job); } /** * @param object $export * @param string $writerType * @return string */ public function raw($export, string $writerType) { $this->raws[get_class($export)] = $export; return 'RAW-CONTENTS'; } /** * @param object $import * @param string|UploadedFile $file * @param string|null $disk * @param string|null $readerType * @return Reader|PendingDispatch */ public function import($import, $file, string $disk = null, string $readerType = null) { if ($import instanceof ShouldQueue) { return $this->queueImport($import, $file, $disk, $readerType); } $filePath = ($file instanceof UploadedFile) ? $file->getClientOriginalName() : $file; $this->imported[$disk ?? 'default'][$filePath] = $import; return $this; } /** * @param object $import * @param string|UploadedFile $file * @param string|null $disk * @param string|null $readerType * @return array */ public function toArray($import, $file, string $disk = null, string $readerType = null): array { $filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file; $this->imported[$disk ?? 'default'][$filePath] = $import; return []; } /** * @param object $import * @param string|UploadedFile $file * @param string|null $disk * @param string|null $readerType * @return Collection */ public function toCollection($import, $file, string $disk = null, string $readerType = null): Collection { $filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file; $this->imported[$disk ?? 'default'][$filePath] = $import; return new Collection(); } /** * @param ShouldQueue $import * @param string|UploadedFile $file * @param string|null $disk * @param string $readerType * @return PendingDispatch */ public function queueImport(ShouldQueue $import, $file, string $disk = null, string $readerType = null) { Queue::fake(); $filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file; $this->queued[$disk ?? 'default'][$filePath] = $import; $this->imported[$disk ?? 'default'][$filePath] = $import; $this->job = new class { use Queueable; public function handle() { // } }; Queue::push($this->job); return new PendingDispatch($this->job); } /** * When asserting downloaded, stored, queued or imported, use regular expression * to look for a matching file path. * * @return void */ public function matchByRegex() { $this->matchByRegex = true; } /** * When asserting downloaded, stored, queued or imported, use regular string * comparison for matching file path. * * @return void */ public function doNotMatchByRegex() { $this->matchByRegex = false; } /** * @param string $fileName * @param callable|null $callback */ public function assertDownloaded(string $fileName, $callback = null) { $fileName = $this->assertArrayHasKey($fileName, $this->downloads, sprintf('%s is not downloaded', $fileName)); $callback = $callback ?: function () { return true; }; Assert::assertTrue( $callback($this->downloads[$fileName]), "The file [{$fileName}] was not downloaded with the expected data." ); } /** * @param string $filePath * @param string|callable|null $disk * @param callable|null $callback */ public function assertStored(string $filePath, $disk = null, $callback = null) { if (is_callable($disk)) { $callback = $disk; $disk = null; } $disk = $disk ?? 'default'; $storedOnDisk = $this->stored[$disk] ?? []; $filePath = $this->assertArrayHasKey( $filePath, $storedOnDisk, sprintf('%s is not stored on disk %s', $filePath, $disk) ); $callback = $callback ?: function () { return true; }; Assert::assertTrue( $callback($storedOnDisk[$filePath]), "The file [{$filePath}] was not stored with the expected data." ); } /** * @param string $filePath * @param string|callable|null $disk * @param callable|null $callback */ public function assertQueued(string $filePath, $disk = null, $callback = null) { if (is_callable($disk)) { $callback = $disk; $disk = null; } $disk = $disk ?? 'default'; $queuedForDisk = $this->queued[$disk] ?? []; $filePath = $this->assertArrayHasKey( $filePath, $queuedForDisk, sprintf('%s is not queued for export on disk %s', $filePath, $disk) ); $callback = $callback ?: function () { return true; }; Assert::assertTrue( $callback($queuedForDisk[$filePath]), "The file [{$filePath}] was not stored with the expected data." ); } public function assertQueuedWithChain($chain): void { Queue::assertPushedWithChain(get_class($this->job), $chain); } /** * @param string $classname * @param callable|null $callback */ public function assertExportedInRaw(string $classname, $callback = null) { Assert::assertArrayHasKey($classname, $this->raws, sprintf('%s is not exported in raw', $classname)); $callback = $callback ?: function () { return true; }; Assert::assertTrue( $callback($this->raws[$classname]), "The [{$classname}] export was not exported in raw with the expected data." ); } /** * @param string $filePath * @param string|callable|null $disk * @param callable|null $callback */ public function assertImported(string $filePath, $disk = null, $callback = null) { if (is_callable($disk)) { $callback = $disk; $disk = null; } $disk = $disk ?? 'default'; $importedOnDisk = $this->imported[$disk] ?? []; $filePath = $this->assertArrayHasKey( $filePath, $importedOnDisk, sprintf('%s is not stored on disk %s', $filePath, $disk) ); $callback = $callback ?: function () { return true; }; Assert::assertTrue( $callback($importedOnDisk[$filePath]), "The file [{$filePath}] was not imported with the expected data." ); } /** * Asserts that an array has a specified key and returns the key if successful. * * @see matchByRegex for more information about file path matching * * @param string $key * @param array $array * @param string $message * @return string * * @throws ExpectationFailedException * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException * @throws Exception */ protected function assertArrayHasKey(string $key, array $disk, string $message = ''): string { if ($this->matchByRegex) { $files = array_keys($disk); $results = preg_grep($key, $files); Assert::assertGreaterThan(0, count($results), $message); Assert::assertEquals(1, count($results), "More than one result matches the file name expression '$key'."); return array_values($results)[0]; } Assert::assertArrayHasKey($key, $disk, $message); return $key; } } excel/src/Mixins/StoreQueryMacro.php 0000644 00000003565 15060131672 0013531 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Database\Eloquent\Builder; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Sheet; class StoreQueryMacro { public function __invoke() { return function (string $filePath, string $disk = null, string $writerType = null, $withHeadings = false) { $export = new class($this, $withHeadings) implements FromQuery, WithHeadings { use Exportable; /** * @var bool */ private $withHeadings; /** * @var Builder */ private $query; /** * @param $query * @param bool $withHeadings */ public function __construct($query, bool $withHeadings = false) { $this->query = $query; $this->withHeadings = $withHeadings; } /** * @return Builder */ public function query() { return $this->query; } /** * @return array */ public function headings(): array { if (!$this->withHeadings) { return []; } $firstRow = (clone $this->query)->first(); if ($firstRow) { return array_keys(Sheet::mapArraybleRow($firstRow)); } return []; } }; return $export->store($filePath, $disk, $writerType); }; } } excel/src/Mixins/StoreCollectionMixin.php 0000644 00000003660 15060131672 0014536 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\WithHeadings; class StoreCollectionMixin { /** * @return callable */ public function storeExcel() { return function (string $filePath, string $disk = null, string $writerType = null, $withHeadings = false) { $export = new class($this, $withHeadings) implements FromCollection, WithHeadings { use Exportable; /** * @var bool */ private $withHeadings; /** * @var Collection */ private $collection; /** * @param Collection $collection * @param bool $withHeadings */ public function __construct(Collection $collection, bool $withHeadings = false) { $this->collection = $collection->toBase(); $this->withHeadings = $withHeadings; } /** * @return Collection */ public function collection() { return $this->collection; } /** * @return array */ public function headings(): array { if (!$this->withHeadings) { return []; } return is_array($first = $this->collection->first()) ? $this->collection->collapse()->keys()->all() : array_keys($first->toArray()); } }; return $export->store($filePath, $disk, $writerType); }; } } excel/src/Mixins/ImportMacro.php 0000644 00000002266 15060131672 0012656 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Database\Eloquent\Model; use Maatwebsite\Excel\Concerns\Importable; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithHeadingRow; class ImportMacro { public function __invoke() { return function (string $filename, string $disk = null, string $readerType = null) { $import = new class(get_class($this->getModel())) implements ToModel, WithHeadingRow { use Importable; /** * @var string */ private $model; /** * @param string $model */ public function __construct(string $model) { $this->model = $model; } /** * @param array $row * @return Model|Model[]|null */ public function model(array $row) { return (new $this->model)->fill($row); } }; return $import->import($filename, $disk, $readerType); }; } } excel/src/Mixins/DownloadCollectionMixin.php 0000644 00000004206 15060131672 0015206 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Sheet; class DownloadCollectionMixin { /** * @return callable */ public function downloadExcel() { return function (string $fileName, string $writerType = null, $withHeadings = false, array $responseHeaders = []) { $export = new class($this, $withHeadings) implements FromCollection, WithHeadings { use Exportable; /** * @var bool */ private $withHeadings; /** * @var Collection */ private $collection; /** * @param Collection $collection * @param bool $withHeading */ public function __construct(Collection $collection, bool $withHeading = false) { $this->collection = $collection->toBase(); $this->withHeadings = $withHeading; } /** * @return Collection */ public function collection() { return $this->collection; } /** * @return array */ public function headings(): array { if (!$this->withHeadings) { return []; } $firstRow = $this->collection->first(); if ($firstRow instanceof Arrayable || \is_object($firstRow)) { return array_keys(Sheet::mapArraybleRow($firstRow)); } return $this->collection->collapse()->keys()->all(); } }; return $export->download($fileName, $writerType, $responseHeaders); }; } } excel/src/Mixins/ImportAsMacro.php 0000644 00000002664 15060131672 0013144 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Database\Eloquent\Model; use Maatwebsite\Excel\Concerns\Importable; use Maatwebsite\Excel\Concerns\ToModel; class ImportAsMacro { public function __invoke() { return function (string $filename, callable $mapping, string $disk = null, string $readerType = null) { $import = new class(get_class($this->getModel()), $mapping) implements ToModel { use Importable; /** * @var string */ private $model; /** * @var callable */ private $mapping; /** * @param string $model * @param callable $mapping */ public function __construct(string $model, callable $mapping) { $this->model = $model; $this->mapping = $mapping; } /** * @param array $row * @return Model|Model[]|null */ public function model(array $row) { return (new $this->model)->fill( ($this->mapping)($row) ); } }; return $import->import($filename, $disk, $readerType); }; } } excel/src/Mixins/DownloadQueryMacro.php 0000644 00000003537 15060131672 0014203 0 ustar 00 <?php namespace Maatwebsite\Excel\Mixins; use Illuminate\Database\Eloquent\Builder; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Sheet; class DownloadQueryMacro { public function __invoke() { return function (string $fileName, string $writerType = null, $withHeadings = false) { $export = new class($this, $withHeadings) implements FromQuery, WithHeadings { use Exportable; /** * @var bool */ private $withHeadings; /** * @var Builder */ private $query; /** * @param $query * @param bool $withHeadings */ public function __construct($query, bool $withHeadings = false) { $this->query = $query; $this->withHeadings = $withHeadings; } /** * @return Builder */ public function query() { return $this->query; } /** * @return array */ public function headings(): array { if (!$this->withHeadings) { return []; } $firstRow = (clone $this->query)->first(); if ($firstRow) { return array_keys(Sheet::mapArraybleRow($firstRow)); } return []; } }; return $export->download($fileName, $writerType); }; } } excel/src/Validators/RowValidator.php 0000644 00000007715 15060131672 0013704 0 ustar 00 <?php namespace Maatwebsite\Excel\Validators; use Illuminate\Contracts\Validation\Factory; use Illuminate\Support\Str; use Illuminate\Validation\ValidationException as IlluminateValidationException; use Maatwebsite\Excel\Concerns\SkipsOnFailure; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Exceptions\RowSkippedException; class RowValidator { /** * @var Factory */ private $validator; /** * @param Factory $validator */ public function __construct(Factory $validator) { $this->validator = $validator; } /** * @param array $rows * @param WithValidation $import * * @throws ValidationException * @throws RowSkippedException */ public function validate(array $rows, WithValidation $import) { $rules = $this->rules($import); $messages = $this->messages($import); $attributes = $this->attributes($import); try { $validator = $this->validator->make($rows, $rules, $messages, $attributes); if (method_exists($import, 'withValidator')) { $import->withValidator($validator); } $validator->validate(); } catch (IlluminateValidationException $e) { $failures = []; foreach ($e->errors() as $attribute => $messages) { $row = strtok($attribute, '.'); $attributeName = strtok(''); $attributeName = $attributes['*.' . $attributeName] ?? $attributeName; $failures[] = new Failure( $row, $attributeName, str_replace($attribute, $attributeName, $messages), $rows[$row] ?? [] ); } if ($import instanceof SkipsOnFailure) { $import->onFailure(...$failures); throw new RowSkippedException(...$failures); } throw new ValidationException( $e, $failures ); } } /** * @param WithValidation $import * @return array */ private function messages(WithValidation $import): array { return method_exists($import, 'customValidationMessages') ? $this->formatKey($import->customValidationMessages()) : []; } /** * @param WithValidation $import * @return array */ private function attributes(WithValidation $import): array { return method_exists($import, 'customValidationAttributes') ? $this->formatKey($import->customValidationAttributes()) : []; } /** * @param WithValidation $import * @return array */ private function rules(WithValidation $import): array { return $this->formatKey($import->rules()); } /** * @param array $elements * @return array */ private function formatKey(array $elements): array { return collect($elements)->mapWithKeys(function ($rule, $attribute) { $attribute = Str::startsWith($attribute, '*.') ? $attribute : '*.' . $attribute; return [$attribute => $this->formatRule($rule)]; })->all(); } /** * @param string|object|callable|array $rules * @return string|array */ private function formatRule($rules) { if (is_array($rules)) { foreach ($rules as $rule) { $formatted[] = $this->formatRule($rule); } return $formatted ?? []; } if (is_object($rules) || is_callable($rules)) { return $rules; } if (Str::contains($rules, 'required_') && preg_match('/(.*?):(.*),(.*)/', $rules, $matches)) { $column = Str::startsWith($matches[2], '*.') ? $matches[2] : '*.' . $matches[2]; return $matches[1] . ':' . $column . ',' . $matches[3]; } return $rules; } } excel/src/Validators/Failure.php 0000644 00000003466 15060131672 0012655 0 ustar 00 <?php namespace Maatwebsite\Excel\Validators; use Illuminate\Contracts\Support\Arrayable; use JsonSerializable; class Failure implements Arrayable, JsonSerializable { /** * @var int */ protected $row; /** * @var string */ protected $attribute; /** * @var array */ protected $errors; /** * @var array */ private $values; /** * @param int $row * @param string $attribute * @param array $errors * @param array $values */ public function __construct(int $row, string $attribute, array $errors, array $values = []) { $this->row = $row; $this->attribute = $attribute; $this->errors = $errors; $this->values = $values; } /** * @return int */ public function row(): int { return $this->row; } /** * @return string */ public function attribute(): string { return $this->attribute; } /** * @return array */ public function errors(): array { return $this->errors; } /** * @return array */ public function values(): array { return $this->values; } /** * @return array */ public function toArray() { return collect($this->errors)->map(function ($message) { return __('There was an error on row :row. :message', ['row' => $this->row, 'message' => $message]); })->all(); } /** * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return [ 'row' => $this->row(), 'attribute' => $this->attribute(), 'errors' => $this->errors(), 'values' => $this->values(), ]; } } excel/src/Validators/ValidationException.php 0000644 00000001546 15060131672 0015234 0 ustar 00 <?php namespace Maatwebsite\Excel\Validators; use Illuminate\Validation\ValidationException as IlluminateValidationException; class ValidationException extends IlluminateValidationException { /** * @var Failure[] */ protected $failures; /** * @param IlluminateValidationException $previous * @param array $failures */ public function __construct(IlluminateValidationException $previous, array $failures) { parent::__construct($previous->validator, $previous->response, $previous->errorBag); $this->failures = $failures; } /** * @return string[] */ public function errors(): array { return collect($this->failures)->map->toArray()->all(); } /** * @return array */ public function failures(): array { return $this->failures; } } excel/src/Cache/BatchCache.php 0000644 00000007473 15060131672 0012130 0 ustar 00 <?php namespace Maatwebsite\Excel\Cache; use Illuminate\Support\Facades\Cache; use Psr\SimpleCache\CacheInterface; class BatchCache implements CacheInterface { /** * @var CacheInterface */ protected $cache; /** * @var MemoryCache */ protected $memory; /** * @var null|int|\DateInterval|callable */ protected $defaultTTL = null; /** * @param CacheInterface $cache * @param MemoryCache $memory * @param null|int|\DateInterval|callable $defaultTTL */ public function __construct( CacheInterface $cache, MemoryCache $memory, null|int|\DateInterval|callable $defaultTTL = null ) { $this->cache = $cache; $this->memory = $memory; $this->defaultTTL = $defaultTTL; } public function __sleep() { return ['memory']; } public function __wakeup() { $this->cache = Cache::driver( config('excel.cache.illuminate.store') ); } /** * {@inheritdoc} */ public function get(string $key, mixed $default = null): mixed { if ($this->memory->has($key)) { return $this->memory->get($key); } return $this->cache->get($key, $default); } /** * {@inheritdoc} */ public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool { if (func_num_args() === 2) { $ttl = value($this->defaultTTL); } $this->memory->set($key, $value, $ttl); if ($this->memory->reachedMemoryLimit()) { return $this->cache->setMultiple($this->memory->flush(), $ttl); } return true; } /** * {@inheritdoc} */ public function delete(string $key): bool { if ($this->memory->has($key)) { return $this->memory->delete($key); } return $this->cache->delete($key); } /** * {@inheritdoc} */ public function clear(): bool { $this->memory->clear(); return $this->cache->clear(); } /** * {@inheritdoc} */ public function getMultiple(iterable $keys, mixed $default = null): iterable { // Check if all keys are still in memory $memory = $this->memory->getMultiple($keys, $default); $actualItemsInMemory = count(array_filter($memory)); if ($actualItemsInMemory === count($keys)) { return $memory; } // Get all rows from cache if none is hold in memory. if ($actualItemsInMemory === 0) { return $this->cache->getMultiple($keys, $default); } // Add missing values from cache. foreach ($this->cache->getMultiple($keys, $default) as $key => $value) { if (null !== $value) { $memory[$key] = $value; } } return $memory; } /** * {@inheritdoc} */ public function setMultiple(iterable $values, null|int|\DateInterval $ttl = null): bool { if (func_num_args() === 1) { $ttl = value($this->defaultTTL); } $this->memory->setMultiple($values, $ttl); if ($this->memory->reachedMemoryLimit()) { return $this->cache->setMultiple($this->memory->flush(), $ttl); } return true; } /** * {@inheritdoc} */ public function deleteMultiple(iterable $keys): bool { $keys = is_array($keys) ? $keys : iterator_to_array($keys); $this->memory->deleteMultiple($keys); return $this->cache->deleteMultiple($keys); } /** * {@inheritdoc} */ public function has(string $key): bool { if ($this->memory->has($key)) { return true; } return $this->cache->has($key); } } excel/src/Cache/MemoryCache.php 0000644 00000005057 15060131672 0012353 0 ustar 00 <?php namespace Maatwebsite\Excel\Cache; use PhpOffice\PhpSpreadsheet\Cell\Cell; use Psr\SimpleCache\CacheInterface; class MemoryCache implements CacheInterface { /** * @var int|null */ protected $memoryLimit; /** * @var array */ protected $cache = []; /** * @param int|null $memoryLimit */ public function __construct(int $memoryLimit = null) { $this->memoryLimit = $memoryLimit; } /** * {@inheritdoc} */ public function clear(): bool { $this->cache = []; return true; } /** * {@inheritdoc} */ public function delete(string $key): bool { unset($this->cache[$key]); return true; } /** * {@inheritdoc} */ public function deleteMultiple($keys): bool { foreach ($keys as $key) { $this->delete($key); } return true; } /** * {@inheritdoc} */ public function get(string $key, mixed $default = null): mixed { if ($this->has($key)) { return $this->cache[$key]; } return $default; } /** * {@inheritdoc} */ public function getMultiple(iterable $keys, mixed $default = null): iterable { $results = []; foreach ($keys as $key) { $results[$key] = $this->get($key, $default); } return $results; } /** * {@inheritdoc} */ public function has($key): bool { return isset($this->cache[$key]); } /** * {@inheritdoc} */ public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool { $this->cache[$key] = $value; return true; } /** * {@inheritdoc} */ public function setMultiple($values, $ttl = null): bool { foreach ($values as $key => $value) { $this->set($key, $value); } return true; } /** * @return bool */ public function reachedMemoryLimit(): bool { // When no limit is given, we'll never reach any limit. if (null === $this->memoryLimit) { return false; } return count($this->cache) >= $this->memoryLimit; } /** * @return array */ public function flush(): array { $memory = $this->cache; foreach ($memory as $cell) { if ($cell instanceof Cell) { $cell->detach(); } } $this->clear(); return $memory; } } excel/src/Cache/MemoryCacheDeprecated.php 0000644 00000004675 15060131672 0014341 0 ustar 00 <?php namespace Maatwebsite\Excel\Cache; use PhpOffice\PhpSpreadsheet\Cell\Cell; use Psr\SimpleCache\CacheInterface; class MemoryCacheDeprecated implements CacheInterface { /** * @var int|null */ protected $memoryLimit; /** * @var array */ protected $cache = []; /** * @param int|null $memoryLimit */ public function __construct(int $memoryLimit = null) { $this->memoryLimit = $memoryLimit; } /** * {@inheritdoc} */ public function clear() { $this->cache = []; return true; } /** * {@inheritdoc} */ public function delete($key) { unset($this->cache[$key]); return true; } /** * {@inheritdoc} */ public function deleteMultiple($keys) { foreach ($keys as $key) { $this->delete($key); } return true; } /** * {@inheritdoc} */ public function get($key, $default = null) { if ($this->has($key)) { return $this->cache[$key]; } return $default; } /** * {@inheritdoc} */ public function getMultiple($keys, $default = null) { $results = []; foreach ($keys as $key) { $results[$key] = $this->get($key, $default); } return $results; } /** * {@inheritdoc} */ public function has($key) { return isset($this->cache[$key]); } /** * {@inheritdoc} */ public function set($key, $value, $ttl = null) { $this->cache[$key] = $value; return true; } /** * {@inheritdoc} */ public function setMultiple($values, $ttl = null) { foreach ($values as $key => $value) { $this->set($key, $value); } return true; } /** * @return bool */ public function reachedMemoryLimit(): bool { // When no limit is given, we'll never reach any limit. if (null === $this->memoryLimit) { return false; } return count($this->cache) >= $this->memoryLimit; } /** * @return array */ public function flush(): array { $memory = $this->cache; foreach ($memory as $cell) { if ($cell instanceof Cell) { $cell->detach(); } } $this->clear(); return $memory; } } excel/src/Cache/BatchCacheDeprecated.php 0000644 00000007241 15060131672 0014102 0 ustar 00 <?php namespace Maatwebsite\Excel\Cache; use Illuminate\Support\Facades\Cache; use Psr\SimpleCache\CacheInterface; class BatchCacheDeprecated implements CacheInterface { /** * @var CacheInterface */ protected $cache; /** * @var MemoryCacheDeprecated */ protected $memory; /** * @var null|int|\DateTimeInterface|callable */ protected $defaultTTL = null; /** * @param CacheInterface $cache * @param MemoryCacheDeprecated $memory * @param int|\DateTimeInterface|callable|null $defaultTTL */ public function __construct( CacheInterface $cache, MemoryCacheDeprecated $memory, $defaultTTL = null ) { $this->cache = $cache; $this->memory = $memory; $this->defaultTTL = $defaultTTL; } public function __sleep() { return ['memory']; } public function __wakeup() { $this->cache = Cache::driver( config('excel.cache.illuminate.store') ); } /** * {@inheritdoc} */ public function get($key, $default = null) { if ($this->memory->has($key)) { return $this->memory->get($key); } return $this->cache->get($key, $default); } /** * {@inheritdoc} */ public function set($key, $value, $ttl = null) { if (func_num_args() === 2) { $ttl = value($this->defaultTTL); } $this->memory->set($key, $value, $ttl); if ($this->memory->reachedMemoryLimit()) { return $this->cache->setMultiple($this->memory->flush(), $ttl); } return true; } /** * {@inheritdoc} */ public function delete($key) { if ($this->memory->has($key)) { return $this->memory->delete($key); } return $this->cache->delete($key); } /** * {@inheritdoc} */ public function clear() { $this->memory->clear(); return $this->cache->clear(); } /** * {@inheritdoc} */ public function getMultiple($keys, $default = null) { // Check if all keys are still in memory $memory = $this->memory->getMultiple($keys, $default); $actualItemsInMemory = count(array_filter($memory)); if ($actualItemsInMemory === count($keys)) { return $memory; } // Get all rows from cache if none is hold in memory. if ($actualItemsInMemory === 0) { return $this->cache->getMultiple($keys, $default); } // Add missing values from cache. foreach ($this->cache->getMultiple($keys, $default) as $key => $value) { if (null !== $value) { $memory[$key] = $value; } } return $memory; } /** * {@inheritdoc} */ public function setMultiple($values, $ttl = null) { if (func_num_args() === 1) { $ttl = value($this->defaultTTL); } $this->memory->setMultiple($values, $ttl); if ($this->memory->reachedMemoryLimit()) { return $this->cache->setMultiple($this->memory->flush(), $ttl); } return true; } /** * {@inheritdoc} */ public function deleteMultiple($keys) { $keys = is_array($keys) ? $keys : iterator_to_array($keys); $this->memory->deleteMultiple($keys); return $this->cache->deleteMultiple($keys); } /** * {@inheritdoc} */ public function has($key) { if ($this->memory->has($key)) { return true; } return $this->cache->has($key); } } excel/src/Cache/CacheManager.php 0000644 00000004115 15060131672 0012447 0 ustar 00 <?php namespace Maatwebsite\Excel\Cache; use Composer\InstalledVersions; use Composer\Semver\VersionParser; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Manager; use Psr\SimpleCache\CacheInterface; class CacheManager extends Manager { /** * @const string */ public const DRIVER_BATCH = 'batch'; /** * @const string */ public const DRIVER_MEMORY = 'memory'; /** * @const string */ public const DRIVER_ILLUMINATE = 'illuminate'; /** * Get the default driver name. * * @return string */ public function getDefaultDriver(): string { return config('excel.cache.driver', 'memory'); } /** * @return MemoryCache */ public function createMemoryDriver(): CacheInterface { if (!InstalledVersions::satisfies(new VersionParser, 'psr/simple-cache', '^3.0')) { return new MemoryCacheDeprecated( config('excel.cache.batch.memory_limit', 60000) ); } return new MemoryCache( config('excel.cache.batch.memory_limit', 60000) ); } /** * @return BatchCache */ public function createBatchDriver(): CacheInterface { if (!InstalledVersions::satisfies(new VersionParser, 'psr/simple-cache', '^3.0')) { return new BatchCacheDeprecated( $this->createIlluminateDriver(), $this->createMemoryDriver(), config('excel.cache.ttl') ); } return new BatchCache( $this->createIlluminateDriver(), $this->createMemoryDriver(), config('excel.cache.ttl') ); } /** * @return CacheInterface */ public function createIlluminateDriver(): CacheInterface { return Cache::driver( config('excel.cache.illuminate.store') ); } public function flush() { $this->driver()->clear(); } public function isInMemory(): bool { return $this->getDefaultDriver() === self::DRIVER_MEMORY; } } excel/src/Filters/ChunkReadFilter.php 0000644 00000002455 15060131672 0013575 0 ustar 00 <?php namespace Maatwebsite\Excel\Filters; use PhpOffice\PhpSpreadsheet\Reader\IReadFilter; class ChunkReadFilter implements IReadFilter { /** * @var int */ private $headingRow; /** * @var int */ private $startRow; /** * @var int */ private $endRow; /** * @var string */ private $worksheetName; /** * @param int $headingRow * @param int $startRow * @param int $chunkSize * @param string $worksheetName */ public function __construct(int $headingRow, int $startRow, int $chunkSize, string $worksheetName) { $this->headingRow = $headingRow; $this->startRow = $startRow; $this->endRow = $startRow + $chunkSize; $this->worksheetName = $worksheetName; } /** * @param string $column * @param int $row * @param string $worksheetName * @return bool */ public function readCell($column, $row, $worksheetName = '') { // Only read the heading row, and the rows that are configured in $this->_startRow and $this->_endRow return ($worksheetName === $this->worksheetName || $worksheetName === '') && ($row === $this->headingRow || ($row >= $this->startRow && $row < $this->endRow)); } } excel/src/Filters/LimitFilter.php 0000644 00000001355 15060131672 0013005 0 ustar 00 <?php namespace Maatwebsite\Excel\Filters; use PhpOffice\PhpSpreadsheet\Reader\IReadFilter; class LimitFilter implements IReadFilter { /** * @var int */ private $startRow; /** * @var int */ private $endRow; /** * @param int $startRow * @param int $limit */ public function __construct(int $startRow, int $limit) { $this->startRow = $startRow; $this->endRow = $startRow + $limit; } /** * @param string $column * @param int $row * @param string $worksheetName * @return bool */ public function readCell($column, $row, $worksheetName = '') { return $row >= $this->startRow && $row < $this->endRow; } } excel/src/Facades/Excel.php 0000644 00000004516 15060131672 0011541 0 ustar 00 <?php namespace Maatwebsite\Excel\Facades; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Http\UploadedFile; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Facade; use Maatwebsite\Excel\Excel as BaseExcel; use Maatwebsite\Excel\Fakes\ExcelFake; use Symfony\Component\HttpFoundation\BinaryFileResponse; /** * @method static BinaryFileResponse download(object $export, string $fileName, string $writerType = null, array $headers = []) * @method static bool store(object $export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) * @method static PendingDispatch queue(object $export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) * @method static string raw(object $export, string $writerType) * @method static BaseExcel import(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null) * @method static array toArray(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null) * @method static Collection toCollection(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null) * @method static PendingDispatch queueImport(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null) * @method static void matchByRegex() * @method static void doNotMatchByRegex() * @method static void assertDownloaded(string $fileName, callable $callback = null) * @method static void assertStored(string $filePath, string|callable $disk = null, callable $callback = null) * @method static void assertQueued(string $filePath, string|callable $disk = null, callable $callback = null) * @method static void assertQueuedWithChain(array $chain) * @method static void assertExportedInRaw(string $classname, callable $callback = null) * @method static void assertImported(string $filePath, string|callable $disk = null, callable $callback = null) */ class Excel extends Facade { /** * Replace the bound instance with a fake. * * @return void */ public static function fake() { static::swap(new ExcelFake()); } /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'excel'; } } excel/src/Factories/WriterFactory.php 0000644 00000005465 15060131672 0013702 0 ustar 00 <?php namespace Maatwebsite\Excel\Factories; use Maatwebsite\Excel\Cache\CacheManager; use Maatwebsite\Excel\Concerns\MapsCsvSettings; use Maatwebsite\Excel\Concerns\WithCharts; use Maatwebsite\Excel\Concerns\WithCustomCsvSettings; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Concerns\WithPreCalculateFormulas; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Csv; use PhpOffice\PhpSpreadsheet\Writer\Html; use PhpOffice\PhpSpreadsheet\Writer\IWriter; class WriterFactory { use MapsCsvSettings; /** * @param string $writerType * @param Spreadsheet $spreadsheet * @param object $export * @return IWriter * * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ public static function make(string $writerType, Spreadsheet $spreadsheet, $export): IWriter { $writer = IOFactory::createWriter($spreadsheet, $writerType); $writer->setUseDiskCaching( config('excel.cache.driver', CacheManager::DRIVER_MEMORY) !== CacheManager::DRIVER_MEMORY ); if (static::includesCharts($export)) { $writer->setIncludeCharts(true); } if ($writer instanceof Html && $export instanceof WithMultipleSheets) { $writer->writeAllSheets(); } if ($writer instanceof Csv) { static::applyCsvSettings(config('excel.exports.csv', [])); if ($export instanceof WithCustomCsvSettings) { static::applyCsvSettings($export->getCsvSettings()); } $writer->setDelimiter(static::$delimiter); $writer->setEnclosure(static::$enclosure); $writer->setEnclosureRequired((bool) static::$enclosure); $writer->setLineEnding(static::$lineEnding); $writer->setUseBOM(static::$useBom); $writer->setIncludeSeparatorLine(static::$includeSeparatorLine); $writer->setExcelCompatibility(static::$excelCompatibility); $writer->setOutputEncoding(static::$outputEncoding); } // Calculation settings $writer->setPreCalculateFormulas( $export instanceof WithPreCalculateFormulas ? true : config('excel.exports.pre_calculate_formulas', false) ); return $writer; } /** * @param $export * @return bool */ private static function includesCharts($export): bool { if ($export instanceof WithCharts) { return true; } if ($export instanceof WithMultipleSheets) { foreach ($export->sheets() as $sheet) { if ($sheet instanceof WithCharts) { return true; } } } return false; } } excel/src/Factories/ReaderFactory.php 0000644 00000005415 15060131672 0013623 0 ustar 00 <?php namespace Maatwebsite\Excel\Factories; use Maatwebsite\Excel\Concerns\MapsCsvSettings; use Maatwebsite\Excel\Concerns\WithCustomCsvSettings; use Maatwebsite\Excel\Concerns\WithLimit; use Maatwebsite\Excel\Concerns\WithReadFilter; use Maatwebsite\Excel\Concerns\WithStartRow; use Maatwebsite\Excel\Exceptions\NoTypeDetectedException; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Filters\LimitFilter; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Csv; use PhpOffice\PhpSpreadsheet\Reader\Exception; use PhpOffice\PhpSpreadsheet\Reader\IReader; class ReaderFactory { use MapsCsvSettings; /** * @param object $import * @param TemporaryFile $file * @param string $readerType * @return IReader * * @throws Exception */ public static function make($import, TemporaryFile $file, string $readerType = null): IReader { $reader = IOFactory::createReader( $readerType ?: static::identify($file) ); if (method_exists($reader, 'setReadDataOnly')) { $reader->setReadDataOnly(config('excel.imports.read_only', true)); } if (method_exists($reader, 'setReadEmptyCells')) { $reader->setReadEmptyCells(!config('excel.imports.ignore_empty', false)); } if ($reader instanceof Csv) { static::applyCsvSettings(config('excel.imports.csv', [])); if ($import instanceof WithCustomCsvSettings) { static::applyCsvSettings($import->getCsvSettings()); } $reader->setDelimiter(static::$delimiter); $reader->setEnclosure(static::$enclosure); $reader->setEscapeCharacter(static::$escapeCharacter); $reader->setContiguous(static::$contiguous); $reader->setInputEncoding(static::$inputEncoding); if (method_exists($reader, 'setTestAutoDetect')) { $reader->setTestAutoDetect(static::$testAutoDetect); } } if ($import instanceof WithReadFilter) { $reader->setReadFilter($import->readFilter()); } elseif ($import instanceof WithLimit) { $reader->setReadFilter(new LimitFilter( $import instanceof WithStartRow ? $import->startRow() : 1, $import->limit() )); } return $reader; } /** * @param TemporaryFile $temporaryFile * @return string * * @throws NoTypeDetectedException */ private static function identify(TemporaryFile $temporaryFile): string { try { return IOFactory::identify($temporaryFile->getLocalPath()); } catch (Exception $e) { throw new NoTypeDetectedException(null, null, $e); } } } excel/src/RegistersCustomConcerns.php 0000644 00000002145 15060131672 0014004 0 ustar 00 <?php namespace Maatwebsite\Excel; use Maatwebsite\Excel\Events\AfterSheet; use Maatwebsite\Excel\Events\BeforeExport; use Maatwebsite\Excel\Events\BeforeSheet; use Maatwebsite\Excel\Events\BeforeWriting; use Maatwebsite\Excel\Events\Event; trait RegistersCustomConcerns { /** * @var array */ private static $eventMap = [ BeforeWriting::class => Writer::class, BeforeExport::class => Writer::class, BeforeSheet::class => Sheet::class, AfterSheet::class => Sheet::class, ]; /** * @param string $concern * @param callable $handler * @param string $event */ public static function extend(string $concern, callable $handler, string $event = BeforeWriting::class) { /** @var HasEventBus $delegate */ $delegate = static::$eventMap[$event] ?? BeforeWriting::class; $delegate::listen($event, function (Event $event) use ($concern, $handler) { if ($event->appliesToConcern($concern)) { $handler($event->getConcernable(), $event->getDelegate()); } }); } } excel/src/Jobs/Middleware/LocalizeJob.php 0000644 00000001740 15060131672 0014316 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs\Middleware; use Closure; use Illuminate\Contracts\Translation\HasLocalePreference; use Illuminate\Support\Traits\Localizable; class LocalizeJob { use Localizable; /** * @var object */ private $localizable; /** * LocalizeJob constructor. * * @param object $localizable */ public function __construct($localizable) { $this->localizable = $localizable; } /** * Handles the job. * * @param mixed $job * @param Closure $next * @return mixed */ public function handle($job, Closure $next) { $locale = value(function () { if ($this->localizable instanceof HasLocalePreference) { return $this->localizable->preferredLocale(); } return null; }); return $this->withLocale($locale, function () use ($next, $job) { return $next($job); }); } } excel/src/Jobs/AppendQueryToSheet.php 0000644 00000005611 15060131672 0013576 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\AfterChunk; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\HasEventBus; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; class AppendQueryToSheet implements ShouldQueue { use Queueable, Dispatchable, ProxyFailures, InteractsWithQueue, HasEventBus; /** * @var TemporaryFile */ public $temporaryFile; /** * @var string */ public $writerType; /** * @var int */ public $sheetIndex; /** * @var FromQuery */ public $sheetExport; /** * @var int */ public $page; /** * @var int */ public $chunkSize; /** * @param FromQuery $sheetExport * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @param int $page * @param int $chunkSize */ public function __construct( FromQuery $sheetExport, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex, int $page, int $chunkSize ) { $this->sheetExport = $sheetExport; $this->temporaryFile = $temporaryFile; $this->writerType = $writerType; $this->sheetIndex = $sheetIndex; $this->page = $page; $this->chunkSize = $chunkSize; } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->sheetExport, 'middleware')) ? $this->sheetExport->middleware() : []; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(Writer $writer) { (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { if ($this->sheetExport instanceof WithEvents) { $this->registerListeners($this->sheetExport->registerEvents()); } $writer = $writer->reopen($this->temporaryFile, $this->writerType); $sheet = $writer->getSheetByIndex($this->sheetIndex); $query = $this->sheetExport->query()->forPage($this->page, $this->chunkSize); $sheet->appendRows($query->get(), $this->sheetExport); $writer->write($this->sheetExport, $this->temporaryFile, $this->writerType); $this->raise(new AfterChunk($sheet, $this->sheetExport, ($this->page - 1) * $this->chunkSize)); $this->clearListeners(); }); } } excel/src/Jobs/QueueExport.php 0000644 00000004774 15060131672 0012344 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Exceptions\NoSheetsFoundException; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; use Throwable; class QueueExport implements ShouldQueue { use ExtendedQueueable, Dispatchable; /** * @var object */ public $export; /** * @var string */ private $writerType; /** * @var TemporaryFile */ private $temporaryFile; /** * @param object $export * @param TemporaryFile $temporaryFile * @param string $writerType */ public function __construct($export, TemporaryFile $temporaryFile, string $writerType) { $this->export = $export; $this->writerType = $writerType; $this->temporaryFile = $temporaryFile; } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->export, 'middleware')) ? $this->export->middleware() : []; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function handle(Writer $writer) { (new LocalizeJob($this->export))->handle($this, function () use ($writer) { $writer->open($this->export); $sheetExports = [$this->export]; if ($this->export instanceof WithMultipleSheets) { $sheetExports = $this->export->sheets(); } if (count($sheetExports) === 0) { throw new NoSheetsFoundException('Your export did not return any sheet export instances, please make sure your sheets() method always at least returns one instance.'); } // Pre-create the worksheets foreach ($sheetExports as $sheetIndex => $sheetExport) { $sheet = $writer->addNewSheet($sheetIndex); $sheet->open($sheetExport); } // Write to temp file with empty sheets. $writer->write($sheetExport, $this->temporaryFile, $this->writerType); }); } /** * @param Throwable $e */ public function failed(Throwable $e) { if (method_exists($this->export, 'failed')) { $this->export->failed($e); } } } excel/src/Jobs/CloseSheet.php 0000644 00000003312 15060131672 0012077 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Writer; class CloseSheet implements ShouldQueue { use Queueable, ProxyFailures; /** * @var object */ private $sheetExport; /** * @var string */ private $temporaryFile; /** * @var string */ private $writerType; /** * @var int */ private $sheetIndex; /** * @param object $sheetExport * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex */ public function __construct($sheetExport, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex) { $this->sheetExport = $sheetExport; $this->temporaryFile = $temporaryFile; $this->writerType = $writerType; $this->sheetIndex = $sheetIndex; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(Writer $writer) { $writer = $writer->reopen( $this->temporaryFile, $this->writerType ); $sheet = $writer->getSheetByIndex($this->sheetIndex); if ($this->sheetExport instanceof WithEvents) { $sheet->registerListeners($this->sheetExport->registerEvents()); } $sheet->close($this->sheetExport); $writer->write( $this->sheetExport, $this->temporaryFile, $this->writerType ); } } excel/src/Jobs/QueueImport.php 0000644 00000001202 15060131672 0012314 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; class QueueImport implements ShouldQueue { use ExtendedQueueable, Dispatchable; /** * @var int */ public $tries; /** * @var int */ public $timeout; /** * @param ShouldQueue $import */ public function __construct(ShouldQueue $import = null) { if ($import) { $this->timeout = $import->timeout ?? null; $this->tries = $import->tries ?? null; } } public function handle() { // } } excel/src/Jobs/ReadChunk.php 0000644 00000014732 15060131672 0011715 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Facades\Cache; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithCustomValueBinder; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\AfterChunk; use Maatwebsite\Excel\Events\ImportFailed; use Maatwebsite\Excel\Files\RemoteTemporaryFile; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Filters\ChunkReadFilter; use Maatwebsite\Excel\HasEventBus; use Maatwebsite\Excel\Imports\HeadingRowExtractor; use Maatwebsite\Excel\Sheet; use Maatwebsite\Excel\Transactions\TransactionHandler; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Reader\IReader; use Throwable; class ReadChunk implements ShouldQueue { use Queueable, HasEventBus, InteractsWithQueue; /** * @var int */ public $timeout; /** * @var int */ public $tries; /** * @var int */ public $maxExceptions; /** * @var int */ public $backoff; /** * @var string */ public $queue; /** * @var string */ public $connection; /** * @var WithChunkReading */ private $import; /** * @var IReader */ private $reader; /** * @var TemporaryFile */ private $temporaryFile; /** * @var string */ private $sheetName; /** * @var object */ private $sheetImport; /** * @var int */ private $startRow; /** * @var int */ private $chunkSize; /** * @var string */ private $uniqueId; /** * @param WithChunkReading $import * @param IReader $reader * @param TemporaryFile $temporaryFile * @param string $sheetName * @param object $sheetImport * @param int $startRow * @param int $chunkSize */ public function __construct(WithChunkReading $import, IReader $reader, TemporaryFile $temporaryFile, string $sheetName, $sheetImport, int $startRow, int $chunkSize) { $this->import = $import; $this->reader = $reader; $this->temporaryFile = $temporaryFile; $this->sheetName = $sheetName; $this->sheetImport = $sheetImport; $this->startRow = $startRow; $this->chunkSize = $chunkSize; $this->timeout = $import->timeout ?? null; $this->tries = $import->tries ?? null; $this->maxExceptions = $import->maxExceptions ?? null; $this->backoff = method_exists($import, 'backoff') ? $import->backoff() : ($import->backoff ?? null); $this->connection = property_exists($import, 'connection') ? $import->connection : null; $this->queue = property_exists($import, 'queue') ? $import->queue : null; } public function getUniqueId(): string { if (!isset($this->uniqueId)) { $this->uniqueId = uniqid(); Cache::set('laravel-excel/read-chunk/' . $this->uniqueId, true); } return $this->uniqueId; } public static function isComplete(string $id): bool { return !Cache::has('laravel-excel/read-chunk/' . $id); } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->import, 'middleware')) ? $this->import->middleware() : []; } /** * Determine the time at which the job should timeout. * * @return \DateTime */ public function retryUntil() { return (method_exists($this->import, 'retryUntil')) ? $this->import->retryUntil() : null; } /** * @param TransactionHandler $transaction * * @throws \Maatwebsite\Excel\Exceptions\SheetNotFoundException * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(TransactionHandler $transaction) { if (method_exists($this->import, 'setChunkOffset')) { $this->import->setChunkOffset($this->startRow); } if (method_exists($this->sheetImport, 'setChunkOffset')) { $this->sheetImport->setChunkOffset($this->startRow); } if ($this->sheetImport instanceof WithCustomValueBinder) { Cell::setValueBinder($this->sheetImport); } $headingRow = HeadingRowExtractor::headingRow($this->sheetImport); $filter = new ChunkReadFilter( $headingRow, $this->startRow, $this->chunkSize, $this->sheetName ); $this->reader->setReadFilter($filter); $this->reader->setReadDataOnly(config('excel.imports.read_only', true)); $this->reader->setReadEmptyCells(!config('excel.imports.ignore_empty', false)); $spreadsheet = $this->reader->load( $this->temporaryFile->sync()->getLocalPath() ); $sheet = Sheet::byName( $spreadsheet, $this->sheetName ); if ($sheet->getHighestRow() < $this->startRow) { $sheet->disconnect(); $this->cleanUpTempFile(); return; } $transaction(function () use ($sheet) { $sheet->import( $this->sheetImport, $this->startRow ); $sheet->disconnect(); $this->cleanUpTempFile(); $sheet->raise(new AfterChunk($sheet, $this->import, $this->startRow)); }); } /** * @param Throwable $e */ public function failed(Throwable $e) { $this->cleanUpTempFile(true); if ($this->import instanceof WithEvents) { $this->registerListeners($this->import->registerEvents()); $this->raise(new ImportFailed($e)); if (method_exists($this->import, 'failed')) { $this->import->failed($e); } } } private function cleanUpTempFile(bool $force = false): bool { if (!empty($this->uniqueId)) { Cache::delete('laravel-excel/read-chunk/' . $this->uniqueId); } if (!$force && !config('excel.temporary_files.force_resync_remote')) { return true; } if (!$this->temporaryFile instanceof RemoteTemporaryFile) { return true; } return $this->temporaryFile->deleteLocalCopy(); } } excel/src/Jobs/AppendViewToSheet.php 0000644 00000004105 15060131672 0013400 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Maatwebsite\Excel\Concerns\FromView; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; class AppendViewToSheet implements ShouldQueue { use Queueable, Dispatchable, InteractsWithQueue; /** * @var TemporaryFile */ public $temporaryFile; /** * @var string */ public $writerType; /** * @var int */ public $sheetIndex; /** * @var FromView */ public $sheetExport; /** * @param FromView $sheetExport * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @param array $data */ public function __construct(FromView $sheetExport, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex) { $this->sheetExport = $sheetExport; $this->temporaryFile = $temporaryFile; $this->writerType = $writerType; $this->sheetIndex = $sheetIndex; } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->sheetExport, 'middleware')) ? $this->sheetExport->middleware() : []; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(Writer $writer) { (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { $writer = $writer->reopen($this->temporaryFile, $this->writerType); $sheet = $writer->getSheetByIndex($this->sheetIndex); $sheet->fromView($this->sheetExport, $this->sheetIndex); $writer->write($this->sheetExport, $this->temporaryFile, $this->writerType); }); } } excel/src/Jobs/ExtendedQueueable.php 0000644 00000000773 15060131672 0013442 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; trait ExtendedQueueable { use Queueable { chain as originalChain; } /** * @param $chain * @return $this */ public function chain($chain) { collect($chain)->each(function ($job) { $serialized = method_exists($this, 'serializeJob') ? $this->serializeJob($job) : serialize($job); $this->chained[] = $serialized; }); return $this; } } excel/src/Jobs/ProxyFailures.php 0000644 00000000445 15060131672 0012661 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Throwable; trait ProxyFailures { /** * @param Throwable $e */ public function failed(Throwable $e) { if (method_exists($this->sheetExport, 'failed')) { $this->sheetExport->failed($e); } } } excel/src/Jobs/AfterImportJob.php 0000644 00000004415 15060131672 0012735 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\ImportFailed; use Maatwebsite\Excel\HasEventBus; use Maatwebsite\Excel\Reader; use Throwable; class AfterImportJob implements ShouldQueue { use HasEventBus, InteractsWithQueue, Queueable; /** * @var WithEvents */ private $import; /** * @var Reader */ private $reader; /** * @var iterable */ private $dependencyIds = []; private $interval = 60; /** * @param object $import * @param Reader $reader */ public function __construct($import, Reader $reader) { $this->import = $import; $this->reader = $reader; } public function setInterval(int $interval) { $this->interval = $interval; } public function setDependencies(Collection $jobs) { $this->dependencyIds = $jobs->map(function (ReadChunk $job) { return $job->getUniqueId(); })->all(); } public function handle() { foreach ($this->dependencyIds as $id) { if (!ReadChunk::isComplete($id)) { // Until there is no jobs left to run we put this job back into the queue every minute // Note: this will do nothing in a SyncQueue but that's desired, because in a SyncQueue jobs run in order $this->release($this->interval); return; } } if ($this->import instanceof ShouldQueue && $this->import instanceof WithEvents) { $this->reader->clearListeners(); $this->reader->registerListeners($this->import->registerEvents()); } $this->reader->afterImport($this->import); } /** * @param Throwable $e */ public function failed(Throwable $e) { if ($this->import instanceof WithEvents) { $this->registerListeners($this->import->registerEvents()); $this->raise(new ImportFailed($e)); if (method_exists($this->import, 'failed')) { $this->import->failed($e); } } } } excel/src/Jobs/StoreQueuedExport.php 0000644 00000002425 15060131672 0013514 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Maatwebsite\Excel\Files\Filesystem; use Maatwebsite\Excel\Files\TemporaryFile; class StoreQueuedExport implements ShouldQueue { use Queueable; /** * @var string */ private $filePath; /** * @var string|null */ private $disk; /** * @var TemporaryFile */ private $temporaryFile; /** * @var array|string */ private $diskOptions; /** * @param TemporaryFile $temporaryFile * @param string $filePath * @param string|null $disk * @param array|string $diskOptions */ public function __construct(TemporaryFile $temporaryFile, string $filePath, string $disk = null, $diskOptions = []) { $this->disk = $disk; $this->filePath = $filePath; $this->temporaryFile = $temporaryFile; $this->diskOptions = $diskOptions; } /** * @param Filesystem $filesystem */ public function handle(Filesystem $filesystem) { $filesystem->disk($this->disk, $this->diskOptions)->copy( $this->temporaryFile, $this->filePath ); $this->temporaryFile->delete(); } } excel/src/Jobs/AppendPaginatedToSheet.php 0000644 00000005716 15060131672 0014373 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Query\Builder; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Laravel\Scout\Builder as ScoutBuilder; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; class AppendPaginatedToSheet implements ShouldQueue { use Queueable, Dispatchable, ProxyFailures, InteractsWithQueue; /** * @var TemporaryFile */ public $temporaryFile; /** * @var string */ public $writerType; /** * @var int */ public $sheetIndex; /** * @var FromQuery */ public $sheetExport; /** * @var int */ public $page; /** * @var int */ public $perPage; /** * @param FromQuery $sheetExport * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @param int $page * @param int $perPage */ public function __construct( FromQuery $sheetExport, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex, int $page, int $perPage ) { $this->sheetExport = $sheetExport; $this->temporaryFile = $temporaryFile; $this->writerType = $writerType; $this->sheetIndex = $sheetIndex; $this->page = $page; $this->perPage = $perPage; } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->sheetExport, 'middleware')) ? $this->sheetExport->middleware() : []; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(Writer $writer) { (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { $writer = $writer->reopen($this->temporaryFile, $this->writerType); $sheet = $writer->getSheetByIndex($this->sheetIndex); $sheet->appendRows($this->chunk($this->sheetExport->query()), $this->sheetExport); $writer->write($this->sheetExport, $this->temporaryFile, $this->writerType); }); } /** * @param Builder|Relation|EloquentBuilder|ScoutBuilder $query */ protected function chunk($query) { if ($query instanceof \Laravel\Scout\Builder) { return $query->paginate($this->perPage, 'page', $this->page)->items(); } // Fallback return $query->forPage($this->page, $this->perPage)->get(); } } excel/src/Jobs/AppendDataToSheet.php 0000644 00000004200 15060131672 0013333 0 ustar 00 <?php namespace Maatwebsite\Excel\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; class AppendDataToSheet implements ShouldQueue { use Queueable, Dispatchable, ProxyFailures, InteractsWithQueue; /** * @var array */ public $data = []; /** * @var string */ public $temporaryFile; /** * @var string */ public $writerType; /** * @var int */ public $sheetIndex; /** * @var object */ public $sheetExport; /** * @param object $sheetExport * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @param array $data */ public function __construct($sheetExport, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex, array $data) { $this->sheetExport = $sheetExport; $this->data = $data; $this->temporaryFile = $temporaryFile; $this->writerType = $writerType; $this->sheetIndex = $sheetIndex; } /** * Get the middleware the job should be dispatched through. * * @return array */ public function middleware() { return (method_exists($this->sheetExport, 'middleware')) ? $this->sheetExport->middleware() : []; } /** * @param Writer $writer * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function handle(Writer $writer) { (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { $writer = $writer->reopen($this->temporaryFile, $this->writerType); $sheet = $writer->getSheetByIndex($this->sheetIndex); $sheet->appendRows($this->data, $this->sheetExport); $writer->write($this->sheetExport, $this->temporaryFile, $this->writerType); }); } } excel/src/Files/Filesystem.php 0000644 00000001211 15060131672 0012326 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; use Illuminate\Contracts\Filesystem\Factory; class Filesystem { /** * @var Factory */ private $filesystem; /** * @param Factory $filesystem */ public function __construct(Factory $filesystem) { $this->filesystem = $filesystem; } /** * @param string|null $disk * @param array $diskOptions * @return Disk */ public function disk(string $disk = null, array $diskOptions = []): Disk { return new Disk( $this->filesystem->disk($disk), $disk, $diskOptions ); } } excel/src/Files/RemoteTemporaryFile.php 0000644 00000006064 15060131672 0014153 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; use Illuminate\Support\Arr; class RemoteTemporaryFile extends TemporaryFile { /** * @var string */ private $disk; /** * @var Disk|null */ private $diskInstance; /** * @var string */ private $filename; /** * @var LocalTemporaryFile */ private $localTemporaryFile; /** * @param string $disk * @param string $filename * @param LocalTemporaryFile $localTemporaryFile */ public function __construct(string $disk, string $filename, LocalTemporaryFile $localTemporaryFile) { $this->disk = $disk; $this->filename = $filename; $this->localTemporaryFile = $localTemporaryFile; $this->disk()->touch($filename); } public function __sleep() { return ['disk', 'filename', 'localTemporaryFile']; } /** * @return string */ public function getLocalPath(): string { return $this->localTemporaryFile->getLocalPath(); } /** * @return bool */ public function existsLocally(): bool { return $this->localTemporaryFile->exists(); } /** * @return bool */ public function exists(): bool { return $this->disk()->exists($this->filename); } /** * @return bool */ public function deleteLocalCopy(): bool { return $this->localTemporaryFile->delete(); } /** * @return bool */ public function delete(): bool { // we don't need to delete local copy as it's deleted at end of each chunk if (!config('excel.temporary_files.force_resync_remote')) { $this->deleteLocalCopy(); } return $this->disk()->delete($this->filename); } /** * @return TemporaryFile */ public function sync(): TemporaryFile { if (!$this->localTemporaryFile->exists()) { $this->localTemporaryFile = resolve(TemporaryFileFactory::class) ->makeLocal(Arr::last(explode('/', $this->filename))); } $this->disk()->copy( $this, $this->localTemporaryFile->getLocalPath() ); return $this; } /** * Store on remote disk. */ public function updateRemote() { $this->disk()->copy( $this->localTemporaryFile, $this->filename ); } /** * @return resource */ public function readStream() { return $this->disk()->readStream($this->filename); } /** * @return string */ public function contents(): string { return $this->disk()->get($this->filename); } /** * @param string|resource $contents */ public function put($contents) { $this->disk()->put($this->filename, $contents); } /** * @return Disk */ public function disk(): Disk { return $this->diskInstance ?: $this->diskInstance = app(Filesystem::class)->disk($this->disk); } } excel/src/Files/TemporaryFile.php 0000644 00000003624 15060131672 0012776 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Symfony\Component\HttpFoundation\File\UploadedFile; abstract class TemporaryFile { /** * @return string */ abstract public function getLocalPath(): string; /** * @return bool */ abstract public function exists(): bool; /** * @param @param string|resource $contents */ abstract public function put($contents); /** * @return bool */ abstract public function delete(): bool; /** * @return resource */ abstract public function readStream(); /** * @return string */ abstract public function contents(): string; /** * @return TemporaryFile */ public function sync(): TemporaryFile { return $this; } /** * @param string|UploadedFile $filePath * @param string|null $disk * @return TemporaryFile */ public function copyFrom($filePath, string $disk = null): TemporaryFile { if ($filePath instanceof UploadedFile) { $readStream = fopen($filePath->getRealPath(), 'rb'); } elseif ($disk === null && realpath($filePath) !== false) { $readStream = fopen($filePath, 'rb'); } else { $diskInstance = app('filesystem')->disk($disk); if (!$diskInstance->exists($filePath)) { $logPath = '[' . $filePath . ']'; if ($disk) { $logPath .= ' (' . $disk . ')'; } throw new FileNotFoundException('File ' . $logPath . ' does not exist and can therefor not be imported.'); } $readStream = $diskInstance->readStream($filePath); } $this->put($readStream); if (is_resource($readStream)) { fclose($readStream); } return $this->sync(); } } excel/src/Files/Disk.php 0000644 00000004261 15060131672 0011104 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; use Illuminate\Contracts\Filesystem\Filesystem as IlluminateFilesystem; /** * @method bool get(string $filename) * @method resource readStream(string $filename) * @method bool delete(string $filename) * @method bool exists(string $filename) */ class Disk { /** * @var IlluminateFilesystem */ protected $disk; /** * @var string|null */ protected $name; /** * @var array */ protected $diskOptions; /** * @param IlluminateFilesystem $disk * @param string|null $name * @param array $diskOptions */ public function __construct(IlluminateFilesystem $disk, string $name = null, array $diskOptions = []) { $this->disk = $disk; $this->name = $name; $this->diskOptions = $diskOptions; } /** * @param string $name * @param array $arguments * @return mixed */ public function __call($name, $arguments) { return $this->disk->{$name}(...$arguments); } /** * @param string $destination * @param string|resource $contents * @return bool */ public function put(string $destination, $contents): bool { return $this->disk->put($destination, $contents, $this->diskOptions); } /** * @param TemporaryFile $source * @param string $destination * @return bool */ public function copy(TemporaryFile $source, string $destination): bool { $readStream = $source->readStream(); if (realpath($destination)) { $tempStream = fopen($destination, 'rb+'); $success = stream_copy_to_stream($readStream, $tempStream) !== false; if (is_resource($tempStream)) { fclose($tempStream); } } else { $success = $this->put($destination, $readStream); } if (is_resource($readStream)) { fclose($readStream); } return $success; } /** * @param string $filename */ public function touch(string $filename) { $this->disk->put($filename, '', $this->diskOptions); } } excel/src/Files/LocalTemporaryFile.php 0000644 00000002574 15060131672 0013754 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; class LocalTemporaryFile extends TemporaryFile { /** * @var string */ private $filePath; /** * @param string $filePath */ public function __construct(string $filePath) { touch($filePath); if (($rights = config('excel.temporary_files.local_permissions.file', null)) !== null) { chmod($filePath, $rights); } $this->filePath = realpath($filePath); } /** * @return string */ public function getLocalPath(): string { return $this->filePath; } /** * @return bool */ public function exists(): bool { return file_exists($this->filePath); } /** * @return bool */ public function delete(): bool { if (@unlink($this->filePath) || !$this->exists()) { return true; } return unlink($this->filePath); } /** * @return resource */ public function readStream() { return fopen($this->getLocalPath(), 'rb+'); } /** * @return string */ public function contents(): string { return file_get_contents($this->filePath); } /** * @param @param string|resource $contents */ public function put($contents) { file_put_contents($this->filePath, $contents); } } excel/src/Files/TemporaryFileFactory.php 0000644 00000004426 15060131672 0014327 0 ustar 00 <?php namespace Maatwebsite\Excel\Files; use Illuminate\Support\Str; class TemporaryFileFactory { /** * @var string|null */ private $temporaryPath; /** * @var string|null */ private $temporaryDisk; /** * @param string|null $temporaryPath * @param string|null $temporaryDisk */ public function __construct(string $temporaryPath = null, string $temporaryDisk = null) { $this->temporaryPath = $temporaryPath; $this->temporaryDisk = $temporaryDisk; } /** * @param string|null $fileExtension * @return TemporaryFile */ public function make(string $fileExtension = null): TemporaryFile { if (null !== $this->temporaryDisk) { return $this->makeRemote($fileExtension); } return $this->makeLocal(null, $fileExtension); } /** * @param string|null $fileName * @param string|null $fileExtension * @return LocalTemporaryFile */ public function makeLocal(string $fileName = null, string $fileExtension = null): LocalTemporaryFile { if (!file_exists($this->temporaryPath) && !mkdir($concurrentDirectory = $this->temporaryPath, config('excel.temporary_files.local_permissions.dir', 0777), true) && !is_dir($concurrentDirectory)) { throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory)); } return new LocalTemporaryFile( $this->temporaryPath . DIRECTORY_SEPARATOR . ($fileName ?: $this->generateFilename($fileExtension)) ); } /** * @param string|null $fileExtension * @return RemoteTemporaryFile */ private function makeRemote(string $fileExtension = null): RemoteTemporaryFile { $filename = $this->generateFilename($fileExtension); return new RemoteTemporaryFile( $this->temporaryDisk, config('excel.temporary_files.remote_prefix') . $filename, $this->makeLocal($filename) ); } /** * @param string|null $fileExtension * @return string */ private function generateFilename(string $fileExtension = null): string { return 'laravel-excel-' . Str::random(32) . ($fileExtension ? '.' . $fileExtension : ''); } } excel/src/Excel.php 0000644 00000012045 15060131672 0010207 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; use Maatwebsite\Excel\Files\Filesystem; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Helpers\FileTypeDetector; 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 = []) { // Clear output buffer to prevent stuff being prepended to the Excel output. if (ob_get_length() > 0) { ob_end_clean(); ob_start(); } return response()->download( $this->export($export, $fileName, $writerType)->getLocalPath(), $fileName, $headers )->deleteFileAfterSend(true); } /** * {@inheritdoc} * * @param string|null $disk Fallback for usage with named properties */ public function store($export, string $filePath, string $diskName = null, string $writerType = null, $diskOptions = [], string $disk = null) { if ($export instanceof ShouldQueue) { return $this->queue($export, $filePath, $diskName ?: $disk, $writerType, $diskOptions); } $temporaryFile = $this->export($export, $filePath, $writerType); $exported = $this->filesystem->disk($diskName ?: $disk, $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 * @return TemporaryFile * * @throws \PhpOffice\PhpSpreadsheet\Exception */ protected function export($export, string $fileName, string $writerType = null): TemporaryFile { $writerType = FileTypeDetector::detectStrict($fileName, $writerType); return $this->writer->export($export, $writerType); } } excel/src/Console/ExportMakeCommand.php 0000755 00000004337 15060131672 0014137 0 ustar 00 <?php namespace Maatwebsite\Excel\Console; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputOption; class ExportMakeCommand extends GeneratorCommand { use WithModelStub; /** * The console command name. * * @var string */ protected $name = 'make:export'; /** * The console command description. * * @var string */ protected $description = 'Create a new export class'; /** * The type of class being generated. * * @var string */ protected $type = 'Export'; /** * Get the stub file for the generator. * * @return string */ protected function getStub() { if ($this->option('model') && $this->option('query')) { return $this->resolveStubPath('/stubs/export.query-model.stub'); } elseif ($this->option('model')) { return $this->resolveStubPath('/stubs/export.model.stub'); } elseif ($this->option('query')) { return $this->resolveStubPath('/stubs/export.query.stub'); } return $this->resolveStubPath('/stubs/export.plain.stub'); } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return $rootNamespace . '\Exports'; } /** * Build the class with the given name. * Remove the base controller import if we are already in base namespace. * * @param string $name * @return string */ protected function buildClass($name) { $replace = []; if ($this->option('model')) { $replace = $this->buildModelReplacements($replace); } return str_replace( array_keys($replace), array_values($replace), parent::buildClass($name) ); } /** * Get the console command options. * * @return array */ protected function getOptions() { return [ ['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate an export for the given model.'], ['query', '', InputOption::VALUE_NONE, 'Generate an export for a query.'], ]; } } excel/src/Console/stubs/import.model.stub 0000644 00000000542 15060131672 0014507 0 ustar 00 <?php namespace DummyNamespace; use DummyFullModelClass; use Maatwebsite\Excel\Concerns\ToModel; class DummyClass implements ToModel { /** * @param array $row * * @return \Illuminate\Database\Eloquent\Model|null */ public function model(array $row) { return new DummyModelClass([ // ]); } } excel/src/Console/stubs/export.query.stub 0000644 00000000352 15060131672 0014562 0 ustar 00 <?php namespace DummyNamespace; use Maatwebsite\Excel\Concerns\FromQuery; class DummyClass implements FromQuery { /** * @return \Illuminate\Database\Query\Builder */ public function query() { // } } excel/src/Console/stubs/export.model.stub 0000644 00000000452 15060131672 0014516 0 ustar 00 <?php namespace DummyNamespace; use DummyFullModelClass; use Maatwebsite\Excel\Concerns\FromCollection; class DummyClass implements FromCollection { /** * @return \Illuminate\Support\Collection */ public function collection() { return DummyModelClass::all(); } } excel/src/Console/stubs/export.query-model.stub 0000644 00000000441 15060131672 0015657 0 ustar 00 <?php namespace DummyNamespace; use DummyFullModelClass; use Maatwebsite\Excel\Concerns\FromQuery; class DummyClass implements FromQuery { /** * @return \Illuminate\Database\Query\Builder */ public function query() { return DummyModelClass::query(); } } excel/src/Console/stubs/export.plain.stub 0000644 00000000365 15060131672 0014524 0 ustar 00 <?php namespace DummyNamespace; use Maatwebsite\Excel\Concerns\FromCollection; class DummyClass implements FromCollection { /** * @return \Illuminate\Support\Collection */ public function collection() { // } } excel/src/Console/stubs/import.collection.stub 0000644 00000000441 15060131672 0015540 0 ustar 00 <?php namespace DummyNamespace; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ToCollection; class DummyClass implements ToCollection { /** * @param Collection $collection */ public function collection(Collection $collection) { // } } excel/src/Console/ImportMakeCommand.php 0000755 00000003565 15060131672 0014132 0 ustar 00 <?php namespace Maatwebsite\Excel\Console; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputOption; class ImportMakeCommand extends GeneratorCommand { use WithModelStub; /** * The console command name. * * @var string */ protected $name = 'make:import'; /** * The console command description. * * @var string */ protected $description = 'Create a new import class'; /** * The type of class being generated. * * @var string */ protected $type = 'Import'; /** * Get the stub file for the generator. * * @return string */ protected function getStub() { return $this->option('model') ? $this->resolveStubPath('/stubs/import.model.stub') : $this->resolveStubPath('/stubs/import.collection.stub'); } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return $rootNamespace . '\Imports'; } /** * Build the class with the given name. * Remove the base controller import if we are already in base namespace. * * @param string $name * @return string */ protected function buildClass($name) { $replace = []; if ($this->option('model')) { $replace = $this->buildModelReplacements($replace); } return str_replace( array_keys($replace), array_values($replace), parent::buildClass($name) ); } /** * Get the console command options. * * @return array */ protected function getOptions() { return [ ['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate an import for the given model.'], ]; } } excel/src/Console/WithModelStub.php 0000644 00000003132 15060131672 0013300 0 ustar 00 <?php namespace Maatwebsite\Excel\Console; use Illuminate\Support\Str; use InvalidArgumentException; trait WithModelStub { /** * Build the model replacement values. * * @param array $replace * @return array */ protected function buildModelReplacements(array $replace): array { $modelClass = $this->parseModel($this->option('model')); return array_merge($replace, [ 'DummyFullModelClass' => $modelClass, 'DummyModelClass' => class_basename($modelClass), ]); } /** * Get the fully-qualified model class name. * * @param string $model * @return string */ protected function parseModel($model): string { if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) { throw new InvalidArgumentException('Model name contains invalid characters.'); } $model = ltrim($model, '\\/'); $model = str_replace('/', '\\', $model); $rootNamespace = $this->rootNamespace(); if (Str::startsWith($model, $rootNamespace)) { return $model; } $model = is_dir(app_path('Models')) ? $rootNamespace . 'Models\\' . $model : $rootNamespace . $model; return $model; } /** * Resolve the fully-qualified path to the stub. * * @param string $stub * @return string */ protected function resolveStubPath($stub) { return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) ? $customPath : __DIR__ . $stub; } } excel/src/MappedReader.php 0000644 00000002622 15060131672 0011500 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ToArray; use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithCalculatedFormulas; use Maatwebsite\Excel\Concerns\WithFormatData; use Maatwebsite\Excel\Concerns\WithMappedCells; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class MappedReader { /** * @param WithMappedCells $import * @param Worksheet $worksheet * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function map(WithMappedCells $import, Worksheet $worksheet) { $mapped = $import->mapping(); array_walk_recursive($mapped, function (&$coordinate) use ($import, $worksheet) { $cell = Cell::make($worksheet, $coordinate); $coordinate = $cell->getValue( null, $import instanceof WithCalculatedFormulas, $import instanceof WithFormatData ); }); if ($import instanceof ToModel) { $model = $import->model($mapped); if ($model) { $model->saveOrFail(); } } if ($import instanceof ToCollection) { $import->collection(new Collection($mapped)); } if ($import instanceof ToArray) { $import->array($mapped); } } } excel/src/Sheet.php 0000644 00000061670 15060131672 0010227 0 ustar 00 <?php namespace Maatwebsite\Excel; use Closure; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; use Maatwebsite\Excel\Concerns\FromArray; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\FromGenerator; use Maatwebsite\Excel\Concerns\FromIterator; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\FromView; use Maatwebsite\Excel\Concerns\OnEachRow; use Maatwebsite\Excel\Concerns\ShouldAutoSize; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\ToArray; use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithCalculatedFormulas; use Maatwebsite\Excel\Concerns\WithCharts; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithColumnFormatting; use Maatwebsite\Excel\Concerns\WithColumnLimit; use Maatwebsite\Excel\Concerns\WithColumnWidths; use Maatwebsite\Excel\Concerns\WithCustomChunkSize; use Maatwebsite\Excel\Concerns\WithCustomStartCell; use Maatwebsite\Excel\Concerns\WithCustomValueBinder; use Maatwebsite\Excel\Concerns\WithDrawings; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\WithFormatData; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Concerns\WithMappedCells; use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithProgressBar; use Maatwebsite\Excel\Concerns\WithStrictNullComparison; use Maatwebsite\Excel\Concerns\WithStyles; use Maatwebsite\Excel\Concerns\WithTitle; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Events\AfterSheet; use Maatwebsite\Excel\Events\BeforeSheet; use Maatwebsite\Excel\Exceptions\ConcernConflictException; use Maatwebsite\Excel\Exceptions\RowSkippedException; use Maatwebsite\Excel\Exceptions\SheetNotFoundException; use Maatwebsite\Excel\Files\TemporaryFileFactory; use Maatwebsite\Excel\Helpers\ArrayHelper; use Maatwebsite\Excel\Helpers\CellHelper; use Maatwebsite\Excel\Imports\EndRowFinder; use Maatwebsite\Excel\Imports\HeadingRowExtractor; use Maatwebsite\Excel\Imports\ModelImporter; use Maatwebsite\Excel\Validators\RowValidator; use PhpOffice\PhpSpreadsheet\Cell\Cell as SpreadsheetCell; use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Html; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; /** @mixin Worksheet */ class Sheet { use DelegatedMacroable, HasEventBus; /** * @var int */ protected $chunkSize; /** * @var TemporaryFileFactory */ protected $temporaryFileFactory; /** * @var object */ protected $exportable; /** * @var Worksheet */ private $worksheet; /** * @param Worksheet $worksheet */ public function __construct(Worksheet $worksheet) { $this->worksheet = $worksheet; $this->chunkSize = config('excel.exports.chunk_size', 100); $this->temporaryFileFactory = app(TemporaryFileFactory::class); } /** * @param Spreadsheet $spreadsheet * @param string|int $index * @return Sheet * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws SheetNotFoundException */ public static function make(Spreadsheet $spreadsheet, $index) { if (is_numeric($index)) { return self::byIndex($spreadsheet, $index); } return self::byName($spreadsheet, $index); } /** * @param Spreadsheet $spreadsheet * @param int $index * @return Sheet * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws SheetNotFoundException */ public static function byIndex(Spreadsheet $spreadsheet, int $index): Sheet { if (!isset($spreadsheet->getAllSheets()[$index])) { throw SheetNotFoundException::byIndex($index, $spreadsheet->getSheetCount()); } return new static($spreadsheet->getSheet($index)); } /** * @param Spreadsheet $spreadsheet * @param string $name * @return Sheet * * @throws SheetNotFoundException */ public static function byName(Spreadsheet $spreadsheet, string $name): Sheet { if (!$spreadsheet->sheetNameExists($name)) { throw SheetNotFoundException::byName($name); } return new static($spreadsheet->getSheetByName($name)); } /** * @param object $sheetExport * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function open($sheetExport) { $this->exportable = $sheetExport; if ($sheetExport instanceof WithCustomValueBinder) { SpreadsheetCell::setValueBinder($sheetExport); } if ($sheetExport instanceof WithEvents) { $this->registerListeners($sheetExport->registerEvents()); } $this->raise(new BeforeSheet($this, $this->exportable)); if ($sheetExport instanceof WithTitle) { $title = $sheetExport->title(); $title = str_replace(['*', ':', '/', '\\', '?', '[', ']'], '', $title); if (StringHelper::countCharacters($title) > Worksheet::SHEET_TITLE_MAXIMUM_LENGTH) { $title = StringHelper::substring($title, 0, Worksheet::SHEET_TITLE_MAXIMUM_LENGTH); } $this->worksheet->setTitle($title); } if (($sheetExport instanceof FromQuery || $sheetExport instanceof FromCollection || $sheetExport instanceof FromArray) && $sheetExport instanceof FromView) { throw ConcernConflictException::queryOrCollectionAndView(); } if (!$sheetExport instanceof FromView && $sheetExport instanceof WithHeadings) { if ($sheetExport instanceof WithCustomStartCell) { $startCell = $sheetExport->startCell(); } $this->append( ArrayHelper::ensureMultipleRows($sheetExport->headings()), $startCell ?? null, $this->hasStrictNullComparison($sheetExport) ); } if ($sheetExport instanceof WithCharts) { $this->addCharts($sheetExport->charts()); } } /** * @param object $sheetExport * * @throws \PhpOffice\PhpSpreadsheet\Exception * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function export($sheetExport) { $this->open($sheetExport); if ($sheetExport instanceof FromView) { $this->fromView($sheetExport); } else { if ($sheetExport instanceof FromQuery) { $this->fromQuery($sheetExport, $this->worksheet); } if ($sheetExport instanceof FromCollection) { $this->fromCollection($sheetExport); } if ($sheetExport instanceof FromArray) { $this->fromArray($sheetExport); } if ($sheetExport instanceof FromIterator) { $this->fromIterator($sheetExport); } if ($sheetExport instanceof FromGenerator) { $this->fromGenerator($sheetExport); } } $this->close($sheetExport); } /** * @param object $import * @param int $startRow */ public function import($import, int $startRow = 1) { if ($import instanceof WithEvents) { $this->registerListeners($import->registerEvents()); } $this->raise(new BeforeSheet($this, $import)); if ($import instanceof WithProgressBar && !$import instanceof WithChunkReading) { $import->getConsoleOutput()->progressStart($this->worksheet->getHighestRow()); } $calculatesFormulas = $import instanceof WithCalculatedFormulas; $formatData = $import instanceof WithFormatData; if ($import instanceof WithMappedCells) { app(MappedReader::class)->map($import, $this->worksheet); } else { if ($import instanceof ToModel) { app(ModelImporter::class)->import($this->worksheet, $import, $startRow); } if ($import instanceof ToCollection) { $rows = $this->toCollection($import, $startRow, null, $calculatesFormulas, $formatData); if ($import instanceof WithValidation) { $rows = $this->validated($import, $startRow, $rows); } $import->collection($rows); } if ($import instanceof ToArray) { $rows = $this->toArray($import, $startRow, null, $calculatesFormulas, $formatData); if ($import instanceof WithValidation) { $rows = $this->validated($import, $startRow, $rows); } $import->array($rows); } } if ($import instanceof OnEachRow) { $headingRow = HeadingRowExtractor::extract($this->worksheet, $import); $headerIsGrouped = HeadingRowExtractor::extractGrouping($headingRow, $import); $endColumn = $import instanceof WithColumnLimit ? $import->endColumn() : null; $preparationCallback = $this->getPreparationCallback($import); foreach ($this->worksheet->getRowIterator()->resetStart($startRow ?? 1) as $row) { $sheetRow = new Row($row, $headingRow, $headerIsGrouped); if ($import instanceof WithValidation) { $sheetRow->setPreparationCallback($preparationCallback); } $rowArray = $sheetRow->toArray(null, $import instanceof WithCalculatedFormulas, $import instanceof WithFormatData, $endColumn); $rowIsEmptyAccordingToImport = $import instanceof SkipsEmptyRows && method_exists($import, 'isEmptyWhen') && $import->isEmptyWhen($rowArray); if (!$import instanceof SkipsEmptyRows || ($import instanceof SkipsEmptyRows && (!$rowIsEmptyAccordingToImport && !$sheetRow->isEmpty($calculatesFormulas)))) { if ($import instanceof WithValidation) { $toValidate = [$sheetRow->getIndex() => $rowArray]; try { app(RowValidator::class)->validate($toValidate, $import); $import->onRow($sheetRow); } catch (RowSkippedException $e) { } } else { $import->onRow($sheetRow); } } if ($import instanceof WithProgressBar) { $import->getConsoleOutput()->progressAdvance(); } } } $this->raise(new AfterSheet($this, $import)); if ($import instanceof WithProgressBar && !$import instanceof WithChunkReading) { $import->getConsoleOutput()->progressFinish(); } } /** * @param object $import * @param int|null $startRow * @param null $nullValue * @param bool $calculateFormulas * @param bool $formatData * @return array */ public function toArray($import, int $startRow = null, $nullValue = null, $calculateFormulas = false, $formatData = false) { if ($startRow > $this->worksheet->getHighestRow()) { return []; } $endRow = EndRowFinder::find($import, $startRow, $this->worksheet->getHighestRow()); $headingRow = HeadingRowExtractor::extract($this->worksheet, $import); $headerIsGrouped = HeadingRowExtractor::extractGrouping($headingRow, $import); $endColumn = $import instanceof WithColumnLimit ? $import->endColumn() : null; $rows = []; foreach ($this->worksheet->getRowIterator($startRow, $endRow) as $index => $row) { $row = new Row($row, $headingRow, $headerIsGrouped); if ($import instanceof SkipsEmptyRows && $row->isEmpty($calculateFormulas, $endColumn)) { continue; } $row = $row->toArray($nullValue, $calculateFormulas, $formatData, $endColumn); if ($import && method_exists($import, 'isEmptyWhen') && $import->isEmptyWhen($row)) { continue; } if ($import instanceof WithMapping) { $row = $import->map($row); } if ($import instanceof WithValidation && method_exists($import, 'prepareForValidation')) { $row = $import->prepareForValidation($row, $index); } $rows[] = $row; if ($import instanceof WithProgressBar) { $import->getConsoleOutput()->progressAdvance(); } } return $rows; } /** * @param object $import * @param int|null $startRow * @param null $nullValue * @param bool $calculateFormulas * @param bool $formatData * @return Collection */ public function toCollection($import, int $startRow = null, $nullValue = null, $calculateFormulas = false, $formatData = false): Collection { $rows = $this->toArray($import, $startRow, $nullValue, $calculateFormulas, $formatData); return new Collection(array_map(function (array $row) { return new Collection($row); }, $rows)); } /** * @param object $sheetExport * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function close($sheetExport) { if ($sheetExport instanceof WithDrawings) { $this->addDrawings($sheetExport->drawings()); } $this->exportable = $sheetExport; if ($sheetExport instanceof WithColumnFormatting) { foreach ($sheetExport->columnFormats() as $column => $format) { $this->formatColumn($column, $format); } } if ($sheetExport instanceof ShouldAutoSize) { $this->autoSize(); } if ($sheetExport instanceof WithColumnWidths) { foreach ($sheetExport->columnWidths() as $column => $width) { $this->worksheet->getColumnDimension($column)->setAutoSize(false)->setWidth($width); } } if ($sheetExport instanceof WithStyles) { $styles = $sheetExport->styles($this->worksheet); if (is_array($styles)) { foreach ($styles as $coordinate => $coordinateStyles) { if (is_numeric($coordinate)) { $coordinate = 'A' . $coordinate . ':' . $this->worksheet->getHighestColumn($coordinate) . $coordinate; } $this->worksheet->getStyle($coordinate)->applyFromArray($coordinateStyles); } } } $this->raise(new AfterSheet($this, $this->exportable)); $this->clearListeners(); } /** * @param FromView $sheetExport * @param int|null $sheetIndex * * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception */ public function fromView(FromView $sheetExport, $sheetIndex = null) { $temporaryFile = $this->temporaryFileFactory->makeLocal(null, 'html'); $temporaryFile->put($sheetExport->view()->render()); $spreadsheet = $this->worksheet->getParent(); /** @var Html $reader */ $reader = IOFactory::createReader('Html'); // If no sheetIndex given, insert content into the last sheet $reader->setSheetIndex($sheetIndex ?? $spreadsheet->getSheetCount() - 1); $reader->loadIntoExisting($temporaryFile->getLocalPath(), $spreadsheet); $temporaryFile->delete(); } /** * @param FromQuery $sheetExport * @param Worksheet $worksheet */ public function fromQuery(FromQuery $sheetExport, Worksheet $worksheet) { if ($sheetExport->query() instanceof \Laravel\Scout\Builder) { $this->fromScout($sheetExport, $worksheet); return; } $sheetExport->query()->chunk($this->getChunkSize($sheetExport), function ($chunk) use ($sheetExport) { $this->appendRows($chunk, $sheetExport); }); } /** * @param FromQuery $sheetExport * @param Worksheet $worksheet */ public function fromScout(FromQuery $sheetExport, Worksheet $worksheet) { $scout = $sheetExport->query(); $chunkSize = $this->getChunkSize($sheetExport); $chunk = $scout->paginate($chunkSize); // Append first page $this->appendRows($chunk->items(), $sheetExport); // Append rest of pages for ($page = 2; $page <= $chunk->lastPage(); $page++) { $this->appendRows($scout->paginate($chunkSize, 'page', $page)->items(), $sheetExport); } } /** * @param FromCollection $sheetExport */ public function fromCollection(FromCollection $sheetExport) { $this->appendRows($sheetExport->collection()->all(), $sheetExport); } /** * @param FromArray $sheetExport */ public function fromArray(FromArray $sheetExport) { $this->appendRows($sheetExport->array(), $sheetExport); } /** * @param FromIterator $sheetExport */ public function fromIterator(FromIterator $sheetExport) { $iterator = class_exists(LazyCollection::class) ? new LazyCollection(function () use ($sheetExport) { foreach ($sheetExport->iterator() as $row) { yield $row; } }) : $sheetExport->iterator(); $this->appendRows($iterator, $sheetExport); } /** * @param FromGenerator $sheetExport */ public function fromGenerator(FromGenerator $sheetExport) { $generator = class_exists(LazyCollection::class) ? new LazyCollection(function () use ($sheetExport) { foreach ($sheetExport->generator() as $row) { yield $row; } }) : $sheetExport->generator(); $this->appendRows($generator, $sheetExport); } /** * @param array $rows * @param string|null $startCell * @param bool $strictNullComparison */ public function append(array $rows, string $startCell = null, bool $strictNullComparison = false) { if (!$startCell) { $startCell = 'A1'; } if ($this->hasRows()) { $startCell = CellHelper::getColumnFromCoordinate($startCell) . ($this->worksheet->getHighestRow() + 1); } $this->worksheet->fromArray($rows, null, $startCell, $strictNullComparison); } public function autoSize() { foreach ($this->buildColumnRange('A', $this->worksheet->getHighestDataColumn()) as $col) { $dimension = $this->worksheet->getColumnDimension($col); // Only auto-size columns that have not have an explicit width. if ($dimension->getWidth() == -1) { $dimension->setAutoSize(true); } } } /** * @param string $column * @param string $format * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public function formatColumn(string $column, string $format) { // If the column is a range, we wouldn't need to calculate the range. if (stripos($column, ':') !== false) { $this->worksheet ->getStyle($column) ->getNumberFormat() ->setFormatCode($format); } else { $this->worksheet ->getStyle($column . '1:' . $column . $this->worksheet->getHighestRow()) ->getNumberFormat() ->setFormatCode($format); } } /** * @param int $chunkSize * @return Sheet */ public function chunkSize(int $chunkSize) { $this->chunkSize = $chunkSize; return $this; } /** * @return Worksheet */ public function getDelegate() { return $this->worksheet; } /** * @param Chart|Chart[] $charts */ public function addCharts($charts) { $charts = \is_array($charts) ? $charts : [$charts]; foreach ($charts as $chart) { $this->worksheet->addChart($chart); } } /** * @param BaseDrawing|BaseDrawing[] $drawings */ public function addDrawings($drawings) { $drawings = \is_array($drawings) ? $drawings : [$drawings]; foreach ($drawings as $drawing) { $drawing->setWorksheet($this->worksheet); } } /** * @param string $concern * @return string */ public function hasConcern(string $concern): string { return $this->exportable instanceof $concern; } /** * @param iterable $rows * @param object $sheetExport */ public function appendRows($rows, $sheetExport) { if (method_exists($sheetExport, 'prepareRows')) { $rows = $sheetExport->prepareRows($rows); } $rows = $rows instanceof LazyCollection ? $rows : new Collection($rows); $rows->flatMap(function ($row) use ($sheetExport) { if ($sheetExport instanceof WithMapping) { $row = $sheetExport->map($row); } if ($sheetExport instanceof WithCustomValueBinder) { SpreadsheetCell::setValueBinder($sheetExport); } return ArrayHelper::ensureMultipleRows( static::mapArraybleRow($row) ); })->chunk(1000)->each(function ($rows) use ($sheetExport) { $this->append( $rows->toArray(), $sheetExport instanceof WithCustomStartCell ? $sheetExport->startCell() : null, $this->hasStrictNullComparison($sheetExport) ); }); } /** * @param mixed $row * @return array */ public static function mapArraybleRow($row): array { // When dealing with eloquent models, we'll skip the relations // as we won't be able to display them anyway. if (is_object($row) && method_exists($row, 'attributesToArray')) { return $row->attributesToArray(); } if ($row instanceof Arrayable) { return $row->toArray(); } // Convert StdObjects to arrays if (is_object($row)) { return json_decode(json_encode($row), true); } return $row; } /** * @param $sheetImport * @return int */ public function getStartRow($sheetImport): int { return HeadingRowExtractor::determineStartRow($sheetImport); } /** * Disconnect the sheet. */ public function disconnect() { $this->worksheet->disconnectCells(); unset($this->worksheet); } /** * @return Collection|array */ protected function validated(WithValidation $import, int $startRow, $rows) { $toValidate = (new Collection($rows))->mapWithKeys(function ($row, $index) use ($startRow) { return [($startRow + $index) => $row]; }); try { app(RowValidator::class)->validate($toValidate->toArray(), $import); } catch (RowSkippedException $e) { foreach ($e->skippedRows() as $row) { unset($rows[$row - $startRow]); } } return $rows; } /** * @param string $lower * @param string $upper * @return \Generator */ protected function buildColumnRange(string $lower, string $upper) { $upper++; for ($i = $lower; $i !== $upper; $i++) { yield $i; } } /** * @return bool */ private function hasRows(): bool { $startCell = 'A1'; if ($this->exportable instanceof WithCustomStartCell) { $startCell = $this->exportable->startCell(); } return $this->worksheet->cellExists($startCell); } /** * @param object $sheetExport * @return bool */ private function hasStrictNullComparison($sheetExport): bool { if ($sheetExport instanceof WithStrictNullComparison) { return true; } return config('excel.exports.strict_null_comparison', false); } /** * @param object|WithCustomChunkSize $export * @return int */ private function getChunkSize($export): int { if ($export instanceof WithCustomChunkSize) { return $export->chunkSize(); } return $this->chunkSize; } /** * @param object|WithValidation $import * @return Closure|null */ private function getPreparationCallback($import) { if (!$import instanceof WithValidation || !method_exists($import, 'prepareForValidation')) { return null; } return function (array $data, int $index) use ($import) { return $import->prepareForValidation($data, $index); }; } } excel/src/Importer.php 0000644 00000003034 15060131672 0010746 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Support\Collection; interface Importer { /** * @param object $import * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath * @param string|null $disk * @param string|null $readerType * @return Reader|\Illuminate\Foundation\Bus\PendingDispatch */ public function import($import, $filePath, string $disk = null, string $readerType = null); /** * @param object $import * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath * @param string|null $disk * @param string|null $readerType * @return array */ public function toArray($import, $filePath, string $disk = null, string $readerType = null): array; /** * @param object $import * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath * @param string|null $disk * @param string|null $readerType * @return Collection */ public function toCollection($import, $filePath, string $disk = null, string $readerType = null): Collection; /** * @param ShouldQueue $import * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath * @param string|null $disk * @param string $readerType * @return \Illuminate\Foundation\Bus\PendingDispatch */ public function queueImport(ShouldQueue $import, $filePath, string $disk = null, string $readerType = null); } excel/src/Row.php 0000644 00000010175 15060131672 0007720 0 ustar 00 <?php namespace Maatwebsite\Excel; use ArrayAccess; use Closure; use Illuminate\Support\Collection; use PhpOffice\PhpSpreadsheet\Worksheet\Row as SpreadsheetRow; /** @mixin SpreadsheetRow */ class Row implements ArrayAccess { use DelegatedMacroable; /** * @var array */ protected $headingRow = []; /** * @var array */ protected $headerIsGrouped = []; /** * @var \Closure */ protected $preparationCallback; /** * @var SpreadsheetRow */ protected $row; /** * @var array|null */ protected $rowCache; /** * @var bool|null */ protected $rowCacheFormatData; /** * @var string|null */ protected $rowCacheEndColumn; /** * @param SpreadsheetRow $row * @param array $headingRow * @param array $headerIsGrouped */ public function __construct(SpreadsheetRow $row, array $headingRow = [], array $headerIsGrouped = []) { $this->row = $row; $this->headingRow = $headingRow; $this->headerIsGrouped = $headerIsGrouped; } /** * @return SpreadsheetRow */ public function getDelegate(): SpreadsheetRow { return $this->row; } /** * @param null $nullValue * @param bool $calculateFormulas * @param bool $formatData * @param string|null $endColumn * @return Collection */ public function toCollection($nullValue = null, $calculateFormulas = false, $formatData = true, ?string $endColumn = null): Collection { return new Collection($this->toArray($nullValue, $calculateFormulas, $formatData, $endColumn)); } /** * @param null $nullValue * @param bool $calculateFormulas * @param bool $formatData * @param string|null $endColumn * @return array */ public function toArray($nullValue = null, $calculateFormulas = false, $formatData = true, ?string $endColumn = null) { if (is_array($this->rowCache) && ($this->rowCacheFormatData === $formatData) && ($this->rowCacheEndColumn === $endColumn)) { return $this->rowCache; } $cells = []; $i = 0; foreach ($this->row->getCellIterator('A', $endColumn) as $cell) { $value = (new Cell($cell))->getValue($nullValue, $calculateFormulas, $formatData); if (isset($this->headingRow[$i])) { if (!$this->headerIsGrouped[$i]) { $cells[$this->headingRow[$i]] = $value; } else { $cells[$this->headingRow[$i]][] = $value; } } else { $cells[] = $value; } $i++; } if (isset($this->preparationCallback)) { $cells = ($this->preparationCallback)($cells, $this->row->getRowIndex()); } $this->rowCache = $cells; $this->rowCacheFormatData = $formatData; $this->rowCacheEndColumn = $endColumn; return $cells; } /** * @param bool $calculateFormulas * @param string|null $endColumn * @return bool */ public function isEmpty($calculateFormulas = false, ?string $endColumn = null): bool { return count(array_filter($this->toArray(null, $calculateFormulas, false, $endColumn))) === 0; } /** * @return int */ public function getIndex(): int { return $this->row->getRowIndex(); } #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->toArray()[$offset]); } #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->toArray()[$offset]; } #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { // } #[\ReturnTypeWillChange] public function offsetUnset($offset) { // } /** * @param \Closure $preparationCallback * * @internal */ public function setPreparationCallback(Closure $preparationCallback = null) { $this->preparationCallback = $preparationCallback; } } excel/src/DefaultValueBinder.php 0000644 00000001075 15060131672 0012655 0 ustar 00 <?php namespace Maatwebsite\Excel; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder as PhpSpreadsheetDefaultValueBinder; class DefaultValueBinder extends PhpSpreadsheetDefaultValueBinder { /** * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell * @return bool */ public function bindValue(Cell $cell, $value) { if (is_array($value)) { $value = \json_encode($value); } return parent::bindValue($cell, $value); } } excel/src/Cell.php 0000644 00000004535 15060131672 0010033 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Pipeline\Pipeline; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Cell\Cell as SpreadsheetCell; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; /** @mixin SpreadsheetCell */ class Cell { use DelegatedMacroable; /** * @var SpreadsheetCell */ private $cell; /** * @param SpreadsheetCell $cell */ public function __construct(SpreadsheetCell $cell) { $this->cell = $cell; } /** * @param Worksheet $worksheet * @param string $coordinate * @return Cell * * @throws \PhpOffice\PhpSpreadsheet\Exception */ public static function make(Worksheet $worksheet, string $coordinate) { return new static($worksheet->getCell($coordinate)); } /** * @return SpreadsheetCell */ public function getDelegate(): SpreadsheetCell { return $this->cell; } /** * @param null $nullValue * @param bool $calculateFormulas * @param bool $formatData * @return mixed */ public function getValue($nullValue = null, $calculateFormulas = false, $formatData = true) { $value = $nullValue; if ($this->cell->getValue() !== null) { if ($this->cell->getValue() instanceof RichText) { $value = $this->cell->getValue()->getPlainText(); } elseif ($calculateFormulas) { try { $value = $this->cell->getCalculatedValue(); } catch (Exception $e) { $value = $this->cell->getOldCalculatedValue(); } } else { $value = $this->cell->getValue(); } if ($formatData) { $style = $this->cell->getWorksheet()->getParent()->getCellXfByIndex($this->cell->getXfIndex()); $value = NumberFormat::toFormattedString( $value, ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : NumberFormat::FORMAT_GENERAL ); } } return app(Pipeline::class)->send($value)->through(config('excel.imports.cells.middleware', []))->thenReturn(); } } excel/src/QueuedWriter.php 0000644 00000016543 15060131672 0011603 0 ustar 00 <?php namespace Maatwebsite\Excel; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\FromView; use Maatwebsite\Excel\Concerns\WithCustomChunkSize; use Maatwebsite\Excel\Concerns\WithCustomQuerySize; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Files\TemporaryFileFactory; use Maatwebsite\Excel\Jobs\AppendDataToSheet; use Maatwebsite\Excel\Jobs\AppendPaginatedToSheet; use Maatwebsite\Excel\Jobs\AppendQueryToSheet; use Maatwebsite\Excel\Jobs\AppendViewToSheet; use Maatwebsite\Excel\Jobs\CloseSheet; use Maatwebsite\Excel\Jobs\QueueExport; use Maatwebsite\Excel\Jobs\StoreQueuedExport; use Traversable; class QueuedWriter { /** * @var Writer */ protected $writer; /** * @var int */ protected $chunkSize; /** * @var TemporaryFileFactory */ protected $temporaryFileFactory; /** * @param Writer $writer * @param TemporaryFileFactory $temporaryFileFactory */ public function __construct(Writer $writer, TemporaryFileFactory $temporaryFileFactory) { $this->writer = $writer; $this->chunkSize = config('excel.exports.chunk_size', 1000); $this->temporaryFileFactory = $temporaryFileFactory; } /** * @param object $export * @param string $filePath * @param string $disk * @param string|null $writerType * @param array|string $diskOptions * @return \Illuminate\Foundation\Bus\PendingDispatch */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { $extension = pathinfo($filePath, PATHINFO_EXTENSION); $temporaryFile = $this->temporaryFileFactory->make($extension); $jobs = $this->buildExportJobs($export, $temporaryFile, $writerType); $jobs->push(new StoreQueuedExport( $temporaryFile, $filePath, $disk, $diskOptions )); return new PendingDispatch( (new QueueExport($export, $temporaryFile, $writerType))->chain($jobs->toArray()) ); } /** * @param object $export * @param TemporaryFile $temporaryFile * @param string $writerType * @return Collection */ private function buildExportJobs($export, TemporaryFile $temporaryFile, string $writerType): Collection { $sheetExports = [$export]; if ($export instanceof WithMultipleSheets) { $sheetExports = $export->sheets(); } $jobs = new Collection; foreach ($sheetExports as $sheetIndex => $sheetExport) { if ($sheetExport instanceof FromCollection) { $jobs = $jobs->merge($this->exportCollection($sheetExport, $temporaryFile, $writerType, $sheetIndex)); } elseif ($sheetExport instanceof FromQuery) { $jobs = $jobs->merge($this->exportQuery($sheetExport, $temporaryFile, $writerType, $sheetIndex)); } elseif ($sheetExport instanceof FromView) { $jobs = $jobs->merge($this->exportView($sheetExport, $temporaryFile, $writerType, $sheetIndex)); } $jobs->push(new CloseSheet($sheetExport, $temporaryFile, $writerType, $sheetIndex)); } return $jobs; } /** * @param FromCollection $export * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @return Collection|LazyCollection */ private function exportCollection( FromCollection $export, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex ) { return $export ->collection() ->chunk($this->getChunkSize($export)) ->map(function ($rows) use ($writerType, $temporaryFile, $sheetIndex, $export) { if ($rows instanceof Traversable) { $rows = iterator_to_array($rows); } return new AppendDataToSheet( $export, $temporaryFile, $writerType, $sheetIndex, $rows ); }); } /** * @param FromQuery $export * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @return Collection */ private function exportQuery( FromQuery $export, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex ): Collection { $query = $export->query(); if ($query instanceof \Laravel\Scout\Builder) { return $this->exportScout($export, $temporaryFile, $writerType, $sheetIndex); } $count = $export instanceof WithCustomQuerySize ? $export->querySize() : $query->count(); $spins = ceil($count / $this->getChunkSize($export)); $jobs = new Collection(); for ($page = 1; $page <= $spins; $page++) { $jobs->push(new AppendQueryToSheet( $export, $temporaryFile, $writerType, $sheetIndex, $page, $this->getChunkSize($export) )); } return $jobs; } /** * @param FromQuery $export * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @return Collection */ private function exportScout( FromQuery $export, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex ): Collection { $jobs = new Collection(); $chunk = $export->query()->paginate($this->getChunkSize($export)); // Append first page $jobs->push(new AppendDataToSheet( $export, $temporaryFile, $writerType, $sheetIndex, $chunk->items() )); // Append rest of pages for ($page = 2; $page <= $chunk->lastPage(); $page++) { $jobs->push(new AppendPaginatedToSheet( $export, $temporaryFile, $writerType, $sheetIndex, $page, $this->getChunkSize($export) )); } return $jobs; } /** * @param FromView $export * @param TemporaryFile $temporaryFile * @param string $writerType * @param int $sheetIndex * @return Collection */ private function exportView( FromView $export, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex ): Collection { $jobs = new Collection(); $jobs->push(new AppendViewToSheet( $export, $temporaryFile, $writerType, $sheetIndex )); return $jobs; } /** * @param object|WithCustomChunkSize $export * @return int */ private function getChunkSize($export): int { if ($export instanceof WithCustomChunkSize) { return $export->chunkSize(); } return $this->chunkSize; } } excel/src/Exceptions/NoFilenameGivenException.php 0000644 00000001050 15060131672 0016147 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use InvalidArgumentException; use Throwable; class NoFilenameGivenException extends InvalidArgumentException implements LaravelExcelException { /** * @param string $message * @param int $code * @param Throwable|null $previous */ public function __construct( $message = 'A filename needs to be passed in order to download the export', $code = 0, Throwable $previous = null ) { parent::__construct($message, $code, $previous); } } excel/src/Exceptions/RowSkippedException.php 0000644 00000001343 15060131672 0015235 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use Exception; use Illuminate\Support\Collection; use Maatwebsite\Excel\Validators\Failure; class RowSkippedException extends Exception { /** * @var Failure[] */ private $failures; /** * @param Failure ...$failures */ public function __construct(Failure ...$failures) { $this->failures = $failures; parent::__construct(); } /** * @return Failure[]|Collection */ public function failures(): Collection { return new Collection($this->failures); } /** * @return int[] */ public function skippedRows(): array { return $this->failures()->map->row()->all(); } } excel/src/Exceptions/ConcernConflictException.php 0000644 00000000612 15060131672 0016215 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use LogicException; class ConcernConflictException extends LogicException implements LaravelExcelException { /** * @return ConcernConflictException */ public static function queryOrCollectionAndView() { return new static('Cannot use FromQuery, FromArray or FromCollection and FromView on the same sheet.'); } } excel/src/Exceptions/NoTypeDetectedException.php 0000644 00000001120 15060131672 0016017 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use Exception; use Throwable; class NoTypeDetectedException extends Exception implements LaravelExcelException { /** * @param string $message * @param int $code * @param Throwable|null $previous */ public function __construct( $message = 'No ReaderType or WriterType could be detected. Make sure you either pass a valid extension to the filename or pass an explicit type.', $code = 0, Throwable $previous = null ) { parent::__construct($message, $code, $previous); } } excel/src/Exceptions/SheetNotFoundException.php 0000644 00000001331 15060131672 0015670 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; class SheetNotFoundException extends \Exception implements LaravelExcelException { /** * @param string $name * @return SheetNotFoundException */ public static function byName(string $name): SheetNotFoundException { return new static("Your requested sheet name [{$name}] is out of bounds."); } /** * @param int $index * @param int $sheetCount * @return SheetNotFoundException */ public static function byIndex(int $index, int $sheetCount): SheetNotFoundException { return new static("Your requested sheet index: {$index} is out of bounds. The actual number of sheets is {$sheetCount}."); } } excel/src/Exceptions/NoFilePathGivenException.php 0000644 00000001626 15060131672 0016134 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use InvalidArgumentException; use Throwable; class NoFilePathGivenException extends InvalidArgumentException implements LaravelExcelException { /** * @param string $message * @param int $code * @param Throwable|null $previous */ public function __construct( $message = 'A filepath needs to be passed.', $code = 0, Throwable $previous = null ) { parent::__construct($message, $code, $previous); } /** * @return NoFilePathGivenException */ public static function import() { return new static('A filepath or UploadedFile needs to be passed to start the import.'); } /** * @return NoFilePathGivenException */ public static function export() { return new static('A filepath needs to be passed in order to store the export.'); } } excel/src/Exceptions/NoSheetsFoundException.php 0000644 00000000236 15060131672 0015672 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use LogicException; class NoSheetsFoundException extends LogicException implements LaravelExcelException { } excel/src/Exceptions/LaravelExcelException.php 0000644 00000000166 15060131672 0015517 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use Throwable; interface LaravelExcelException extends Throwable { } excel/src/Exceptions/UnreadableFileException.php 0000644 00000000742 15060131672 0016012 0 ustar 00 <?php namespace Maatwebsite\Excel\Exceptions; use Exception; use Throwable; class UnreadableFileException extends Exception implements LaravelExcelException { /** * @param string $message * @param int $code * @param Throwable|null $previous */ public function __construct( $message = 'File could not be read', $code = 0, Throwable $previous = null ) { parent::__construct($message, $code, $previous); } } excel/.phpunit.cache/test-results 0000644 00000261530 15060131672 0013064 0 ustar 00 {"version":1,"defects":{"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import_with_batch_cache":5,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export_with_batch_cache":8,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_batch_cache":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_relation_query_queued":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_eager_loads":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_eager_loads_and_queued":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_without_using_eloquent":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_without_using_eloquent_and_queued":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_with_nested_arrays":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_with_nested_arrays_queued":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_batch_caching":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_prepare_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_scout":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::can_export_from_view":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::can_export_multiple_sheets_from_view":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_from_uploaded_file":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_csv_file_with_html_tags_inside":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_with_ignore_empty_set_to_true":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_with_ignore_empty_set_to_false":8,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::can_import_each_row_individually":8,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::it_respects_the_end_column":8,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::events_get_called_when_importing":8,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersChunkOffsetTest::can_access_chunk_offset_on_import_to_array_in_chunks":8,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_array_in_chunks":8,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_array_in_chunks_with_batch_inserts":8,"ShouldQueueWithoutChainTest::can_import_to_model_in_chunks":8,"ShouldQueueWithoutChainTest::can_import_to_model_without_job_chaining":8,"ShouldQueueWithoutChainTest::a_queue_name_can_be_specified_when_importing":8,"ShouldQueueWithoutChainTest::the_cleanup_only_runs_when_all_jobs_are_done":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_to_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_on_each_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_importing_to_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_importing_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_using_oneachrow":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::can_skip_on_error":7,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::can_skip_errors_and_collect_all_errors_at_the_end":7,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_skip_on_error":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::skips_only_failed_rows_in_batch":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_skip_failures_and_collect_all_failures_at_the_end":8,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_validate_using_oneachrow_and_skipsonfailure":7,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_validate_using_tocollection_and_skipsonfailure":7,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::can_import_to_array":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::can_import_multiple_sheets_to_array":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::can_import_to_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::can_import_multiple_sheets_to_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_each_row_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::has_timestamps_when_imported_single_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_multiple_models_in_single_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_multiple_different_types_of_models_in_single_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_to_model_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_to_model_in_batches_bigger_file":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_multiple_different_types_of_models_in_single_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::has_timestamps_when_imported_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::by_default_does_not_calculate_formulas":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_model_with_calculated_formulas":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas_and_multi_sheet_references":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas_and_skips_empty":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_model_with_calculated_formulas_and_skips_empty":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_un":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_heading_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_csv_in_chunks_and_insert_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_in_chunks":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_index":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_name":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_catch_job_failed_in_chunks":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_and_format_in_chunks":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_in_chunks_without_formatting":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::can_import_to_array_with_column_limit":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::can_import_to_array_with_column_limit_and_skips_empty_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithConditionalSheetsTest::can_select_which_sheets_will_be_imported":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_read_csv_import_with_custom_settings":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::cannot_read_with_wrong_delimiter":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomQuerySizeTest::can_export_with_custom_count":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::can_set_a_value_binder_on_import":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::import_events_get_called":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::import_chunked_events_get_called":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_array":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_array_with_format_data":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_array_with_format_data_and_skips_empty_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_collection_with_format_data":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_model_with_format_data":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_to_array_with_grouped_headers":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_oneachrow_with_grouped_headers":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_to_collection_with_grouped_headers":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_each_row_to_model_with_grouped_headers":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_each_row_to_model_with_heading_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_each_row_to_model_with_different_heading_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_to_array_with_heading_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_empty_rows_with_header":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_empty_models_with_header":7,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_cast_empty_headers_to_indexed_int":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_import_a_limited_section_of_rows_to_model_with_different_start_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_import_to_array_with_limit":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_set_limit_bigger_than_row_size":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_references_to_cells":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_nested_references_to_cells":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_references_to_cells_to_model":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_export_with_multiple_sheets_using_collections":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_export_multiple_sheets_from_view":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_index_will_throw_sheet_not_found_exception":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_name_will_throw_sheet_not_found_exception":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_name_can_be_ignored":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored_per_name":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored_per_sheet":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_name":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_index_and_name":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_name_and_index":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::can_import_each_row_to_model_with_different_start_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::can_import_to_array_with_start_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_batches_with_defined_upsert_columns":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_rows_with_defined_upsert_columns":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_closure_validation_rules":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_custom_validation_rule_objects":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_conditionality":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_unless_conditionality":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_combined_rules_with_colons":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_with_custom_attributes":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_with_custom_message":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_headings":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_grouped_headings":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_in_batches":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_oneachrow":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_array":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_configure_validator":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_toarray":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_tocollection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_tomodel":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_oneachrow":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_skipsemptyrows":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_tsv_file":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_chain_imports":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_from_uploaded_file":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_from_real_path":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_without_extension_with_explicit_reader_type":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_model_collection_with_headings_as_excel":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::cannot_queue_import_that_does_not_implement_should_queue":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import":7,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import_with_batch_cache_and_file_store":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_import_with_remote_temp_disk":7,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_keep_extension_for_temp_file_on_remote_disk":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_import_with_remote_temp_disk_and_prefix":7,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_automatically_delete_temp_file_on_failure_when_using_remote_disk":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::cannot_automatically_delete_temp_file_on_failure_when_using_local_disk":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_force_remote_download_and_deletion_for_each_chunk_on_queue":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_middleware_method_on_queued_import":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_retry_until_method_on_queued_import":8,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_max_exceptions_property_on_queued_import":8,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export":8,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_batch_cache_and_file_store":8,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_mapping":8,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_scout_export":8,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::can_queue_an_export":8,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::can_export_multiple_sheets_from_view":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_lazy_collection":8,"Maatwebsite\\Excel\\Tests\\CellTest::can_get_cell_value":7,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::export_chunked_events_get_called":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromArrayTest::can_export_from_array":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_with_multiple_sheets_from_collection":8,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_lazy_collection_with_queue":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnFormattingTest::can_export_with_column_formatting":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnWidthsTest::can_set_column_width":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_store_csv_export_with_custom_settings":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_store_csv_export_with_custom_encoding":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomStartCellTest::can_store_collection_with_custom_start_cell":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::can_set_a_value_binder_on_export":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithDefaultStylesTest::can_configure_default_styles":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_heading_row":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_multiple_heading_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_heading_row_with_custom_start_cell":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::can_export_with_heading":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::can_return_multiple_rows_in_map":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::json_array_columns_shouldnt_be_detected_as_multiple_rows":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exported_zero_values_are_not_null_when_exporting_with_strict_null_comparison":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exported_zero_values_are_null_when_not_exporting_with_strict_null_comparison":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exports_trailing_empty_cells":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exports_trailing_empty_cells_by_setting_config_strict_null_comparison":8,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStylesTest::can_configure_styles":8,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_csv_export_with_custom_settings":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_a_collection_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_a_collection_with_headers_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_collection_with_headers_with_hidden_eloquent_attributes":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_collection_with_headers_when_making_attributes_visible":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_set_custom_response_headers":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::can_download_a_query_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::can_download_a_collection_with_headers_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportAsMacroTest::can_import_directly_into_a_model_with_mapping":8,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportMacroTest::can_import_directly_into_a_model":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_as_excel_on_non_default_disk":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_with_headings_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_download_a_query_as_excel":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_download_a_query_as_excel_on_different_disk":8,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_store_a_query_with_headers_as_excel":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export_and_store_on_different_disk":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_remote_temp_disk":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_remote_temp_disk_and_prefix":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_implicitly_queue_an_export":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_mapping_on_eloquent_models":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_set_locale_on_queue_export_job":8,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_not_flushing_the_cache":8,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_models_with_belongs_to_relations":7,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_models_with_belongs_to_many_relations":7,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_writes_to_cache_with_a_dateinterval_ttl":7,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_heading_row_formatter":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_heading_row_formatter_with_key":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_row_number":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets_with_key":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets_with_custom_row_number":5,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_heading_row_with_custom_formatter_defined_in_config":5,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_cannot_import_a_non_existing_xlsx_file":8},"times":{"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import_with_batch_cache":2.346,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export":0.241,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export_with_batch_cache":0.067,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_batch_cache":0.374,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::will_get_multiple_from_memory_if_cells_hold_in_memory":0.02,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::will_get_multiple_from_cache_if_cells_are_persisted":0.002,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::will_get_multiple_from_cache_and_persisted":0.001,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_persists_to_cache_when_memory_limit_reached_on_setting_a_value":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_persists_to_cache_when_memory_limit_reached_on_setting_multiple_values":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_writes_to_cache_with_default_ttl#null (forever)":0.001,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_writes_to_cache_with_default_ttl#int value":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_writes_to_cache_with_default_ttl#callable":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_writes_to_cache_with_a_dateinterval_ttl":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::it_can_override_default_ttl":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::needs_to_have_a_file_name_when_downloading":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::needs_to_have_a_file_name_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::needs_to_have_a_file_name_when_queuing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::responsable_needs_to_have_file_name_configured_inside_the_export":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::is_responsable":0.037,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_have_customized_header":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_set_custom_headers_in_export_class":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_get_raw_export_contents":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_have_customized_disk_options_when_storing":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_have_customized_disk_options_when_queueing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_set_disk_options_in_export_class_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_set_disk_options_in_export_class_when_queuing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_override_export_class_disk_options_when_calling_store":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_override_export_class_disk_options_when_calling_queue":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_have_empty_disk_options_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::can_have_empty_disk_options_when_queueing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\FromArrayTest::can_export_from_array":0.011,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_collection":0.036,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_with_multiple_sheets_from_collection":0.139,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_lazy_collection":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\FromGeneratorTest::can_export_from_generator":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\FromIteratorTest::can_export_from_iterator":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_from_uploaded_file":0.008,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_csv_file_with_html_tags_inside":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_with_ignore_empty_set_to_true":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::can_import_a_simple_xlsx_file_with_ignore_empty_set_to_false":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::can_import_each_row_individually":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::it_respects_the_end_column":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::events_get_called_when_exporting":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::events_get_called_when_importing":0.01,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::can_have_invokable_class_as_listener":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersChunkOffsetTest::can_set_and_get_chunk_offset":0,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersChunkOffsetTest::can_access_chunk_offset_on_import_to_array_in_chunks":0.249,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_set_and_get_row_number":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_model":0.185,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_array_in_chunks":3.444,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::can_access_row_number_on_import_to_array_in_chunks_with_batch_inserts":3.44,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_to_collection":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_on_each_row":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::skips_empty_rows_when_importing_to_model":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_importing_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_importing_to_model":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::custom_skips_rows_when_using_oneachrow":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::can_import_to_array":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::can_import_multiple_sheets_to_array":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::can_import_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::can_import_multiple_sheets_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::can_configure_background_color_from_rgb_string":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::can_configure_background_color_as_array":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::can_configure_background_color_with_color_instance":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::by_default_does_not_calculate_formulas":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_model_with_calculated_formulas":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas_and_multi_sheet_references":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_array_with_calculated_formulas_and_skips_empty":0.018,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::can_import_to_model_with_calculated_formulas_and_skips_empty":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnFormattingTest::can_export_with_column_formatting":0.008,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnWidthsTest::can_set_column_width":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_store_csv_export_with_custom_settings":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_store_csv_export_with_custom_encoding":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_read_csv_with_auto_detecting_delimiter_semicolon":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_read_csv_with_auto_detecting_delimiter_comma":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::can_read_csv_import_with_custom_settings":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::cannot_read_with_wrong_delimiter":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomStartCellTest::can_store_collection_with_custom_start_cell":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::can_set_a_value_binder_on_export":0.011,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::can_set_a_value_binder_on_import":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithDefaultStylesTest::can_configure_default_styles":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::export_events_get_called":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::import_events_get_called":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::import_chunked_events_get_called":0.499,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::can_have_invokable_class_as_listener":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::can_have_global_event_listeners":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::can_have_custom_concern_handlers":0.012,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::can_have_custom_sheet_concern_handlers":0.011,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_array":0.008,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_array_with_format_data":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_array_with_format_data_and_skips_empty_rows":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_collection_with_format_data":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::by_default_import_to_model":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::can_import_to_model_with_format_data":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_heading_row":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_multiple_heading_rows":0.021,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::can_export_from_collection_with_heading_row_with_custom_start_cell":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::can_export_with_heading":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::can_return_multiple_rows_in_map":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::json_array_columns_shouldnt_be_detected_as_multiple_rows":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::can_set_custom_document_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::it_merges_with_default_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::it_ignores_empty_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithReadFilterTest::can_register_custom_read_filter":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exported_zero_values_are_not_null_when_exporting_with_strict_null_comparison":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exported_zero_values_are_null_when_not_exporting_with_strict_null_comparison":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exports_trailing_empty_cells":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::exports_trailing_empty_cells_by_setting_config_strict_null_comparison":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStylesTest::can_configure_styles":0.009,"Maatwebsite\\Excel\\Tests\\Concerns\\WithTitleTest::can_export_with_title":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithTitleTest::can_export_sheet_title_when_longer_than_max_length":0.006,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::can_call_methods_from_delegate":0.004,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::can_use_writer_macros":0.004,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::can_use_sheet_macros":0.004,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_fake_an_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_downloaded_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_stored_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_regex_against_a_fake_stored_export_with_multiple_files":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::a_callback_can_be_passed_as_the_second_argument_when_asserting_against_a_faked_stored_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_implicitly_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_queued_export_with_chain":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_raw_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_import_with_uploaded_file":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_queued_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_implicitly_queued_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::can_assert_against_a_fake_queued_import_with_chain":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::a_callback_can_be_passed_as_the_second_argument_when_asserting_against_a_faked_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::custom_transaction_handler_is_bound":0.001,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::is_bound":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::has_aliased":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::registers_console_commands":0.006,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::sets_php_spreadsheet_settings":0,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_download_an_export_object_with_facade":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_download_an_export_object":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_an_export_object_on_default_disk":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_an_export_object_on_another_disk":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_csv_export_with_default_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_get_raw_export_contents":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_tsv_export_with_default_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_store_csv_export_with_custom_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::cannot_use_from_collection_and_from_view_on_same_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_to_array":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_to_collection":0.039,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_to_collection_without_import_object":0.031,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_tsv_file":0.005,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_chain_imports":0.006,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_from_uploaded_file":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_a_simple_xlsx_file_from_real_path":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::import_will_throw_error_when_no_reader_type_could_be_detected_when_no_extension":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::import_will_throw_error_when_no_reader_type_could_be_detected_with_unknown_extension":0.013,"Maatwebsite\\Excel\\Tests\\ExcelTest::can_import_without_extension_with_explicit_reader_type":0.004,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row":0.059,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_heading_row_formatter":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_heading_row_formatter_with_key":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_with_custom_row_number":0.008,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets_with_key":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_only_heading_row_for_multiple_sheets_with_custom_row_number":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::can_import_heading_row_with_custom_formatter_defined_in_config":0.003,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::read_chunk_job_can_interact_with_queue":0.001,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::append_data_to_sheet_job_can_interact_with_queue":0,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::append_query_to_sheet_job_can_interact_with_queue":0,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::append_view_to_sheet_job_can_interact_with_queue":0,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_a_collection_as_excel":0.008,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_a_collection_with_headers_as_excel":0.009,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_collection_with_headers_with_hidden_eloquent_attributes":0.007,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_download_collection_with_headers_when_making_attributes_visible":0.007,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::can_set_custom_response_headers":0.005,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_as_excel":0.011,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_as_excel_on_non_default_disk":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_collection_with_headings_as_excel":0.007,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::can_store_a_model_collection_with_headings_as_excel":0.008,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export_and_store_on_different_disk":0.234,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_remote_temp_disk":0.276,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_remote_temp_disk_and_prefix":0.24,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_implicitly_queue_an_export":0.241,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_with_mapping_on_eloquent_models":0.017,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_catch_failures":0.007,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_catch_failures_on_queue_export_job":0.003,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_set_locale_on_queue_export_job":0.015,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_export_not_flushing_the_cache":0.294,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::can_use_default_rights":0.001,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::can_use_dir_rights":0.001,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::can_use_file_rights":0.001,"ShouldQueueWithoutChainTest::can_import_to_model_in_chunks":0.065,"ShouldQueueWithoutChainTest::can_import_to_model_without_job_chaining":0.053,"ShouldQueueWithoutChainTest::a_queue_name_can_be_specified_when_importing":0.045,"ShouldQueueWithoutChainTest::the_cleanup_only_runs_when_all_jobs_are_done":0.067,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::can_skip_on_error":0.039,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::can_skip_errors_and_collect_all_errors_at_the_end":0.036,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_skip_on_error":0.037,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::skips_only_failed_rows_in_batch":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_skip_failures_and_collect_all_failures_at_the_end":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_validate_using_oneachrow_and_skipsonfailure":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::can_validate_using_tocollection_and_skipsonfailure":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_each_row_to_model":0.058,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::has_timestamps_when_imported_single_model":0.052,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_multiple_models_in_single_to_model":0.06,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_multiple_different_types_of_models_in_single_to_model":0.063,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_to_model_in_batches":0.074,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_to_model_in_batches_bigger_file":0.278,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::can_import_multiple_different_types_of_models_in_single_to_model":0.054,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::has_timestamps_when_imported_in_batches":0.056,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_un":0.065,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches":0.436,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_heading_row":0.429,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_csv_in_chunks_and_insert_in_batches":1.206,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets":1.223,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_in_chunks":1.854,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_index":1.216,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_name":1.211,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_catch_job_failed_in_chunks":0.048,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_and_format_in_chunks":0.054,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::can_import_to_array_in_chunks_without_formatting":0.048,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::can_import_to_array_with_column_limit":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::can_import_to_array_with_column_limit_and_skips_empty_rows":0.033,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_to_array_with_grouped_headers":0.055,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_oneachrow_with_grouped_headers":0.053,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_to_collection_with_grouped_headers":0.05,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::can_import_each_row_to_model_with_grouped_headers":0.061,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_each_row_to_model_with_heading_row":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_each_row_to_model_with_different_heading_row":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_to_array_with_heading_row":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_empty_rows_with_header":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_import_empty_models_with_header":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::can_cast_empty_headers_to_indexed_int":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_import_a_limited_section_of_rows_to_model_with_different_start_row":0.057,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_import_to_array_with_limit":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::can_set_limit_bigger_than_row_size":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_references_to_cells":0.034,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_nested_references_to_cells":0.031,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::can_import_with_references_to_cells_to_model":0.041,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::can_import_each_row_to_model_with_different_start_row":0.027,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::can_import_to_array_with_start_row":0.027,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_batches":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_rows":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_batches_with_defined_upsert_columns":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::can_upsert_models_in_rows_with_defined_upsert_columns":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows":0.068,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_closure_validation_rules":0.054,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_custom_validation_rule_objects":0.07,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_conditionality":0.053,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_unless_conditionality":0.056,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_combined_rules_with_colons":0.067,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_with_custom_attributes":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_with_custom_message":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_headings":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_with_grouped_headings":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_rows_in_batches":0.052,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_oneachrow":0.05,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_collection":0.053,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_validate_using_array":0.129,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_configure_validator":0.059,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_toarray":0.057,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_tocollection":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_tomodel":0.053,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_oneachrow":0.052,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::can_prepare_using_skipsemptyrows":0.06,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::cannot_queue_import_that_does_not_implement_should_queue":0.053,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import":2.07,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import_with_batch_cache_and_file_store":2.129,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_import_with_remote_temp_disk":2.209,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_keep_extension_for_temp_file_on_remote_disk":2.125,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_import_with_remote_temp_disk_and_prefix":2.08,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_automatically_delete_temp_file_on_failure_when_using_remote_disk":0.106,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::cannot_automatically_delete_temp_file_on_failure_when_using_local_disk":0.12,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_force_remote_download_and_deletion_for_each_chunk_on_queue":2.13,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_middleware_method_on_queued_import":0.065,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_retry_until_method_on_queued_import":0.064,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_define_max_exceptions_property_on_queued_import":0.105,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query":0.116,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_relation_query_queued":0.181,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_eager_loads":0.085,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_eager_loads_and_queued":0.106,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_without_using_eloquent":0.063,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_without_using_eloquent_and_queued":0.149,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_with_nested_arrays":0.069,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_builder_with_nested_arrays_queued":0.079,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_batch_caching":0.114,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_query_with_prepare_rows":0.123,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::can_export_from_scout":0.117,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::can_export_from_view":0.041,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::can_export_multiple_sheets_from_view":0.094,"Maatwebsite\\Excel\\Tests\\Concerns\\WithConditionalSheetsTest::can_select_which_sheets_will_be_imported":0.013,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomQuerySizeTest::can_export_with_custom_count":0.09,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_export_with_multiple_sheets_using_collections":0.151,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_export_multiple_sheets_from_view":0.11,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_index_will_throw_sheet_not_found_exception":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_name_will_throw_sheet_not_found_exception":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_name_can_be_ignored":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored_per_name":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::unknown_sheet_indices_can_be_ignored_per_sheet":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets":0.013,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_name":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_index_and_name":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::can_import_multiple_sheets_by_sheet_name_and_index":0.004,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export":0.208,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_batch_cache_and_file_store":0.262,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_an_export_with_mapping":0.049,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::can_queue_scout_export":0.228,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::can_queue_an_export":0.145,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::can_export_multiple_sheets_from_view":0.26,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::can_export_from_lazy_collection_with_queue":0.026,"Maatwebsite\\Excel\\Tests\\CellTest::can_get_cell_value":0.029,"Maatwebsite\\Excel\\Tests\\CellTest::can_trim_empty_cells":0.004,"Maatwebsite\\Excel\\Tests\\CellTest::convert_empty_cells_to_null":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::export_chunked_events_get_called":0.113,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportAsMacroTest::can_import_directly_into_a_model_with_mapping":0.036,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportMacroTest::can_import_directly_into_a_model":0.036,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::can_download_a_query_as_excel":0.062,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::can_download_a_collection_with_headers_as_excel":0.061,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_download_a_query_as_excel":0.063,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_download_a_query_as_excel_on_different_disk":0.061,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::can_store_a_query_with_headers_as_excel":0.07,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_models_with_belongs_to_relations":0.067,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::can_import_models_with_belongs_to_many_relations":0.07,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row":0.003,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_will_get_multiple_from_memory_if_cells_hold_in_memory":0.035,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_will_get_multiple_from_cache_if_cells_are_persisted":0.002,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_will_get_multiple_from_cache_and_persisted":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_persists_to_cache_when_memory_limit_reached_on_setting_a_value":0.001,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_persists_to_cache_when_memory_limit_reached_on_setting_multiple_values":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_writes_to_cache_with_default_ttl#null (forever)":0.002,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_writes_to_cache_with_default_ttl#int value":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_writes_to_cache_with_default_ttl#callable":0.001,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_writes_to_cache_with_a_dateinterval_ttl":0,"Maatwebsite\\Excel\\Tests\\Cache\\BatchCacheTest::test_it_can_override_default_ttl":0,"Maatwebsite\\Excel\\Tests\\CellTest::test_can_get_cell_value":0.043,"Maatwebsite\\Excel\\Tests\\CellTest::test_can_trim_empty_cells":0.004,"Maatwebsite\\Excel\\Tests\\CellTest::test_convert_empty_cells_to_null":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_needs_to_have_a_file_name_when_downloading":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_needs_to_have_a_file_name_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_needs_to_have_a_file_name_when_queuing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_responsable_needs_to_have_file_name_configured_inside_the_export":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_is_responsable":0.046,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_have_customized_header":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_set_custom_headers_in_export_class":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_get_raw_export_contents":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_have_customized_disk_options_when_storing":0.008,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_have_customized_disk_options_when_queueing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_set_disk_options_in_export_class_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_set_disk_options_in_export_class_when_queuing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_override_export_class_disk_options_when_calling_store":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_override_export_class_disk_options_when_calling_queue":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_have_empty_disk_options_when_storing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\ExportableTest::test_can_have_empty_disk_options_when_queueing":0,"Maatwebsite\\Excel\\Tests\\Concerns\\FromArrayTest::test_can_export_from_array":0.017,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::test_can_export_from_collection":0.037,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::test_can_export_with_multiple_sheets_from_collection":0.141,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::test_can_export_from_lazy_collection":0.009,"Maatwebsite\\Excel\\Tests\\Concerns\\FromCollectionTest::test_can_export_from_lazy_collection_with_queue":0.058,"Maatwebsite\\Excel\\Tests\\Concerns\\FromGeneratorTest::test_can_export_from_generator":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\FromIteratorTest::test_can_export_from_iterator":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query":0.115,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_relation_query_queued":0.183,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_with_eager_loads":0.085,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_with_eager_loads_and_queued":0.106,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_builder_without_using_eloquent":0.07,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_builder_without_using_eloquent_and_queued":0.149,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_builder_with_nested_arrays":0.07,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_builder_with_nested_arrays_queued":0.09,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_with_batch_caching":0.116,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_query_with_prepare_rows":0.117,"Maatwebsite\\Excel\\Tests\\Concerns\\FromQueryTest::test_can_export_from_scout":0.144,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::test_can_export_from_view":0.04,"Maatwebsite\\Excel\\Tests\\Concerns\\FromViewTest::test_can_export_multiple_sheets_from_view":0.101,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_can_import_a_simple_xlsx_file":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_can_import_a_simple_xlsx_file_from_uploaded_file":0.011,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_can_import_a_simple_csv_file_with_html_tags_inside":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_can_import_a_simple_xlsx_file_with_ignore_empty_set_to_true":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_can_import_a_simple_xlsx_file_with_ignore_empty_set_to_false":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::test_can_import_each_row_individually":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\OnEachRowTest::test_it_respects_the_end_column":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::test_events_get_called_when_exporting":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::test_events_get_called_when_importing":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RegistersEventListenersTest::test_can_have_invokable_class_as_listener":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersChunkOffsetTest::test_can_set_and_get_chunk_offset":0,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersChunkOffsetTest::test_can_access_chunk_offset_on_import_to_array_in_chunks":0.26,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::test_can_set_and_get_row_number":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::test_can_access_row_number_on_import_to_model":0.189,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::test_can_access_row_number_on_import_to_array_in_chunks":3.492,"Maatwebsite\\Excel\\Tests\\Concerns\\RemembersRowNumberTest::test_can_access_row_number_on_import_to_array_in_chunks_with_batch_inserts":3.486,"ShouldQueueWithoutChainTest::test_can_import_to_model_in_chunks":0.065,"ShouldQueueWithoutChainTest::test_can_import_to_model_without_job_chaining":0.046,"ShouldQueueWithoutChainTest::test_a_queue_name_can_be_specified_when_importing":0.051,"ShouldQueueWithoutChainTest::test_the_cleanup_only_runs_when_all_jobs_are_done":0.061,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_skips_empty_rows_when_importing_to_collection":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_skips_empty_rows_when_importing_on_each_row":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_skips_empty_rows_when_importing_to_model":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_custom_skips_rows_when_importing_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_custom_skips_rows_when_importing_to_model":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsEmptyRowsTest::test_custom_skips_rows_when_using_oneachrow":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::test_can_skip_on_error":0.042,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnErrorTest::test_can_skip_errors_and_collect_all_errors_at_the_end":0.037,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::test_can_skip_on_error":0.038,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::test_skips_only_failed_rows_in_batch":0.027,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::test_can_skip_failures_and_collect_all_failures_at_the_end":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::test_can_validate_using_oneachrow_and_skipsonfailure":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\SkipsOnFailureTest::test_can_validate_using_tocollection_and_skipsonfailure":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::test_can_import_to_array":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ToArrayTest::test_can_import_multiple_sheets_to_array":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::test_can_import_to_collection":0.009,"Maatwebsite\\Excel\\Tests\\Concerns\\ToCollectionTest::test_can_import_multiple_sheets_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_can_import_each_row_to_model":0.064,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_has_timestamps_when_imported_single_model":0.055,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_can_import_multiple_models_in_single_to_model":0.059,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_can_import_multiple_different_types_of_models_in_single_to_model":0.055,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_can_import_models_with_belongs_to_relations":0.068,"Maatwebsite\\Excel\\Tests\\Concerns\\ToModelTest::test_can_import_models_with_belongs_to_many_relations":0.076,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::test_can_configure_background_color_from_rgb_string":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::test_can_configure_background_color_as_array":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBackgroundColorTest::test_can_configure_background_color_with_color_instance":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::test_can_import_to_model_in_batches":0.059,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::test_can_import_to_model_in_batches_bigger_file":0.278,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::test_can_import_multiple_different_types_of_models_in_single_to_model":0.054,"Maatwebsite\\Excel\\Tests\\Concerns\\WithBatchInsertsTest::test_has_timestamps_when_imported_in_batches":0.058,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_by_default_does_not_calculate_formulas":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_can_import_to_array_with_calculated_formulas":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_can_import_to_model_with_calculated_formulas":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_can_import_to_array_with_calculated_formulas_and_multi_sheet_references":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_can_import_to_array_with_calculated_formulas_and_skips_empty":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCalculatedFormulasTest::test_can_import_to_model_with_calculated_formulas_and_skips_empty":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_un":0.064,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_and_insert_in_batches":0.438,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_and_insert_in_batches_with_heading_row":0.441,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_csv_in_chunks_and_insert_in_batches":1.218,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets":1.254,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_array_in_chunks":1.882,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_index":1.222,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_model_in_chunks_and_insert_in_batches_with_multiple_sheets_objects_by_name":1.219,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_catch_job_failed_in_chunks":0.048,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_array_and_format_in_chunks":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithChunkReadingTest::test_can_import_to_array_in_chunks_without_formatting":0.088,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnFormattingTest::test_can_export_with_column_formatting":0.009,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::test_can_import_to_array_with_column_limit":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnLimitTest::test_can_import_to_array_with_column_limit_and_skips_empty_rows":0.032,"Maatwebsite\\Excel\\Tests\\Concerns\\WithColumnWidthsTest::test_can_set_column_width":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithConditionalSheetsTest::test_can_select_which_sheets_will_be_imported":0.013,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_can_store_csv_export_with_custom_settings":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_can_store_csv_export_with_custom_encoding":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_can_read_csv_with_auto_detecting_delimiter_semicolon":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_can_read_csv_with_auto_detecting_delimiter_comma":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_can_read_csv_import_with_custom_settings":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomCsvSettingsTest::test_cannot_read_with_wrong_delimiter":0.002,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomQuerySizeTest::test_can_export_with_custom_count":0.09,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomStartCellTest::test_can_store_collection_with_custom_start_cell":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::test_can_set_a_value_binder_on_export":0.014,"Maatwebsite\\Excel\\Tests\\Concerns\\WithCustomValueBinderTest::test_can_set_a_value_binder_on_import":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithDefaultStylesTest::test_can_configure_default_styles":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_export_events_get_called":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_import_events_get_called":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_import_chunked_events_get_called":0.494,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_can_have_invokable_class_as_listener":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_can_have_global_event_listeners":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_can_have_custom_concern_handlers":0.012,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_can_have_custom_sheet_concern_handlers":0.012,"Maatwebsite\\Excel\\Tests\\Concerns\\WithEventsTest::test_export_chunked_events_get_called":0.113,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_by_default_import_to_array":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_can_import_to_array_with_format_data":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_can_import_to_array_with_format_data_and_skips_empty_rows":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_by_default_import_to_collection":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_can_import_to_collection_with_format_data":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_by_default_import_to_model":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithFormatDataTest::test_can_import_to_model_with_format_data":0.005,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::test_can_import_to_array_with_grouped_headers":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::test_can_import_oneachrow_with_grouped_headers":0.047,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::test_can_import_to_collection_with_grouped_headers":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithGroupedHeadingRowTest::test_can_import_each_row_to_model_with_grouped_headers":0.068,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_import_each_row_to_model_with_heading_row":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_import_each_row_to_model_with_different_heading_row":0.032,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_import_to_array_with_heading_row":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_import_empty_rows_with_header":0.03,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_import_empty_models_with_header":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingRowTest::test_can_cast_empty_headers_to_indexed_int":0.025,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::test_can_export_from_collection_with_heading_row":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::test_can_export_from_collection_with_multiple_heading_rows":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithHeadingsTest::test_can_export_from_collection_with_heading_row_with_custom_start_cell":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::test_can_import_a_limited_section_of_rows_to_model_with_different_start_row":0.033,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::test_can_import_to_array_with_limit":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithLimitTest::test_can_set_limit_bigger_than_row_size":0.025,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::test_can_import_with_references_to_cells":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::test_can_import_with_nested_references_to_cells":0.026,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappedCellsTest::test_can_import_with_references_to_cells_to_model":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::test_can_export_with_heading":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::test_can_return_multiple_rows_in_map":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMappingTest::test_json_array_columns_shouldnt_be_detected_as_multiple_rows":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_export_with_multiple_sheets_using_collections":0.143,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_export_multiple_sheets_from_view":0.11,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_index_will_throw_sheet_not_found_exception":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_name_will_throw_sheet_not_found_exception":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_name_can_be_ignored":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_indices_can_be_ignored_per_name":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_indices_can_be_ignored":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_unknown_sheet_indices_can_be_ignored_per_sheet":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_import_multiple_sheets":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_import_multiple_sheets_by_sheet_name":0.013,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_import_multiple_sheets_by_sheet_index_and_name":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithMultipleSheetsTest::test_can_import_multiple_sheets_by_sheet_name_and_index":0.004,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::test_can_set_custom_document_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::test_it_merges_with_default_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithPropertiesTest::test_it_ignores_empty_properties":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithReadFilterTest::test_can_register_custom_read_filter":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::test_can_import_each_row_to_model_with_different_start_row":0.027,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStartRowTest::test_can_import_to_array_with_start_row":0.04,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::test_exported_zero_values_are_not_null_when_exporting_with_strict_null_comparison":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::test_exported_zero_values_are_null_when_not_exporting_with_strict_null_comparison":0.007,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::test_exports_trailing_empty_cells":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStrictNullComparisonTest::test_exports_trailing_empty_cells_by_setting_config_strict_null_comparison":0.003,"Maatwebsite\\Excel\\Tests\\Concerns\\WithStylesTest::test_can_configure_styles":0.009,"Maatwebsite\\Excel\\Tests\\Concerns\\WithTitleTest::test_can_export_with_title":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithTitleTest::test_can_export_sheet_title_when_longer_than_max_length":0.006,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::test_can_upsert_models_in_batches":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::test_can_upsert_models_in_rows":0.041,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::test_can_upsert_models_in_batches_with_defined_upsert_columns":0.029,"Maatwebsite\\Excel\\Tests\\Concerns\\WithUpsertsTest::test_can_upsert_models_in_rows_with_defined_upsert_columns":0.028,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_closure_validation_rules":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_custom_validation_rule_objects":0.052,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_conditionality":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_unless_conditionality":0.052,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_combined_rules_with_colons":0.069,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_with_custom_attributes":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_with_custom_message":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_headings":0.055,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_with_grouped_headings":0.049,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_rows_in_batches":0.05,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_using_oneachrow":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_using_collection":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_validate_using_array":0.048,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_configure_validator":0.057,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_prepare_using_toarray":0.05,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_prepare_using_tocollection":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_prepare_using_tomodel":0.051,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_prepare_using_oneachrow":0.05,"Maatwebsite\\Excel\\Tests\\Concerns\\WithValidationTest::test_can_prepare_using_skipsemptyrows":0.049,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::test_can_call_methods_from_delegate":0.004,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::test_can_use_writer_macros":0.004,"Maatwebsite\\Excel\\Tests\\DelegatedMacroableTest::test_can_use_sheet_macros":0.004,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_fake_an_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_downloaded_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_stored_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_regex_against_a_fake_stored_export_with_multiple_files":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_a_callback_can_be_passed_as_the_second_argument_when_asserting_against_a_faked_stored_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_implicitly_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_queued_export_with_chain":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_raw_export":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_import_with_uploaded_file":0.001,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_queued_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_implicitly_queued_import":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_can_assert_against_a_fake_queued_import_with_chain":0,"Maatwebsite\\Excel\\Tests\\ExcelFakeTest::test_a_callback_can_be_passed_as_the_second_argument_when_asserting_against_a_faked_queued_export":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::test_custom_transaction_handler_is_bound":0.001,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::test_is_bound":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::test_has_aliased":0,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::test_registers_console_commands":0.007,"Maatwebsite\\Excel\\Tests\\ExcelServiceProviderTest::test_sets_php_spreadsheet_settings":0,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_download_an_export_object_with_facade":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_download_an_export_object":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_store_an_export_object_on_default_disk":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_store_an_export_object_on_another_disk":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_store_csv_export_with_default_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_get_raw_export_contents":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_store_tsv_export_with_default_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_store_csv_export_with_custom_settings":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_cannot_use_from_collection_and_from_view_on_same_export":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file_to_array":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file_to_collection":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file_to_collection_without_import_object":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_tsv_file":0.005,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_chain_imports":0.006,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file_from_uploaded_file":0.004,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_a_simple_xlsx_file_from_real_path":0.003,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_import_will_throw_error_when_no_reader_type_could_be_detected_when_no_extension":0.001,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_import_will_throw_error_when_no_reader_type_could_be_detected_with_unknown_extension":0.036,"Maatwebsite\\Excel\\Tests\\ExcelTest::test_can_import_without_extension_with_explicit_reader_type":0.004,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_with_custom_heading_row_formatter":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_with_custom_heading_row_formatter_with_key":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_with_custom_row_number":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_for_multiple_sheets":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_for_multiple_sheets_with_key":0.008,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_only_heading_row_for_multiple_sheets_with_custom_row_number":0.003,"Maatwebsite\\Excel\\Tests\\HeadingRowImportTest::test_can_import_heading_row_with_custom_formatter_defined_in_config":0.003,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::test_read_chunk_job_can_interact_with_queue":0.001,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::test_append_data_to_sheet_job_can_interact_with_queue":0,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::test_append_query_to_sheet_job_can_interact_with_queue":0,"Maatwebsite\\Excel\\Tests\\InteractsWithQueueTest::test_append_view_to_sheet_job_can_interact_with_queue":0.001,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::test_can_download_a_collection_as_excel":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::test_can_download_a_collection_with_headers_as_excel":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::test_can_download_collection_with_headers_with_hidden_eloquent_attributes":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::test_can_download_collection_with_headers_when_making_attributes_visible":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadCollectionTest::test_can_set_custom_response_headers":0.004,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::test_can_download_a_query_as_excel":0.058,"Maatwebsite\\Excel\\Tests\\Mixins\\DownloadQueryMacroTest::test_can_download_a_collection_with_headers_as_excel":0.062,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportAsMacroTest::test_can_import_directly_into_a_model_with_mapping":0.032,"Maatwebsite\\Excel\\Tests\\Mixins\\ImportMacroTest::test_can_import_directly_into_a_model":0.035,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::test_can_store_a_collection_as_excel":0.004,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::test_can_store_a_collection_as_excel_on_non_default_disk":0.012,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::test_can_store_a_collection_with_headings_as_excel":0.006,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreCollectionTest::test_can_store_a_model_collection_with_headings_as_excel":0.008,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::test_can_download_a_query_as_excel":0.061,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::test_can_download_a_query_as_excel_on_different_disk":0.059,"Maatwebsite\\Excel\\Tests\\Mixins\\StoreQueryMacroTest::test_can_store_a_query_with_headers_as_excel":0.065,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_an_export":0.247,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_an_export_and_store_on_different_disk":0.227,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_export_with_remote_temp_disk":0.27,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_export_with_remote_temp_disk_and_prefix":0.233,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_implicitly_queue_an_export":0.237,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_export_with_mapping_on_eloquent_models":0.017,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_catch_failures":0.008,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_catch_failures_on_queue_export_job":0.003,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_set_locale_on_queue_export_job":0.016,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::test_can_queue_export_not_flushing_the_cache":0.294,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_cannot_queue_import_that_does_not_implement_should_queue":0.046,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_queue_an_import":2.07,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_queue_an_import_with_batch_cache_and_file_store":3.877,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_queue_import_with_remote_temp_disk":2.219,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_keep_extension_for_temp_file_on_remote_disk":2.262,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_queue_import_with_remote_temp_disk_and_prefix":2.062,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_automatically_delete_temp_file_on_failure_when_using_remote_disk":0.108,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_cannot_automatically_delete_temp_file_on_failure_when_using_local_disk":0.106,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_force_remote_download_and_deletion_for_each_chunk_on_queue":2.176,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_define_middleware_method_on_queued_import":0.067,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_define_retry_until_method_on_queued_import":0.064,"Maatwebsite\\Excel\\Tests\\QueuedImportTest::test_can_define_max_exceptions_property_on_queued_import":0.106,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::test_can_queue_an_export":0.205,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::test_can_queue_an_export_with_batch_cache_and_file_store":3.691,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::test_can_queue_an_export_with_mapping":0.051,"Maatwebsite\\Excel\\Tests\\QueuedQueryExportTest::test_can_queue_scout_export":0.372,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::test_can_queue_an_export":0.138,"Maatwebsite\\Excel\\Tests\\QueuedViewExportTest::test_can_export_multiple_sheets_from_view":0.266,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::test_can_use_default_rights":0.001,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::test_can_use_dir_rights":0.001,"Maatwebsite\\Excel\\Tests\\TemporaryFileTest::test_can_use_file_rights":0.001,"Maatwebsite\\Excel\\Tests\\Concerns\\ImportableTest::test_cannot_import_a_non_existing_xlsx_file":0.031}} excel/CONTRIBUTING.md 0000644 00000000165 15060131672 0010100 0 ustar 00 # Contributing Find the contributing guide at: https://docs.laravel-excel.com/3.1/getting-started/contributing.html excel/SECURITY.md 0000644 00000000672 15060131672 0007443 0 ustar 00 # Security Policy **PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).** ## Supported Versions Version | Security Fixes Until --- | --- 3.1 | - 3.0 | 31-12-2018 2.1 | 15-5-2018 ## Reporting a Vulnerability If you discover a security vulnerability within Laravel Excel, please send an email to Patrick Brouwers at patrick@spartner.nl. All security vulnerabilities will be promptly addressed. excel/CHANGELOG.md 0000644 00000022243 15060131672 0007461 0 ustar 00 # Changelog All notable changes to this project will be documented in this file. Please view https://github.com/SpartnerNL/Laravel-Excel/releases for the most recent changelog ## [3.1.47] - 2023-02-16 - Support Laravel 10 ### Fixed - Fix Bug Multiple drawings change the behavior of the startCell (#3865). - Allow configuring read data only in chunks as well. ## [3.1.46] - 2023-01-27 - Support Laravel 10 ## [3.1.45] - 2023-01-02 ### Added - Add support for ignoring PHP auto_detect_line_endings INI directive ### Fixed - Fix the PSR simple cache dependency mess to maintain backwards compatability and support 3.0 of the interface. ## [3.1.44] - 2022-10-14 ### Fixed - Fix output of `WithFormatData` in combination with `SkipsEmptyRows` (#3760) ### Changed - Cast empty headings to indexed integer (#3646) - Adds `isEmptyWhen` to customize is row empty logic. (#3645) ### Fixed - Fix temporary local files not being cleaned up when setting force_resync_remote config to true (#3623) - Fix testing for multiple stored files by regex matching (#3631). - Allow `required_unless` rule (#3660) ## [3.1.40] - 2022-05-02 - Fix testing for multiple stored files by regex matching (#3631). ### Changed - Adds `WithDefaultStyles` concern to allow configuring the workbook default styles. - Adds `WithBackgroundColor` concern to allow configuring the workbook default background color. - Expose the ability to set custom response headers when exporting collections via Exportable ## [3.1.39] - 2022-04-23 ### Fixed - Fix PHP8.1 return type for Failure class (#3588) ## [3.1.38] - 2022-03-24 ### Changed - Adds concern `WithGroupedHeadingRow` to allow imported sheets to group the values of columns with the same header in an array ### Fixed - Fix for `prepareForValidation` callback not being called when using `SkipsEmptyRows` ## [3.1.37] - 2022-02-28 ### Fixed - Add `@mixin` docblock to all macroable classes to allow for IDE autocompletion of delegate classes - Fix issue with `Excel::toArray` not allowing nullable reader types for uploaded files ### Changed - Change default Csv Import to auto-detect the delimiter when not explicitly defined ## [3.1.36] - 2022-02-03 ### Fixed - Fix return type of `FromQuery::query()` ### Changed - Support Laravel 9 - Added a config setting to specify DB connection - Added a config setting to specify CSV output encoding - Added an ability to specify CSV ouput encoding through csvSettings ## [3.1.35] - 2022-01-04 ### Fixed - Removed cache flush for cell caching as this is already handled by PhpSpreadsheet - Fix `SkipsEmptyRows` support with the `WithColumnLimit` concern - Added range support to FormatColumn ## [3.1.34] - 2021-12-2 ### Changed - Change default local_path configuration - Fix queueImport function to be able to assert chained jobs - Skipped failure no longer persists in `ToCollection` and `ToArray`. - Fix missing InteractsWithQueue trait in AppendToSheet jobs - Add return types to `Row`'s `ArrayAccess` implementation ## [3.1.33] - 2021-08-12 ### Fixed - Make TransactionManager a singleton (#3270) - Fix Exportable disk options (#3296) - Delete temporary file after exception in import class (#3312) ## [3.1.32] - 2021-07-08 ### Added - Add assertExportedInRaw assertion (#3255) ### Fixed - Make commands detect model directory now (#3213) ## [3.1.31] - 2021-06-02 ### Added - Custom heading row formatter can use column index (#3166) - Added WithFormatData concern (#3154) ### Fixed - Create failures of rows than didn't exists but where requested in row validation - Fix Bug Formulas are not calculated when import implements WithCalculatedFormulas with SkipsEmptyRows #3127 - PhpSpreadsheet 1.18 support ## [3.1.30] - 2021-04-06 ### Added - Octane compatibility ## [3.1.29] - 2021-03-16 ### Fixed - Fix AfterImport Event not being called (#3085) ## [3.1.28] - 2021-03-10 ### Added - Added WithUpsertColumns concern (#3046) - Added ShouldQueueWithoutChain concern (#3072) ### Fixed - Limit Phpspreadsheet version to 1.16 until bugfix release - Fixed issue with not autosizing columns (#3055) - Fix selecting worksheets by name with chunk reading (#3052) ## [3.1.27] - 2021-02-22 ### Added - Added SkipsEmptyRows concern - Added HasReferencesToOtherSheets concern to allow import of calculated ### Changed - Bump minimum PhpSpreadsheet version - Progressbar NullOutput as fallback ## [3.1.26] - 2020-11-13 ### Added - PHP 8 support ## [3.1.25] - 2020-11-13 ### Added - Added an ability to prepare rows before appending rows to sheet. Just add `prepareRows` method for your export class if needed. - Added an ability to catch exceptions from `QueueExport` job. Just add `failed` method for your export class if needed. - Added an ability to set locale for queued export. Just implement `Illuminate\Contracts\Translation\HasLocalePreference` for your export. - Added `JsonSerializable` support in `Maatwebsite\Excel\Validators\Failure`. - Added `$maxExceptions` support in `Maatwebsite\Excel\Jobs\ReadChunk.php`. - Added support to upsert models by implementing the `WithUpserts` concern. ## [3.1.24] - 2020-10-28 ### Added - Added support for `prepareForValidation` on `WithValidation` concern - Added support for `withValidator` on `WithValidation` concern - Added `ArrayAccess` to `Row` ### Fixed - Corrected SkipsErrors doc block ## [3.1.23] - 2020-09-29 ### Added - Added `ignore_empty` setting to `config/excel.php` - Added `strict_null_comparison` setting to `config/excel.php` ## [3.1.22] - 2020-09-08 - Laravel 8 support - Lumen improvements ## [3.1.21] - 2020-08-06 ### Added - Added WithProperties concern - Added default spreadsheet properties config - Added WithColumnWidths concern - Added WithStyles concern. - Config setting to configure cell caching ### Changed - Sheet titles longer than 31 chars get trimmed. - Sheet titles with unsupported chars get cleaned. ### Fixed - Fixed issue with using ShouldAutosize in combination with FromView column widths. ## [3.1.20] - 2020-07-22 ### Added - Re-sycing remote temporary file - Remember row number - Remember chunk offset - WithColumnLimit concern - WithReadFilter concern - Publishing the stubs ### Changed - Interacting with queued jobs - Retry until and middleware on queued imports - Using WithValidation with FromCollection & FromArray - Read filters for WithLimit and HeadingRowImport - Bump of minimum version PhpSpreadsheet ### Fixed - Fixed test helper docblocks on the Excel facade. - Fix for importing with a start row beyond the highest row. - Fixed `BeforeSheet` and `AfterSheet` events receiving exportable instance instead of importable when calling on an Import. - Fix for value binders not working in queued exports. - Fix when using WithLimit concern when having less rows than the limit. - Fix AfterImport job being fired twice if not using queueing. - Raw() method now also available on Exportable. - Fix for breaking changes in PhpSpreadsheet with empty enclosures. [Unreleased]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.47...HEAD [3.1.47]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.46...3.1.47 [3.1.46]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.45...3.1.46 [3.1.45]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.44...3.1.45 [3.1.44]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.43...3.1.44 [3.1.43]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.42...3.1.43 [3.1.42]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.41...3.1.42 [3.1.41]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.40...3.1.41 [3.1.40]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.39...3.1.40 [3.1.39]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.38...3.1.39 [3.1.38]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.37...3.1.38 [3.1.37]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.36...3.1.37 [3.1.36]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.35...3.1.36 [3.1.35]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.34...3.1.35 [3.1.34]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.33...3.1.34 [3.1.33]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.32...3.1.33 [3.1.32]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.31...3.1.32 [3.1.31]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.30...3.1.31 [3.1.30]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.29...3.1.30 [3.1.29]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.28...3.1.29 [3.1.28]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.27...3.1.28 [3.1.27]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.26...3.1.27 [3.1.26]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.25...3.1.26 [3.1.25]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.24...3.1.25 [3.1.24]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.23...3.1.24 [3.1.23]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.22...3.1.23 [3.1.22]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.21...3.1.22 [3.1.21]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.20...3.1.21 [3.1.20]: https://github.com/Maatwebsite/Laravel-Excel/compare/3.1.19...3.1.20 _Older release notes can be found in Github releases._ excel/composer.json 0000644 00000002274 15060131672 0010374 0 ustar 00 { "name": "maatwebsite/excel", "description": "Supercharged Excel exports and imports in Laravel", "license": "MIT", "keywords": [ "laravel", "php", "phpspreadsheet", "phpexcel", "excel", "csv", "export", "import", "batch" ], "authors": [ { "name": "Patrick Brouwers", "email": "patrick@spartner.nl" } ], "require": { "ext-json": "*", "php": "^7.0||^8.0", "phpoffice/phpspreadsheet": "^1.18", "illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0", "psr/simple-cache": "^1.0||^2.0||^3.0", "composer/semver": "^3.3" }, "require-dev": { "orchestra/testbench": "^6.0||^7.0||^8.0||^9.0", "predis/predis": "^1.1", "laravel/scout": "^7.0||^8.0||^9.0||^10.0" }, "autoload": { "psr-4": { "Maatwebsite\\Excel\\": "src/" } }, "autoload-dev": { "psr-4": { "Maatwebsite\\Excel\\Tests\\": "tests/" } }, "extra": { "laravel": { "providers": [ "Maatwebsite\\Excel\\ExcelServiceProvider" ], "aliases": { "Excel": "Maatwebsite\\Excel\\Facades\\Excel" } } }, "minimum-stability": "dev", "prefer-stable": true } excel/LICENSE 0000644 00000002044 15060131672 0006652 0 ustar 00 MIT License Copyright (c) Spartner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. excel/config/excel.php 0000644 00000033615 15060131672 0010733 0 ustar 00 <?php use Maatwebsite\Excel\Excel; return [ 'exports' => [ /* |-------------------------------------------------------------------------- | Chunk size |-------------------------------------------------------------------------- | | When using FromQuery, the query is automatically chunked. | Here you can specify how big the chunk should be. | */ 'chunk_size' => 1000, /* |-------------------------------------------------------------------------- | Pre-calculate formulas during export |-------------------------------------------------------------------------- */ 'pre_calculate_formulas' => false, /* |-------------------------------------------------------------------------- | Enable strict null comparison |-------------------------------------------------------------------------- | | When enabling strict null comparison empty cells ('') will | be added to the sheet. */ 'strict_null_comparison' => false, /* |-------------------------------------------------------------------------- | CSV Settings |-------------------------------------------------------------------------- | | Configure e.g. delimiter, enclosure and line ending for CSV exports. | */ 'csv' => [ 'delimiter' => ',', 'enclosure' => '"', 'line_ending' => PHP_EOL, 'use_bom' => false, 'include_separator_line' => false, 'excel_compatibility' => false, 'output_encoding' => '', 'test_auto_detect' => true, ], /* |-------------------------------------------------------------------------- | Worksheet properties |-------------------------------------------------------------------------- | | Configure e.g. default title, creator, subject,... | */ 'properties' => [ 'creator' => '', 'lastModifiedBy' => '', 'title' => '', 'description' => '', 'subject' => '', 'keywords' => '', 'category' => '', 'manager' => '', 'company' => '', ], ], 'imports' => [ /* |-------------------------------------------------------------------------- | Read Only |-------------------------------------------------------------------------- | | When dealing with imports, you might only be interested in the | data that the sheet exists. By default we ignore all styles, | however if you want to do some logic based on style data | you can enable it by setting read_only to false. | */ 'read_only' => true, /* |-------------------------------------------------------------------------- | Ignore Empty |-------------------------------------------------------------------------- | | When dealing with imports, you might be interested in ignoring | rows that have null values or empty strings. By default rows | containing empty strings or empty values are not ignored but can be | ignored by enabling the setting ignore_empty to true. | */ 'ignore_empty' => false, /* |-------------------------------------------------------------------------- | Heading Row Formatter |-------------------------------------------------------------------------- | | Configure the heading row formatter. | Available options: none|slug|custom | */ 'heading_row' => [ 'formatter' => 'slug', ], /* |-------------------------------------------------------------------------- | CSV Settings |-------------------------------------------------------------------------- | | Configure e.g. delimiter, enclosure and line ending for CSV imports. | */ 'csv' => [ 'delimiter' => null, 'enclosure' => '"', 'escape_character' => '\\', 'contiguous' => false, 'input_encoding' => 'UTF-8', ], /* |-------------------------------------------------------------------------- | Worksheet properties |-------------------------------------------------------------------------- | | Configure e.g. default title, creator, subject,... | */ 'properties' => [ 'creator' => '', 'lastModifiedBy' => '', 'title' => '', 'description' => '', 'subject' => '', 'keywords' => '', 'category' => '', 'manager' => '', 'company' => '', ], /* |-------------------------------------------------------------------------- | Cell Middleware |-------------------------------------------------------------------------- | | Configure middleware that is executed on getting a cell value | */ 'cells' => [ 'middleware' => [ //\Maatwebsite\Excel\Middleware\TrimCellValue::class, //\Maatwebsite\Excel\Middleware\ConvertEmptyCellValuesToNull::class, ], ], ], /* |-------------------------------------------------------------------------- | Extension detector |-------------------------------------------------------------------------- | | Configure here which writer/reader type should be used when the package | needs to guess the correct type based on the extension alone. | */ 'extension_detector' => [ 'xlsx' => Excel::XLSX, 'xlsm' => Excel::XLSX, 'xltx' => Excel::XLSX, 'xltm' => Excel::XLSX, 'xls' => Excel::XLS, 'xlt' => Excel::XLS, 'ods' => Excel::ODS, 'ots' => Excel::ODS, 'slk' => Excel::SLK, 'xml' => Excel::XML, 'gnumeric' => Excel::GNUMERIC, 'htm' => Excel::HTML, 'html' => Excel::HTML, 'csv' => Excel::CSV, 'tsv' => Excel::TSV, /* |-------------------------------------------------------------------------- | PDF Extension |-------------------------------------------------------------------------- | | Configure here which Pdf driver should be used by default. | Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF | */ 'pdf' => Excel::DOMPDF, ], /* |-------------------------------------------------------------------------- | Value Binder |-------------------------------------------------------------------------- | | PhpSpreadsheet offers a way to hook into the process of a value being | written to a cell. In there some assumptions are made on how the | value should be formatted. If you want to change those defaults, | you can implement your own default value binder. | | Possible value binders: | | [x] Maatwebsite\Excel\DefaultValueBinder::class | [x] PhpOffice\PhpSpreadsheet\Cell\StringValueBinder::class | [x] PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder::class | */ 'value_binder' => [ 'default' => Maatwebsite\Excel\DefaultValueBinder::class, ], 'cache' => [ /* |-------------------------------------------------------------------------- | Default cell caching driver |-------------------------------------------------------------------------- | | By default PhpSpreadsheet keeps all cell values in memory, however when | dealing with large files, this might result into memory issues. If you | want to mitigate that, you can configure a cell caching driver here. | When using the illuminate driver, it will store each value in the | cache store. This can slow down the process, because it needs to | store each value. You can use the "batch" store if you want to | only persist to the store when the memory limit is reached. | | Drivers: memory|illuminate|batch | */ 'driver' => 'memory', /* |-------------------------------------------------------------------------- | Batch memory caching |-------------------------------------------------------------------------- | | When dealing with the "batch" caching driver, it will only | persist to the store when the memory limit is reached. | Here you can tweak the memory limit to your liking. | */ 'batch' => [ 'memory_limit' => 60000, ], /* |-------------------------------------------------------------------------- | Illuminate cache |-------------------------------------------------------------------------- | | When using the "illuminate" caching driver, it will automatically use | your default cache store. However if you prefer to have the cell | cache on a separate store, you can configure the store name here. | You can use any store defined in your cache config. When leaving | at "null" it will use the default store. | */ 'illuminate' => [ 'store' => null, ], /* |-------------------------------------------------------------------------- | Cache Time-to-live (TTL) |-------------------------------------------------------------------------- | | The TTL of items written to cache. If you want to keep the items cached | indefinitely, set this to null. Otherwise, set a number of seconds, | a \DateInterval, or a callable. | | Allowable types: callable|\DateInterval|int|null | */ 'default_ttl' => 10800, ], /* |-------------------------------------------------------------------------- | Transaction Handler |-------------------------------------------------------------------------- | | By default the import is wrapped in a transaction. This is useful | for when an import may fail and you want to retry it. With the | transactions, the previous import gets rolled-back. | | You can disable the transaction handler by setting this to null. | Or you can choose a custom made transaction handler here. | | Supported handlers: null|db | */ 'transactions' => [ 'handler' => 'db', 'db' => [ 'connection' => null, ], ], 'temporary_files' => [ /* |-------------------------------------------------------------------------- | Local Temporary Path |-------------------------------------------------------------------------- | | When exporting and importing files, we use a temporary file, before | storing reading or downloading. Here you can customize that path. | permissions is an array with the permission flags for the directory (dir) | and the create file (file). | */ 'local_path' => storage_path('framework/cache/laravel-excel'), /* |-------------------------------------------------------------------------- | Local Temporary Path Permissions |-------------------------------------------------------------------------- | | Permissions is an array with the permission flags for the directory (dir) | and the create file (file). | If omitted the default permissions of the filesystem will be used. | */ 'local_permissions' => [ // 'dir' => 0755, // 'file' => 0644, ], /* |-------------------------------------------------------------------------- | Remote Temporary Disk |-------------------------------------------------------------------------- | | When dealing with a multi server setup with queues in which you | cannot rely on having a shared local temporary path, you might | want to store the temporary file on a shared disk. During the | queue executing, we'll retrieve the temporary file from that | location instead. When left to null, it will always use | the local path. This setting only has effect when using | in conjunction with queued imports and exports. | */ 'remote_disk' => null, 'remote_prefix' => null, /* |-------------------------------------------------------------------------- | Force Resync |-------------------------------------------------------------------------- | | When dealing with a multi server setup as above, it's possible | for the clean up that occurs after entire queue has been run to only | cleanup the server that the last AfterImportJob runs on. The rest of the server | would still have the local temporary file stored on it. In this case your | local storage limits can be exceeded and future imports won't be processed. | To mitigate this you can set this config value to be true, so that after every | queued chunk is processed the local temporary file is deleted on the server that | processed it. | */ 'force_resync_remote' => null, ], ]; excel/.styleci.yml 0000644 00000000435 15060131672 0010124 0 ustar 00 preset: laravel risky: false enabled: - align_double_arrow - align_equals - concat_with_spaces - ordered_class_elements disabled: - concat_without_spaces - not_operator_with_successor_space - unalign_equals finder: not-name: - "*.md" not-path: - ".github"