1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Nayjest\Grids\Components; |
4
|
|
|
|
5
|
|
|
use Event; |
6
|
|
|
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet; |
7
|
|
|
use Maatwebsite\Excel\Excel; |
8
|
|
|
use Maatwebsite\Excel\Writers\LaravelExcelWriter; |
9
|
|
|
use Nayjest\Grids\Components\Base\RenderableComponent; |
10
|
|
|
use Nayjest\Grids\Components\Base\RenderableRegistry; |
11
|
|
|
use Nayjest\Grids\DataProvider; |
12
|
|
|
use Nayjest\Grids\DataRow; |
13
|
|
|
use Nayjest\Grids\FieldConfig; |
14
|
|
|
use Nayjest\Grids\Grid; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class ExcelExport |
18
|
|
|
* |
19
|
|
|
* The component provides control for exporting data to excel. |
20
|
|
|
* |
21
|
|
|
* @author: Alexander Hofmeister |
22
|
|
|
* @package Nayjest\Grids\Components |
23
|
|
|
*/ |
24
|
|
|
class ExcelExport extends RenderableComponent |
25
|
|
|
{ |
26
|
|
|
const NAME = 'excel_export'; |
27
|
|
|
const INPUT_PARAM = 'xls'; |
28
|
|
|
const DEFAULT_ROWS_LIMIT = 5000; |
29
|
|
|
|
30
|
|
|
protected $template = '*.components.excel_export'; |
31
|
|
|
protected $name = ExcelExport::NAME; |
32
|
|
|
protected $render_section = RenderableRegistry::SECTION_END; |
33
|
|
|
protected $rows_limit = self::DEFAULT_ROWS_LIMIT; |
34
|
|
|
protected $extension = 'xls'; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
protected $output; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
protected $fileName; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var string |
48
|
|
|
*/ |
49
|
|
|
protected $sheetName; |
50
|
|
|
|
51
|
|
|
protected $ignored_columns = []; |
52
|
|
|
|
53
|
|
|
protected $is_hidden_columns_exported = false; |
54
|
|
|
|
55
|
|
|
protected $on_file_create; |
56
|
|
|
|
57
|
|
|
protected $on_sheet_create; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param Grid $grid |
61
|
|
|
* @return null|void |
62
|
|
|
*/ |
63
|
|
View Code Duplication |
public function initialize(Grid $grid) |
|
|
|
|
64
|
|
|
{ |
65
|
|
|
parent::initialize($grid); |
66
|
|
|
Event::listen(Grid::EVENT_PREPARE, function (Grid $grid) { |
67
|
|
|
if ($this->grid !== $grid) { |
68
|
|
|
return; |
69
|
|
|
} |
70
|
|
|
if ($grid->getInputProcessor()->getValue(static::INPUT_PARAM, false)) { |
71
|
|
|
$this->renderExcel(); |
72
|
|
|
} |
73
|
|
|
}); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Sets name of exported file. |
78
|
|
|
* |
79
|
|
|
* @param string $name |
80
|
|
|
* @return $this |
81
|
|
|
*/ |
82
|
|
|
public function setFileName($name) |
83
|
|
|
{ |
84
|
|
|
$this->fileName = $name; |
85
|
|
|
return $this; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Returns name of exported file. |
90
|
|
|
* |
91
|
|
|
* @return string |
92
|
|
|
*/ |
93
|
|
|
public function getFileName() |
94
|
|
|
{ |
95
|
|
|
return $this->fileName ?: $this->grid->getConfig()->getName(); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @param string $name |
100
|
|
|
* @return $this |
101
|
|
|
*/ |
102
|
|
|
public function setSheetName($name) |
103
|
|
|
{ |
104
|
|
|
$this->sheetName = $name; |
105
|
|
|
return $this; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
|
|
public function getSheetName() |
112
|
|
|
{ |
113
|
|
|
return $this->sheetName; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @param string $name |
118
|
|
|
* @return $this |
119
|
|
|
*/ |
120
|
|
|
public function setExtension($name) |
121
|
|
|
{ |
122
|
|
|
$this->extension = $name; |
123
|
|
|
return $this; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @return string |
128
|
|
|
*/ |
129
|
|
|
public function getExtension() |
130
|
|
|
{ |
131
|
|
|
return $this->extension; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @return int |
136
|
|
|
*/ |
137
|
|
|
public function getRowsLimit() |
138
|
|
|
{ |
139
|
|
|
return $this->rows_limit; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @param int $limit |
144
|
|
|
* |
145
|
|
|
* @return $this |
146
|
|
|
*/ |
147
|
|
|
public function setRowsLimit($limit) |
148
|
|
|
{ |
149
|
|
|
$this->rows_limit = $limit; |
150
|
|
|
return $this; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
protected function resetPagination(DataProvider $provider) |
154
|
|
|
{ |
155
|
|
|
$provider->getPaginationFactory()->setPageName('page_unused'); |
156
|
|
|
$provider->setPageSize($this->getRowsLimit()); |
157
|
|
|
$provider->setCurrentPage(1); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @param FieldConfig $column |
162
|
|
|
* @return bool |
163
|
|
|
*/ |
164
|
|
|
protected function isColumnExported(FieldConfig $column) |
165
|
|
|
{ |
166
|
|
|
return !in_array($column->getName(), $this->getIgnoredColumns()) |
167
|
|
|
&& ($this->isHiddenColumnsExported() || !$column->isHidden()); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @internal |
172
|
|
|
* @return array |
173
|
|
|
*/ |
174
|
|
|
public function getData() |
175
|
|
|
{ |
176
|
|
|
// Build array |
177
|
|
|
$exportData = []; |
178
|
|
|
/** @var $provider DataProvider */ |
179
|
|
|
$provider = $this->grid->getConfig()->getDataProvider(); |
180
|
|
|
|
181
|
|
|
$exportData[] = $this->getHeaderRow(); |
182
|
|
|
|
183
|
|
|
$this->resetPagination($provider); |
184
|
|
|
$provider->reset(); |
185
|
|
|
|
186
|
|
|
/** @var DataRow $row */ |
187
|
|
|
while ($row = $provider->getRow()) { |
188
|
|
|
$output = []; |
189
|
|
View Code Duplication |
foreach ($this->grid->getConfig()->getColumns() as $column) { |
|
|
|
|
190
|
|
|
if ($this->isColumnExported($column)) { |
191
|
|
|
$output[] = $this->escapeString($column->getValue($row)); |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
$exportData[] = $output; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return $exportData; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
protected function renderExcel() |
201
|
|
|
{ |
202
|
|
|
/** @var Excel $excel */ |
203
|
|
|
$excel = app('excel'); |
204
|
|
|
$excel |
205
|
|
|
->create($this->getFileName(), $this->getOnFileCreate()) |
206
|
|
|
->export($this->getExtension()); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
protected function escapeString($str) |
210
|
|
|
{ |
211
|
|
|
return str_replace('"', '\'', strip_tags(html_entity_decode($str))); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
protected function getHeaderRow() |
215
|
|
|
{ |
216
|
|
|
$output = []; |
217
|
|
View Code Duplication |
foreach ($this->grid->getConfig()->getColumns() as $column) { |
|
|
|
|
218
|
|
|
if ($this->isColumnExported($column)) { |
219
|
|
|
$output[] = $this->escapeString($column->getLabel()); |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
return $output; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @return string[] |
227
|
|
|
*/ |
228
|
|
|
public function getIgnoredColumns() |
229
|
|
|
{ |
230
|
|
|
return $this->ignored_columns; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param string[] $ignoredColumns |
235
|
|
|
* @return $this |
236
|
|
|
*/ |
237
|
|
|
public function setIgnoredColumns(array $ignoredColumns) |
238
|
|
|
{ |
239
|
|
|
$this->ignored_columns = $ignoredColumns; |
240
|
|
|
return $this; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @return boolean |
245
|
|
|
*/ |
246
|
|
|
public function isHiddenColumnsExported() |
247
|
|
|
{ |
248
|
|
|
return $this->is_hidden_columns_exported; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* @param bool $isHiddenColumnsExported |
253
|
|
|
* @return $this |
254
|
|
|
*/ |
255
|
|
|
public function setHiddenColumnsExported($isHiddenColumnsExported) |
256
|
|
|
{ |
257
|
|
|
$this->is_hidden_columns_exported = $isHiddenColumnsExported; |
258
|
|
|
return $this; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* @return mixed |
263
|
|
|
*/ |
264
|
|
|
public function getOnFileCreate() |
265
|
|
|
{ |
266
|
|
|
if ($this->on_file_create === null) { |
267
|
|
|
$this->on_file_create = function (LaravelExcelWriter $excel) { |
268
|
|
|
$excel->sheet($this->getSheetName(), $this->getOnSheetCreate()); |
269
|
|
|
}; |
270
|
|
|
} |
271
|
|
|
return $this->on_file_create; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param callable $onFileCreate |
276
|
|
|
* |
277
|
|
|
* @return $this |
278
|
|
|
*/ |
279
|
|
|
public function setOnFileCreate($onFileCreate) |
280
|
|
|
{ |
281
|
|
|
$this->on_file_create = $onFileCreate; |
282
|
|
|
return $this; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* @return callable |
287
|
|
|
*/ |
288
|
|
|
public function getOnSheetCreate() |
289
|
|
|
{ |
290
|
|
|
if ($this->on_sheet_create === null) { |
291
|
|
|
$this->on_sheet_create = function (LaravelExcelWorksheet $sheet) { |
292
|
|
|
$sheet->fromArray($this->getData(), null, 'A1', false, false); |
293
|
|
|
}; |
294
|
|
|
} |
295
|
|
|
return $this->on_sheet_create; |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* @param callable $onSheetCreate |
300
|
|
|
* |
301
|
|
|
* @return $this |
302
|
|
|
*/ |
303
|
|
|
public function setOnSheetCreate($onSheetCreate) |
304
|
|
|
{ |
305
|
|
|
$this->on_sheet_create = $onSheetCreate; |
306
|
|
|
return $this; |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.