44
55use Illuminate \Http \JsonResponse ;
66use Illuminate \Support \Collection ;
7+ use Rap2hpoutre \FastExcel \FastExcel ;
78use Yajra \DataTables \Contracts \DataTableButtons ;
89use Yajra \DataTables \Contracts \DataTableScope ;
910use Yajra \DataTables \Html \Column ;
11+ use Yajra \DataTables \QueryDataTable ;
1012use Yajra \DataTables \Transformers \DataArrayTransformer ;
1113
1214abstract 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