Skip to content

Commit bc9a145

Browse files
authored
Merge pull request #124 from yajra/fast-excel-export
[4.x] Add support for fast-excel when exporting to excel and csv.
2 parents d9bcd72 + 44462e3 commit bc9a145

File tree

3 files changed

+110
-13
lines changed

3 files changed

+110
-13
lines changed

composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
"mockery/mockery": "~1.0",
2626
"phpunit/phpunit": "~7.0"
2727
},
28+
"suggest": {
29+
"rap2hpoutre/fast-excel": "Faster exporting of dataTables using fast-excel package.",
30+
"barryvdh/laravel-snappy": "For exporting of dataTables to PDF."
31+
},
2832
"autoload": {
2933
"psr-4": {
3034
"Yajra\\DataTables\\": "src/"

src/Exports/DataTablesCollectionExport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Maatwebsite\Excel\Concerns\FromCollection;
88
use Maatwebsite\Excel\Concerns\WithHeadings;
99

10-
abstract class DataTablesCollectionExport implements FromCollection, WithHeadings
10+
abstract class DataTablesCollectionExport implements FromCollection, WithHeadings
1111
{
1212
use Exportable;
1313

src/Services/DataTable.php

Lines changed: 105 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
use Illuminate\Http\JsonResponse;
66
use Illuminate\Support\Collection;
7+
use Rap2hpoutre\FastExcel\FastExcel;
78
use Yajra\DataTables\Contracts\DataTableButtons;
89
use Yajra\DataTables\Contracts\DataTableScope;
910
use Yajra\DataTables\Html\Column;
11+
use Yajra\DataTables\QueryDataTable;
1012
use Yajra\DataTables\Transformers\DataArrayTransformer;
1113

1214
abstract class DataTable implements DataTableButtons
@@ -116,6 +118,23 @@ abstract class DataTable implements DataTableButtons
116118
*/
117119
protected $request;
118120

121+
/**
122+
* Flag to use fast-excel package for export.
123+
*
124+
* @var bool
125+
*/
126+
protected $fastExcel = false;
127+
128+
/**
129+
* Flag to enable/disable fast-excel callback.
130+
* Note: Disabling this flag can improve you export time.
131+
* Enabled by default to emulate the same output
132+
* with laravel-excel.
133+
*
134+
* @var bool
135+
*/
136+
protected $fastExcelCallback = true;
137+
119138
/**
120139
* Export class handler.
121140
*
@@ -393,9 +412,14 @@ public function response(callable $callback)
393412
*/
394413
public function excel()
395414
{
396-
$ext = '.' . strtolower($this->excelWriter);
415+
set_time_limit(3600);
416+
417+
$ext = '.' . strtolower($this->excelWriter);
418+
$callback = $this->fastExcel ?
419+
($this->fastExcelCallback ? $this->fastExcelCallback() : null)
420+
: $this->excelWriter;
397421

398-
return $this->buildExcelFile()->download($this->getFilename() . $ext, $this->excelWriter);
422+
return $this->buildExcelFile()->download($this->getFilename() . $ext, $callback);
399423
}
400424

401425
/**
@@ -405,17 +429,19 @@ public function excel()
405429
*/
406430
protected function buildExcelFile()
407431
{
408-
if ($this->exportClass != DataTablesExportHandler::class) {
409-
$collection = collect($this->getAjaxResponseData());
410-
} else {
411-
$collection = collect($this->getDataForExport());
432+
if ($this->fastExcel) {
433+
return $this->buildFastExcelFile();
412434
}
413435

414-
if (method_exists($collection, 'lazy')) {
415-
$collection->lazy();
436+
if ($this->exportClass != DataTablesExportHandler::class) {
437+
$collection = $this->getAjaxResponseData();
438+
439+
return new $this->exportClass($this->convertToLazyCollection($collection));
416440
}
417441

418-
return new $this->exportClass($collection);
442+
$collection = $this->getDataForExport();
443+
444+
return new $this->exportClass($this->convertToLazyCollection($collection));
419445
}
420446

421447
/**
@@ -468,7 +494,7 @@ protected function getDataForExport()
468494
*
469495
* @return array|string
470496
*/
471-
private function exportColumns()
497+
protected function exportColumns()
472498
{
473499
return is_array($this->exportColumns) ? $this->toColumnsCollection($this->exportColumns) : $this->getExportColumnsFromBuilder();
474500
}
@@ -504,9 +530,13 @@ private function toColumnsCollection(array $columns)
504530
*/
505531
public function csv()
506532
{
507-
$ext = '.' . strtolower($this->csvWriter);
533+
set_time_limit(3600);
534+
$ext = '.' . strtolower($this->csvWriter);
535+
$callback = $this->fastExcel ?
536+
($this->fastExcelCallback ? $this->fastExcelCallback() : null)
537+
: $this->csvWriter;
508538

509-
return $this->buildExcelFile()->download($this->getFilename() . $ext, $this->csvWriter);
539+
return $this->buildExcelFile()->download($this->getFilename() . $ext, $callback);
510540
}
511541

512542
/**
@@ -637,4 +667,67 @@ protected function getBuilderParameters()
637667
{
638668
return config('datatables-buttons.parameters');
639669
}
670+
671+
/**
672+
* @param \Illuminate\Support\|array $collection
673+
* @return \Illuminate\Support\Collection
674+
*/
675+
protected function convertToLazyCollection($collection)
676+
{
677+
if (is_array($collection)) {
678+
$collection = collect($collection);
679+
}
680+
681+
if (method_exists($collection, 'lazy')) {
682+
$collection->lazy();
683+
}
684+
685+
return $collection;
686+
}
687+
688+
/**
689+
* @return \Closure
690+
*/
691+
public function fastExcelCallback()
692+
{
693+
return function ($row) {
694+
$mapped = [];
695+
foreach ($this->exportColumns() as $column) {
696+
if ($column['exportable']) {
697+
$mapped[$column['title']] = $row[$column['name']];
698+
}
699+
}
700+
701+
return $mapped;
702+
};
703+
}
704+
705+
/**
706+
* @return \Rap2hpoutre\FastExcel\FastExcel
707+
*/
708+
protected function buildFastExcelFile()
709+
{
710+
$query = null;
711+
if (method_exists($this, 'query')) {
712+
$query = app()->call([$this, 'query']);
713+
$query = $this->applyScopes($query);
714+
}
715+
716+
/** @var \Yajra\DataTables\DataTableAbstract $dataTable */
717+
$dataTable = app()->call([$this, 'dataTable'], compact('query'));
718+
$dataTable->skipPaging();
719+
720+
if ($dataTable instanceof QueryDataTable) {
721+
function queryGenerator($dataTable)
722+
{
723+
foreach ($dataTable->getFilteredQuery()->cursor() as $row) {
724+
yield $row;
725+
}
726+
}
727+
728+
return new FastExcel(queryGenerator($dataTable));
729+
}
730+
731+
return new FastExcel($this->convertToLazyCollection($dataTable->toArray()['data']));
732+
}
640733
}

0 commit comments

Comments
 (0)