JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrPKyZޠ excel/CODE_OF_CONDUCT.mdnu[# 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/ PKyZvuuexcel/composer.jsonnu[{ "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", "psr/simple-cache": "^1.0|^2.0|^3.0", "composer/semver": "^3.3" }, "require-dev": { "orchestra/testbench": "^6.0|^7.0|^8.0", "predis/predis": "^1.1" }, "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 } PKyZHexcel/SECURITY.mdnu[# 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. PKyZ!y"excel/src/ExcelServiceProvider.phpnu[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 DownloadCollection); Collection::mixin(new StoreCollection); $this->commands([ ExportMakeCommand::class, ImportMakeCommand::class, ]); } /** * @return string */ protected function getConfigFile(): string { return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'excel.php'; } } PKyZKX==excel/src/QueuedWriter.phpnu[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 */ private function exportCollection( FromCollection $export, TemporaryFile $temporaryFile, string $writerType, int $sheetIndex ): Collection { 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(); $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 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; } } PKyZEF((1excel/src/Exceptions/NoFilenameGivenException.phpnu[Ye1excel/src/Exceptions/NoFilePathGivenException.phpnu[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(); } } PKyZUmvv.excel/src/Exceptions/LaravelExcelException.phpnu[ 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()); } }); } } PKyZNG X--&excel/src/Helpers/FileTypeDetector.phpnu[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; } } PKyZ@wxx!excel/src/Helpers/ArrayHelper.phpnu[errors[] = $e; } /** * @return Throwable[]|Collection */ public function errors(): Collection { return new Collection($this->errors); } } PKyZw ;KK%excel/src/Concerns/SkipsEmptyRows.phpnu[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; } PKyZ$ii,excel/src/Concerns/WithGroupedHeadingRow.phpnu[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); } } PKyZyrxx'excel/src/Concerns/WithColumnWidths.phpnu[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); } } PKyZn;%excel/src/Concerns/FromCollection.phpnu[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; } PKyZ+--$excel/src/Concerns/SkipsFailures.phpnu[failures = array_merge($this->failures, $failures); } /** * @return Failure[]|Collection */ public function failures(): Collection { return new Collection($this->failures); } } PKyZ@ؿ'excel/src/Concerns/WithChunkReading.phpnu[rowNumber = $rowNumber; } /** * @return int|null */ public function getRowNumber() { return $this->rowNumber; } } PKyZЇ¾!excel/src/Concerns/WithCharts.phpnu[ '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; } } PKyZE excel/src/Concerns/OnEachRow.phpnu[chunkOffset = $chunkOffset; } /** * @return int|null */ public function getChunkOffset() { return $this->chunkOffset; } } PKyZBexcel/src/Excel.phpnu[writer = $writer; $this->reader = $reader; $this->filesystem = $filesystem; $this->queuedWriter = $queuedWriter; } /** * {@inheritdoc} */ public function download($export, string $fileName, string $writerType = null, array $headers = []) { return response()->download( $this->export($export, $fileName, $writerType)->getLocalPath(), $fileName, $headers )->deleteFileAfterSend(true); } /** * {@inheritdoc} */ public function store($export, string $filePath, string $diskName = null, string $writerType = null, $diskOptions = []) { if ($export instanceof ShouldQueue) { return $this->queue($export, $filePath, $diskName, $writerType, $diskOptions); } $temporaryFile = $this->export($export, $filePath, $writerType); $exported = $this->filesystem->disk($diskName, $diskOptions)->copy( $temporaryFile, $filePath ); $temporaryFile->delete(); return $exported; } /** * {@inheritdoc} */ public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { $writerType = FileTypeDetector::detectStrict($filePath, $writerType); return $this->queuedWriter->store( $export, $filePath, $disk, $writerType, $diskOptions ); } /** * {@inheritdoc} */ public function raw($export, string $writerType) { $temporaryFile = $this->writer->export($export, $writerType); $contents = $temporaryFile->contents(); $temporaryFile->delete(); return $contents; } /** * {@inheritdoc} */ public function import($import, $filePath, string $disk = null, string $readerType = null) { $readerType = FileTypeDetector::detect($filePath, $readerType); $response = $this->reader->read($import, $filePath, $readerType, $disk); if ($response instanceof PendingDispatch) { return $response; } return $this; } /** * {@inheritdoc} */ public function toArray($import, $filePath, string $disk = null, string $readerType = null): array { $readerType = FileTypeDetector::detect($filePath, $readerType); return $this->reader->toArray($import, $filePath, $readerType, $disk); } /** * {@inheritdoc} */ public function toCollection($import, $filePath, string $disk = null, string $readerType = null): Collection { $readerType = FileTypeDetector::detect($filePath, $readerType); return $this->reader->toCollection($import, $filePath, $readerType, $disk); } /** * {@inheritdoc} */ public function queueImport(ShouldQueue $import, $filePath, string $disk = null, string $readerType = null) { return $this->import($import, $filePath, $disk, $readerType); } /** * @param object $export * @param string|null $fileName * @param string $writerType * @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); } } PKyZDf(excel/src/Files/TemporaryFileFactory.phpnu[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) && !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 : ''); } } PKyZexcel/src/Files/Filesystem.phpnu[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 ); } } PKyZ{W!excel/src/Files/TemporaryFile.phpnu[getRealPath(), 'rb'); } elseif ($disk === null && realpath($filePath) !== false) { $readStream = fopen($filePath, 'rb'); } else { $readStream = app('filesystem')->disk($disk)->readStream($filePath); } $this->put($readStream); if (is_resource($readStream)) { fclose($readStream); } return $this->sync(); } } PKyZf&excel/src/Files/LocalTemporaryFile.phpnu[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); } } PKyZVexcel/src/Files/Disk.phpnu[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); } } PKyZ> 'excel/src/Files/RemoteTemporaryFile.phpnu[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()) { touch($this->localTemporaryFile->getLocalPath()); } $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); } } PKyZ%excel/src/HeadingRowImport.phpnu[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); } } PKyZ!hhexcel/src/MappedReader.phpnu[mapping() as $name => $coordinate) { $cell = Cell::make($worksheet, $coordinate); $mapped[$name] = $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); } } } PKyZ>$excel/src/Jobs/ExtendedQueueable.phpnu[each(function ($job) { $serialized = method_exists($this, 'serializeJob') ? $this->serializeJob($job) : serialize($job); $this->chained[] = $serialized; }); return $this; } } PKyZ~hр$excel/src/Jobs/AppendDataToSheet.phpnu[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); }); } } PKyZO=$excel/src/Jobs/StoreQueuedExport.phpnu[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(); } } PKyZ8excel/src/Jobs/ReadChunk.phpnu[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(); } } PKyZb %excel/src/Jobs/AppendQueryToSheet.phpnu[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) { $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); }); } } PKyZ3excel/src/Jobs/QueueImport.phpnu[timeout = $import->timeout ?? null; $this->tries = $import->tries ?? null; } } public function handle() { // } } PKyZ !excel/src/Jobs/AfterImportJob.phpnu[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); } } } } PKyZPaexcel/src/Jobs/QueueExport.phpnu[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(); } // 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); } } } PKyZ ]Ŏexcel/src/Jobs/CloseSheet.phpnu[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 ); } } PKyZY%% excel/src/Jobs/ProxyFailures.phpnu[sheetExport, 'failed')) { $this->sheetExport->failed($e); } } } PKyZӗ()excel/src/Jobs/Middleware/LocalizeJob.phpnu[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); }); } } PKyZEE$excel/src/Jobs/AppendViewToSheet.phpnu[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); }); } } PKyZ[== excel/src/DefaultValueBinder.phpnu[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 $value; } } PKyZKRaEEexcel/src/Events/AfterBatch.phpnu[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; } } PKyZ)znnexcel/src/Events/AfterSheet.phpnu[sheet = $sheet; parent::__construct($exportable); } /** * @return Sheet */ public function getSheet(): Sheet { return $this->sheet; } /** * @return mixed */ public function getDelegate() { return $this->sheet; } } PKyZo( }}!excel/src/Events/BeforeImport.phpnu[reader = $reader; parent::__construct($importable); } /** * @return Reader */ public function getReader(): Reader { return $this->reader; } /** * @return mixed */ public function getDelegate() { return $this->reader; } } PKyZg _;!excel/src/Events/ImportFailed.phpnu[e = $e; } /** * @return Throwable */ public function getException(): Throwable { return $this->e; } } PKyZM|| excel/src/Events/AfterImport.phpnu[reader = $reader; parent::__construct($importable); } /** * @return Reader */ public function getReader(): Reader { return $this->reader; } /** * @return mixed */ public function getDelegate() { return $this->reader; } } PKyZv|}}!excel/src/Events/BeforeExport.phpnu[writer = $writer; parent::__construct($exportable); } /** * @return Writer */ public function getWriter(): Writer { return $this->writer; } /** * @return mixed */ public function getDelegate() { return $this->writer; } } PKyZSZ'excel/src/Events/AfterChunk.phpnu[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; } } PKyZoG=pp excel/src/Events/BeforeSheet.phpnu[sheet = $sheet; parent::__construct($exportable); } /** * @return Sheet */ public function getSheet(): Sheet { return $this->sheet; } /** * @return mixed */ public function getDelegate() { return $this->sheet; } } PKyZ+è"excel/src/Events/BeforeWriting.phpnu[writer = $writer; parent::__construct($exportable); } /** * @return Writer */ public function getWriter(): Writer { return $this->writer; } /** * @return mixed */ public function getDelegate() { return $this->writer; } } PKyZ}excel/src/Events/Event.phpnu[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; } } PKyZt/*7*7excel/src/Reader.phpnu[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(); } } PKyZe )excel/src/Imports/HeadingRowExtractor.phpnu[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; } } PKyZ 9ܸ44"excel/src/Imports/EndRowFinder.phpnu[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; } } PKyZ>Zw"excel/src/Imports/ModelManager.phpnu[validator = $validator; } /** * @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; } $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); } } PKyZ= = )excel/src/Imports/HeadingRowFormatter.phpnu[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; } } PKyZ288#excel/src/Imports/ModelImporter.phpnu[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)); } } PKyZ{kjexcel/src/ChunkReader.phpnu[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]); } } PKyZexcel/src/Fakes/fake_filenu[PKyZ''excel/src/Fakes/ExcelFake.phpnu[downloads[$fileName] = $export; return new BinaryFileResponse(__DIR__ . '/fake_file'); } /** * {@inheritdoc} */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { if ($export instanceof ShouldQueue) { return $this->queue($export, $filePath, $disk, $writerType); } $this->stored[$disk ?? '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; } } PKyZYu1excel/src/Transactions/NullTransactionHandler.phpnu[connection = $connection; } /** * @param callable $callback * @return mixed * * @throws \Throwable */ public function __invoke(callable $callback) { return $this->connection->transaction($callback); } } PKyZ_]H'excel/src/Mixins/DownloadCollection.phpnu[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); }; } } PKyZ1'$excel/src/Mixins/StoreCollection.phpnu[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); }; } } PKyZ2??excel/src/SettingsProvider.phpnu[cache = $cache; } /** * Provide PhpSpreadsheet settings. */ public function provide() { $this->configureCellCaching(); } protected function configureCellCaching() { Settings::setCache( $this->cache->driver() ); } } PKyZbn05 5 %excel/src/Factories/WriterFactory.phpnu[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; } } PKyZ/h %excel/src/Factories/ReaderFactory.phpnu[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); } } } PKyZ+MMexcel/src/HasEventBus.phpnu[ $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); } } PKyZ$mǪexcel/src/Importer.phpnu[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) { $sheetExport->query()->chunk($this->getChunkSize($sheetExport), function ($chunk) use ($sheetExport) { $this->appendRows($chunk, $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) { $this->appendRows($sheetExport->iterator(), $sheetExport); } /** * @param FromGenerator $sheetExport */ public function fromGenerator(FromGenerator $sheetExport) { $this->appendRows($sheetExport->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 = (new Collection($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) ); })->toArray(); $this->append( $rows, $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); }; } } PKyZ 8,ZZ#excel/src/Console/WithModelStub.phpnu[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; } } PKyZu2'excel/src/Console/ExportMakeCommand.phpnu[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.'], ]; } } PKyZV"uu'excel/src/Console/ImportMakeCommand.phpnu[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.'], ]; } } PKyZ9bb)excel/src/Console/stubs/import.model.stubnu[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 ); $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; } } } } PKyZ N N excel/src/Facades/Excel.phpnu[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; } } PKyZff,excel/src/Validators/ValidationException.phpnu[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; } } PKyZ@H66 excel/src/Validators/Failure.phpnu[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(), ]; } } PKyZ)<  excel/src/Cache/MemoryCache.phpnu[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; $this->clear(); return $memory; } } PKyZ )excel/src/Cache/MemoryCacheDeprecated.phpnu[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; $this->clear(); return $memory; } } PKyZ<\g g excel/src/Cache/BatchCache.phpnu[cache = $cache; $this->memory = $memory; } 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 { $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 { $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); } } PKyZj (excel/src/Cache/BatchCacheDeprecated.phpnu[cache = $cache; $this->memory = $memory; } 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) { $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) { $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); } } PKyZD excel/src/Cache/CacheManager.phpnu[createIlluminateDriver(), $this->createMemoryDriver() ); } return new BatchCache( $this->createIlluminateDriver(), $this->createMemoryDriver() ); } /** * @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; } } PKyZ3:b}}excel/src/Row.phpnu[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; } } PKyZiam excel/src/DelegatedMacroable.phpnu[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(); } PKyZ !excel/src/Filters/LimitFilter.phpnu[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; } } PKyZ-j--%excel/src/Filters/ChunkReadFilter.phpnu[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)); } } PKyZexcel/README.mdnu[

Laravel Excel logo


Supercharged Excel exports and imports

A simple, but elegant Laravel wrapper around PhpSpreadsheet exports and imports.

Quickstart · Documentation · Video Course · Nova · Blog · Contributing · Support

Github Actions StyleCI Latest Stable Version Total Downloads License

## ✨ Features - **Easily export collections to Excel.** Supercharge your Laravel collections and export them directly to an Excel or CSV document. Exporting has never been so easy. - **Supercharged exports.** Export queries with automatic chunking for better performance. You provide us the query, we handle the performance. Exporting even larger datasets? No worries, Laravel Excel has your back. You can queue your exports so all of this happens in the background. - **Supercharged imports.** Import workbooks and worksheets to Eloquent models with chunk reading and batch inserts! Have large files? You can queue every chunk of a file! Your entire import will happen in the background. - **Export Blade views.** Want to have a custom layout in your spreadsheet? Use a HTML table in a Blade view and export that to Excel. ![banner](https://user-images.githubusercontent.com/7728097/57463977-2263fc80-727c-11e9-833d-669d816fb7fb.jpg)
## 🎓 Learning Laravel Excel You can find the full documentation of Laravel Excel [on the website](https://docs.laravel-excel.com). We welcome suggestions for improving our docs. The documentation repository can be found at [https://github.com/SpartnerNL/laravel-excel-docs](https://github.com/SpartnerNL/laravel-excel-docs). Some articles and tutorials can be found on our blog: https://medium.com/maatwebsite/laravel-excel/home ## :mailbox_with_mail: License & Postcardware ![1_5nblgs68uarg0wxxejozdq](https://user-images.githubusercontent.com/7728097/53638144-9e5f1a00-3c25-11e9-9f4a-fc71c9d94562.jpg) Laravel Excel is created with love and care by Spartner (formerly known as Maatwebsite) to give back to the Laravel community. It is completely free (MIT license) to use, however the package is licensed as Postcardware. This means that if it makes it to your production environment, we would very much appreciate receiving a postcard from your hometown. **Spartner** Markt 2 6231 LS Meerssen The Netherlands. More about the license can be found at: [https://docs.laravel-excel.com/3.1/getting-started/license.html](https://docs.laravel-excel.com/3.1/getting-started/license.html) ## Created by Spartner (formerly Maatwebsite) We are a strategic development partner, creating web-based custom built software from Laravel. In need of a digital solution for your challenge? Give us a call. https://spartner.software info@spartner.nl +31 (0) 10 - 7449312 ## :wrench: Supported Versions Versions will be supported for a limited amount of time. | Version | Laravel Version | Php Version | Support | |---- |----|----|----| | 2.1 | <=5.6 | <=7.0 | Unsupported since 15-5-2018 | | 3.0 | ^5.5 | ^7.0 | Unsupported since 31-12-2018 | | 3.1 | >=5.8 \| <=10.x | ^7.2 \| ^8.0 | New features | PKyZ2be00excel/config/excel.phpnu[ [ /* |-------------------------------------------------------------------------- | 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' => '', ], ], /* |-------------------------------------------------------------------------- | 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, ], ], /* |-------------------------------------------------------------------------- | 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. | */ 'local_path' => storage_path('framework/cache/laravel-excel'), /* |-------------------------------------------------------------------------- | 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, ], ]; PKyZ7excel/.styleci.ymlnu[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"PKyZ!excel/.phpunit.cache/test-resultsnu[{"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},"times":{"Maatwebsite\\Excel\\Tests\\QueuedImportTest::can_queue_an_import_with_batch_cache":2.346,"Maatwebsite\\Excel\\Tests\\QueuedExportTest::can_queue_an_export":0.308,"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}}PKyZ y($$ excel/LICENSEnu[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. PKyZb3uuexcel/CONTRIBUTING.mdnu[# Contributing Find the contributing guide at: https://docs.laravel-excel.com/3.1/getting-started/contributing.html PKyZ$$excel/CHANGELOG.mdnu[# 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._ PKyZޠ excel/CODE_OF_CONDUCT.mdnu[PKyZvuu excel/composer.jsonnu[PKyZHexcel/SECURITY.mdnu[PKyZ!y"excel/src/ExcelServiceProvider.phpnu[PKyZKX==#excel/src/QueuedWriter.phpnu[PKyZEF((1C<excel/src/Exceptions/NoFilenameGivenException.phpnu[PKyZ>Ye1>excel/src/Exceptions/NoFilePathGivenException.phpnu[PKyZ.1Bexcel/src/Exceptions/ConcernConflictException.phpnu[PKyZPbFPP0Dexcel/src/Exceptions/NoTypeDetectedException.phpnu[PKyZ|,^Gexcel/src/Exceptions/RowSkippedException.phpnu[PKyZUmvv.Jexcel/src/Exceptions/LaravelExcelException.phpnu[PKyZꢕ/qKexcel/src/Exceptions/SheetNotFoundException.phpnu[PKyZZm0Nexcel/src/Exceptions/UnreadableFileException.phpnu[PKyZ nee%Pexcel/src/RegistersCustomConcerns.phpnu[PKyZNG X--&Uexcel/src/Helpers/FileTypeDetector.phpnu[PKyZ@wxx!([excel/src/Helpers/ArrayHelper.phpnu[PKyZ& ]excel/src/Helpers/CellHelper.phpnu[PKyZ]#`_excel/src/Concerns/SkipsOnError.phpnu[PKyZKK%d`excel/src/Concerns/WithHeadingRow.phpnu[PKyZb}n*aexcel/src/Concerns/WithCustomStartCell.phpnu[PKyZQ"aexcel/src/Concerns/WithUpserts.phpnu[PKyZ,bexcel/src/Concerns/WithCustomCsvSettings.phpnu[PKyZE=z*cexcel/src/Concerns/WithBackgroundColor.phpnu[PKyZ@-Wr#eexcel/src/Concerns/WithDrawings.phpnu[PKyZ2G';fexcel/src/Concerns/WithBatchInserts.phpnu[PKyZdu== (gexcel/src/Concerns/FromQuery.phpnu[PKyZ҂(hexcel/src/Concerns/WithDefaultStyles.phpnu[PKyZJC#iexcel/src/Concerns/WithStartRow.phpnu[PKyZ?%jexcel/src/Concerns/SkipsOnFailure.phpnu[PKyZ)lexcel/src/Concerns/SkipsUnknownSheets.phpnu[PKyZ9KK%mexcel/src/Concerns/WithFormatData.phpnu[PKyZ"mexcel/src/Concerns/SkipsErrors.phpnu[PKyZw ;KK%oexcel/src/Concerns/SkipsEmptyRows.phpnu[PKyZi,wpexcel/src/Concerns/WithCustomValueBinder.phpnu[PKyZ*ԁ"kqexcel/src/Concerns/WithMapping.phpnu[PKyZUzj#krexcel/src/Concerns/ToCollection.phpnu[PKyZD !sexcel/src/Concerns/WithEvents.phpnu[PKyZ֍&texcel/src/Concerns/MapsCsvSettings.phpnu[PKyZ8Y:!g}excel/src/Concerns/WithStyles.phpnu[PKyZ=k7UU/`~excel/src/Concerns/WithPreCalculateFormulas.phpnu[PKyZо excel/src/Concerns/WithTitle.phpnu[PKyZexcel/src/Concerns/ToArray.phpnu[PKyZ$݀excel/src/Concerns/FromGenerator.phpnu[PKyZ*;#excel/src/Concerns/FromIterator.phpnu[PKyZ&݂excel/src/Concerns/WithProgressBar.phpnu[PKyZ K.excel/src/Concerns/ShouldQueueWithoutChain.phpnu[PKyZl+H+excel/src/Concerns/WithColumnFormatting.phpnu[PKyZ*excel/src/Concerns/WithCustomChunkSize.phpnu[PKyZBik*excel/src/Concerns/WithCustomQuerySize.phpnu[PKyZ$ii,excel/src/Concerns/WithGroupedHeadingRow.phpnu[PKyZ\cRN&excel/src/Concerns/WithMappedCells.phpnu[PKyZDAKK%excel/src/Concerns/ShouldAutoSize.phpnu[PKyZ;z]DD!8excel/src/Concerns/Importable.phpnu[PKyZyrxx'͛excel/src/Concerns/WithColumnWidths.phpnu[PKyZIexcel/src/Concerns/ToModel.phpnu[PKyZuuu&˝excel/src/Concerns/WithColumnLimit.phpnu[PKyZa®&excel/src/Concerns/FromView.phpnu[PKyZ !excel/src/Concerns/Exportable.phpnu[PKyZn;%excel/src/Concerns/FromCollection.phpnu[PKyZk0 excel/src/Concerns/WithLimit.phpnu[PKyZS,excel/src/Concerns/WithConditionalSheets.phpnu[PKyZ+--$excel/src/Concerns/SkipsFailures.phpnu[PKyZ@ؿ'sexcel/src/Concerns/WithChunkReading.phpnu[PKyZ %`excel/src/Concerns/WithReadFilter.phpnu[PKyZb×)excel/src/Concerns/RemembersRowNumber.phpnu[PKyZЇ¾!|excel/src/Concerns/WithCharts.phpnu[PKyZJWW1excel/src/Concerns/HasReferencesToOtherSheets.phpnu[PKyZNܕ#Bexcel/src/Concerns/WithHeadings.phpnu[PKyZk tt%*excel/src/Concerns/WithProperties.phpnu[PKyZFUU/excel/src/Concerns/WithStrictNullComparison.phpnu[PKyZū,H excel/src/Concerns/FromArray.phpnu[PKyZFי)excel/src/Concerns/WithMultipleSheets.phpnu[PKyZvSS-xexcel/src/Concerns/WithCalculatedFormulas.phpnu[PKyZZR((excel/src/Concerns/WithUpsertColumns.phpnu[PKyZ;%excel/src/Concerns/WithValidation.phpnu[PKyZ=$uu.excel/src/Concerns/RegistersEventListeners.phpnu[PKyZE excel/src/Concerns/OnEachRow.phpnu[PKyZ8@F+excel/src/Concerns/RemembersChunkOffset.phpnu[PKyZBexcel/src/Excel.phpnu[PKyZDf(excel/src/Files/TemporaryFileFactory.phpnu[PKyZ:excel/src/Files/Filesystem.phpnu[PKyZ{W!excel/src/Files/TemporaryFile.phpnu[PKyZf&9excel/src/Files/LocalTemporaryFile.phpnu[PKyZVyexcel/src/Files/Disk.phpnu[PKyZ> 'rexcel/src/Files/RemoteTemporaryFile.phpnu[PKyZ% excel/src/HeadingRowImport.phpnu[PKyZ!hh excel/src/MappedReader.phpnu[PKyZ>$Bexcel/src/Jobs/ExtendedQueueable.phpnu[PKyZ~hр$excel/src/Jobs/AppendDataToSheet.phpnu[PKyZO=$eexcel/src/Jobs/StoreQueuedExport.phpnu[PKyZ8#excel/src/Jobs/ReadChunk.phpnu[PKyZb %=excel/src/Jobs/AppendQueryToSheet.phpnu[PKyZ3!Hexcel/src/Jobs/QueueImport.phpnu[PKyZ !Jexcel/src/Jobs/AfterImportJob.phpnu[PKyZPaOTexcel/src/Jobs/QueueExport.phpnu[PKyZ ]Ŏk]excel/src/Jobs/CloseSheet.phpnu[PKyZY%% dexcel/src/Jobs/ProxyFailures.phpnu[PKyZӗ()eexcel/src/Jobs/Middleware/LocalizeJob.phpnu[PKyZEE$0jexcel/src/Jobs/AppendViewToSheet.phpnu[PKyZ[== rexcel/src/DefaultValueBinder.phpnu[PKyZN{Vuexcel/src/Cell.phpnu[PKyZKRaEEr~excel/src/Events/AfterBatch.phpnu[PKyZ)znnexcel/src/Events/AfterSheet.phpnu[PKyZo( }}!Åexcel/src/Events/BeforeImport.phpnu[PKyZg _;!excel/src/Events/ImportFailed.phpnu[PKyZM|| fexcel/src/Events/AfterImport.phpnu[PKyZv|}}!2excel/src/Events/BeforeExport.phpnu[PKyZSZ'excel/src/Events/AfterChunk.phpnu[PKyZoG=pp excel/src/Events/BeforeSheet.phpnu[PKyZ+è"excel/src/Events/BeforeWriting.phpnu[PKyZ}excel/src/Events/Event.phpnu[PKyZt/*7*7ěexcel/src/Reader.phpnu[PKyZe )2excel/src/Imports/HeadingRowExtractor.phpnu[PKyZ 9ܸ44"excel/src/Imports/EndRowFinder.phpnu[PKyZ>Zw"excel/src/Imports/ModelManager.phpnu[PKyZ= = )Hexcel/src/Imports/HeadingRowFormatter.phpnu[PKyZ288#excel/src/Imports/ModelImporter.phpnu[PKyZ{kjiexcel/src/ChunkReader.phpnu[PKyZ$excel/src/Fakes/fake_filenu[PKyZ'' %excel/src/Fakes/ExcelFake.phpnu[PKyZYu1!Mexcel/src/Transactions/NullTransactionHandler.phpnu[PKyZy-Nexcel/src/Transactions/TransactionManager.phpnu[PKyZ" -Qexcel/src/Transactions/TransactionHandler.phpnu[PKyZx~~/Rexcel/src/Transactions/DbTransactionHandler.phpnu[PKyZ_]H'Uexcel/src/Mixins/DownloadCollection.phpnu[PKyZ1'$y^excel/src/Mixins/StoreCollection.phpnu[PKyZ2??xfexcel/src/SettingsProvider.phpnu[PKyZbn05 5 %iexcel/src/Factories/WriterFactory.phpnu[PKyZ/h %texcel/src/Factories/ReaderFactory.phpnu[PKyZ+MMexcel/src/HasEventBus.phpnu[PKyZ$mǪexcel/src/Importer.phpnu[PKyZݗ&^^excel/src/Sheet.phpnu[PKyZ 8,ZZ#Jexcel/src/Console/WithModelStub.phpnu[PKyZu2'excel/src/Console/ExportMakeCommand.phpnu[PKyZV"uu'-excel/src/Console/ImportMakeCommand.phpnu[PKyZ9bb)excel/src/Console/stubs/import.model.stubnu[PKyZӿ)excel/src/Console/stubs/export.query.stubnu[PKyZȩ!!/excel/src/Console/stubs/export.query-model.stubnu[PKyZ*!**)wexcel/src/Console/stubs/export.model.stubnu[PKyZ7_h)excel/src/Console/stubs/export.plain.stubnu[PKyZU`!!.H excel/src/Console/stubs/import.collection.stubnu[PKyZ]e excel/src/Exporter.phpnu[PKyZƒ  excel/src/Writer.phpnu[PKyZ N N 0excel/src/Facades/Excel.phpnu[PKyZcJ%9excel/src/Validators/RowValidator.phpnu[PKyZff,Iexcel/src/Validators/ValidationException.phpnu[PKyZ@H66 Mexcel/src/Validators/Failure.phpnu[PKyZ)<  Uexcel/src/Cache/MemoryCache.phpnu[PKyZ )^excel/src/Cache/MemoryCacheDeprecated.phpnu[PKyZ<\g g Ihexcel/src/Cache/BatchCache.phpnu[PKyZj (uexcel/src/Cache/BatchCacheDeprecated.phpnu[PKyZD 9excel/src/Cache/CacheManager.phpnu[PKyZ3:b}}excel/src/Row.phpnu[PKyZiam Bexcel/src/DelegatedMacroable.phpnu[PKyZ !fexcel/src/Filters/LimitFilter.phpnu[PKyZ-j--%excel/src/Filters/ChunkReadFilter.phpnu[PKyZ&excel/README.mdnu[PKyZ2be00excel/config/excel.phpnu[PKyZ7Pexcel/.styleci.ymlnu[PKyZ!excel/.phpunit.cache/test-resultsnu[PKyZ y($$ excel/LICENSEnu[PKyZb3uuexcel/CONTRIBUTING.mdnu[PKyZ$$excel/CHANGELOG.mdnu[PK?