216 lines
6.3 KiB
PHP
216 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace Maatwebsite\Excel;
|
|
|
|
use Illuminate\Foundation\Bus\PendingDispatch;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\LazyCollection;
|
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
use Maatwebsite\Excel\Concerns\FromQuery;
|
|
use Maatwebsite\Excel\Concerns\FromView;
|
|
use Maatwebsite\Excel\Concerns\WithCustomChunkSize;
|
|
use Maatwebsite\Excel\Concerns\WithCustomQuerySize;
|
|
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
|
use Maatwebsite\Excel\Files\TemporaryFile;
|
|
use Maatwebsite\Excel\Files\TemporaryFileFactory;
|
|
use Maatwebsite\Excel\Jobs\AppendDataToSheet;
|
|
use Maatwebsite\Excel\Jobs\AppendQueryToSheet;
|
|
use Maatwebsite\Excel\Jobs\AppendViewToSheet;
|
|
use Maatwebsite\Excel\Jobs\CloseSheet;
|
|
use Maatwebsite\Excel\Jobs\QueueExport;
|
|
use Maatwebsite\Excel\Jobs\StoreQueuedExport;
|
|
use Traversable;
|
|
|
|
class QueuedWriter
|
|
{
|
|
/**
|
|
* @var Writer
|
|
*/
|
|
protected $writer;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $chunkSize;
|
|
|
|
/**
|
|
* @var TemporaryFileFactory
|
|
*/
|
|
protected $temporaryFileFactory;
|
|
|
|
/**
|
|
* @param Writer $writer
|
|
* @param TemporaryFileFactory $temporaryFileFactory
|
|
*/
|
|
public function __construct(Writer $writer, TemporaryFileFactory $temporaryFileFactory)
|
|
{
|
|
$this->writer = $writer;
|
|
$this->chunkSize = config('excel.exports.chunk_size', 1000);
|
|
$this->temporaryFileFactory = $temporaryFileFactory;
|
|
}
|
|
|
|
/**
|
|
* @param object $export
|
|
* @param string $filePath
|
|
* @param string $disk
|
|
* @param string|null $writerType
|
|
* @param array|string $diskOptions
|
|
*
|
|
* @return \Illuminate\Foundation\Bus\PendingDispatch
|
|
*/
|
|
public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
|
|
{
|
|
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
|
|
$temporaryFile = $this->temporaryFileFactory->make($extension);
|
|
|
|
$jobs = $this->buildExportJobs($export, $temporaryFile, $writerType);
|
|
|
|
$jobs->push(new StoreQueuedExport(
|
|
$temporaryFile,
|
|
$filePath,
|
|
$disk,
|
|
$diskOptions
|
|
));
|
|
|
|
return new PendingDispatch(
|
|
(new QueueExport($export, $temporaryFile, $writerType))->chain($jobs->toArray())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param object $export
|
|
* @param TemporaryFile $temporaryFile
|
|
* @param string $writerType
|
|
*
|
|
* @return Collection
|
|
*/
|
|
private function buildExportJobs($export, TemporaryFile $temporaryFile, string $writerType): Collection
|
|
{
|
|
$sheetExports = [$export];
|
|
if ($export instanceof WithMultipleSheets) {
|
|
$sheetExports = $export->sheets();
|
|
}
|
|
|
|
$jobs = new Collection;
|
|
foreach ($sheetExports as $sheetIndex => $sheetExport) {
|
|
if ($sheetExport instanceof FromCollection) {
|
|
$jobs = $jobs->merge($this->exportCollection($sheetExport, $temporaryFile, $writerType, $sheetIndex));
|
|
} elseif ($sheetExport instanceof FromQuery) {
|
|
$jobs = $jobs->merge($this->exportQuery($sheetExport, $temporaryFile, $writerType, $sheetIndex));
|
|
} elseif ($sheetExport instanceof FromView) {
|
|
$jobs = $jobs->merge($this->exportView($sheetExport, $temporaryFile, $writerType, $sheetIndex));
|
|
}
|
|
|
|
$jobs->push(new CloseSheet($sheetExport, $temporaryFile, $writerType, $sheetIndex));
|
|
}
|
|
|
|
return $jobs;
|
|
}
|
|
|
|
/**
|
|
* @param FromCollection $export
|
|
* @param TemporaryFile $temporaryFile
|
|
* @param string $writerType
|
|
* @param int $sheetIndex
|
|
*
|
|
* @return LazyCollection // @todo original: Collection
|
|
*/
|
|
private function exportCollection(
|
|
FromCollection $export,
|
|
TemporaryFile $temporaryFile,
|
|
string $writerType,
|
|
int $sheetIndex
|
|
): LazyCollection { // @todo original: 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;
|
|
}
|
|
}
|