1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @noinspection PhpClassConstantAccessedViaChildClassInspection |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
declare(strict_types=1); |
8
|
|
|
|
9
|
|
|
namespace Eclipxe\XlsxExporter\DBAL; |
10
|
|
|
|
11
|
|
|
use Eclipxe\XlsxExporter\CellTypes; |
12
|
|
|
use Eclipxe\XlsxExporter\Column; |
13
|
|
|
use Eclipxe\XlsxExporter\Columns; |
14
|
|
|
use Eclipxe\XlsxExporter\Style; |
15
|
|
|
use Eclipxe\XlsxExporter\Styles\Alignment; |
16
|
|
|
use Eclipxe\XlsxExporter\Styles\Format; |
17
|
|
|
use Eclipxe\XlsxExporter\WorkBook; |
18
|
|
|
use Eclipxe\XlsxExporter\WorkSheet; |
19
|
|
|
use EngineWorks\DBAL\CommonTypes; |
20
|
|
|
use EngineWorks\DBAL\DBAL; |
21
|
|
|
use EngineWorks\DBAL\Recordset; |
22
|
|
|
|
23
|
|
|
class WorkBookExporter |
24
|
|
|
{ |
25
|
|
|
private WorkBook $workbook; |
26
|
|
|
|
27
|
|
|
private ?Style $defaultHeaderStyle; |
28
|
|
|
|
29
|
1 |
|
public function __construct(Style $defaultStyle = null, Style $defaultHeaderStyle = null) |
30
|
|
|
{ |
31
|
1 |
|
$this->workbook = new WorkBook(null, $defaultStyle); |
32
|
1 |
|
$this->defaultHeaderStyle = $defaultHeaderStyle; |
33
|
|
|
} |
34
|
|
|
|
35
|
1 |
|
public function getWorkbook(): WorkBook |
36
|
|
|
{ |
37
|
1 |
|
return $this->workbook; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Attach a recordset with the specified sheet-name, headers and header style |
42
|
|
|
* |
43
|
|
|
* The headers array must contain a key value array using the field-name as key and two properties: |
44
|
|
|
* title & style, the title must be a string and the style a valid array to be used in Style::setFromArray method |
45
|
|
|
* |
46
|
|
|
* @param Recordset $recordset |
47
|
|
|
* @param string $sheetName |
48
|
|
|
* @param array<string, array{title?: string, style?: array<string, array<string, scalar>>}> $headers |
49
|
|
|
* @param Style|null $defaultHeaderStyle |
50
|
|
|
*/ |
51
|
1 |
|
public function attach(Recordset $recordset, string $sheetName, array $headers = [], Style $defaultHeaderStyle = null): void |
52
|
|
|
{ |
53
|
|
|
/** @var array<string, array{name: string, table: string, commontype: string}> $fields */ |
54
|
1 |
|
$fields = $recordset->getFields(); |
55
|
1 |
|
$this->workbook->getWorkSheets()->add( |
56
|
1 |
|
new WorkSheet( |
57
|
1 |
|
$sheetName, |
58
|
1 |
|
new RecordsetProvider($recordset), |
59
|
1 |
|
$this->createColumnsFromFields($fields, $headers), |
60
|
1 |
|
$defaultHeaderStyle ?? $this->defaultHeaderStyle |
61
|
1 |
|
) |
62
|
1 |
|
); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* This function takes an array (as exposed by recordset::getFields method) |
67
|
|
|
* and headers array to create a Columns object |
68
|
|
|
* |
69
|
|
|
* See attach method to write the headers array |
70
|
|
|
* |
71
|
|
|
* @param array<array{name: string, commontype: string}> $fields |
72
|
|
|
* @param array<string, array{title?: string, style?: array<string, array<string, scalar>>}> $headers |
73
|
|
|
*/ |
74
|
3 |
|
public static function createColumnsFromFields(array $fields, array $headers = []): Columns |
75
|
|
|
{ |
76
|
3 |
|
$useHeaders = ([] !== $headers); |
77
|
3 |
|
$columns = new Columns(); |
78
|
3 |
|
foreach ($fields as $field) { |
79
|
3 |
|
if ($useHeaders && ! array_key_exists($field['name'], $headers)) { |
80
|
1 |
|
continue; |
81
|
|
|
} |
82
|
3 |
|
$columns->add(new Column( |
83
|
3 |
|
$field['name'], |
84
|
3 |
|
$field['name'], |
85
|
3 |
|
self::getColumnTypeFromFieldType($field['commontype']), |
86
|
3 |
|
self::getColumnStyleFromFieldType($field['commontype']) |
87
|
3 |
|
)); |
88
|
|
|
} |
89
|
3 |
|
if ($useHeaders) { |
90
|
1 |
|
$sorted = new Columns(); |
91
|
1 |
|
foreach ($headers as $fieldname => $properties) { |
92
|
1 |
|
if (! $columns->existsById($fieldname)) { |
93
|
1 |
|
continue; |
94
|
|
|
} |
95
|
1 |
|
$column = $columns->getById($fieldname); |
96
|
|
|
// set title |
97
|
|
|
if ( |
98
|
1 |
|
array_key_exists('title', $properties) |
99
|
1 |
|
&& is_string($properties['title']) |
100
|
|
|
) { |
101
|
1 |
|
$column->setTitle($properties['title']); |
102
|
|
|
} |
103
|
|
|
// set style |
104
|
|
|
if ( |
105
|
1 |
|
array_key_exists('style', $properties) |
106
|
1 |
|
&& is_array($properties['style']) |
107
|
1 |
|
&& count($properties['style']) |
108
|
|
|
) { |
109
|
1 |
|
$column->getStyle()->setFromArray($properties['style']); |
110
|
|
|
} |
111
|
1 |
|
$sorted->add($column); |
112
|
|
|
} |
113
|
1 |
|
$columns = $sorted; |
114
|
|
|
} |
115
|
3 |
|
return $columns; |
116
|
|
|
} |
117
|
|
|
|
118
|
3 |
|
private static function getColumnTypeFromFieldType(string $type): string |
119
|
|
|
{ |
120
|
3 |
|
$map = [ |
121
|
3 |
|
CommonTypes::TTEXT => CellTypes::TEXT, |
122
|
3 |
|
CommonTypes::TNUMBER => CellTypes::NUMBER, |
123
|
3 |
|
CommonTypes::TINT => CellTypes::NUMBER, |
124
|
3 |
|
CommonTypes::TBOOL => CellTypes::BOOLEAN, |
125
|
3 |
|
CommonTypes::TDATETIME => CellTypes::DATETIME, |
126
|
3 |
|
CommonTypes::TDATE => CellTypes::DATE, |
127
|
3 |
|
CommonTypes::TTIME => CellTypes::TIME, |
128
|
3 |
|
]; |
129
|
3 |
|
return $map[$type] ?? CellTypes::TEXT; |
130
|
|
|
} |
131
|
|
|
|
132
|
3 |
|
private static function getColumnStyleFromFieldType(string $type): Style |
133
|
|
|
{ |
134
|
|
|
/** @var array<string, array<string, array<string, scalar>>> $map */ |
135
|
3 |
|
$map = [ |
136
|
3 |
|
DBAL::TTEXT => [], |
137
|
3 |
|
DBAL::TNUMBER => ['format' => ['code' => Format::FORMAT_COMMA_2DECS]], |
138
|
3 |
|
DBAL::TINT => ['format' => ['code' => Format::FORMAT_ZERO_0DECS]], |
139
|
3 |
|
DBAL::TBOOL => [ |
140
|
3 |
|
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], |
141
|
3 |
|
], |
142
|
3 |
|
DBAL::TDATETIME => ['format' => ['code' => Format::FORMAT_DATE_YMDHM]], |
143
|
3 |
|
DBAL::TDATE => ['format' => ['code' => Format::FORMAT_DATE_YMD]], |
144
|
3 |
|
DBAL::TTIME => ['format' => ['code' => Format::FORMAT_DATE_HM]], |
145
|
3 |
|
]; |
146
|
3 |
|
$style = new Style(); |
147
|
3 |
|
$style->setFromArray($map[$type] ?? []); |
148
|
3 |
|
return $style; |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
|