IOFactory.php
6.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?php
namespace PhpOffice\PhpSpreadsheet;
use PhpOffice\PhpSpreadsheet\Shared\File;
/**
* Factory to create readers and writers easily.
*
* It is not required to use this class, but it should make it easier to read and write files.
* Especially for reading files with an unknown format.
*/
abstract class IOFactory
{
private static $readers = [
'Xlsx' => Reader\Xlsx::class,
'Xls' => Reader\Xls::class,
'Xml' => Reader\Xml::class,
'Ods' => Reader\Ods::class,
'Slk' => Reader\Slk::class,
'Gnumeric' => Reader\Gnumeric::class,
'Html' => Reader\Html::class,
'Csv' => Reader\Csv::class,
];
private static $writers = [
'Xls' => Writer\Xls::class,
'Xlsx' => Writer\Xlsx::class,
'Ods' => Writer\Ods::class,
'Csv' => Writer\Csv::class,
'Html' => Writer\Html::class,
'Tcpdf' => Writer\Pdf\Tcpdf::class,
'Dompdf' => Writer\Pdf\Dompdf::class,
'Mpdf' => Writer\Pdf\Mpdf::class,
];
/**
* Create Writer\IWriter.
*
* @param Spreadsheet $spreadsheet
* @param string $writerType Example: Xlsx
*
* @throws Writer\Exception
*
* @return Writer\IWriter
*/
public static function createWriter(Spreadsheet $spreadsheet, $writerType)
{
if (!isset(self::$writers[$writerType])) {
throw new Writer\Exception("No writer found for type $writerType");
}
// Instantiate writer
$className = self::$writers[$writerType];
$writer = new $className($spreadsheet);
return $writer;
}
/**
* Create Reader\IReader.
*
* @param string $readerType Example: Xlsx
*
* @throws Reader\Exception
*
* @return Reader\IReader
*/
public static function createReader($readerType)
{
if (!isset(self::$readers[$readerType])) {
throw new Reader\Exception("No reader found for type $readerType");
}
// Instantiate reader
$className = self::$readers[$readerType];
$reader = new $className();
return $reader;
}
/**
* Loads Spreadsheet from file using automatic Reader\IReader resolution.
*
* @param string $pFilename The name of the spreadsheet file
*
* @throws Reader\Exception
*
* @return Spreadsheet
*/
public static function load($pFilename)
{
$reader = self::createReaderForFile($pFilename);
return $reader->load($pFilename);
}
/**
* Identify file type using automatic Reader\IReader resolution.
*
* @param string $pFilename The name of the spreadsheet file to identify
*
* @throws Reader\Exception
*
* @return string
*/
public static function identify($pFilename)
{
$reader = self::createReaderForFile($pFilename);
$className = get_class($reader);
$classType = explode('\\', $className);
unset($reader);
return array_pop($classType);
}
/**
* Create Reader\IReader for file using automatic Reader\IReader resolution.
*
* @param string $filename The name of the spreadsheet file
*
* @throws Reader\Exception
*
* @return Reader\IReader
*/
public static function createReaderForFile($filename)
{
File::assertFile($filename);
// First, lucky guess by inspecting file extension
$guessedReader = self::getReaderTypeFromExtension($filename);
if ($guessedReader !== null) {
$reader = self::createReader($guessedReader);
// Let's see if we are lucky
if (isset($reader) && $reader->canRead($filename)) {
return $reader;
}
}
// If we reach here then "lucky guess" didn't give any result
// Try walking through all the options in self::$autoResolveClasses
foreach (self::$readers as $type => $class) {
// Ignore our original guess, we know that won't work
if ($type !== $guessedReader) {
$reader = self::createReader($type);
if ($reader->canRead($filename)) {
return $reader;
}
}
}
throw new Reader\Exception('Unable to identify a reader for this file');
}
/**
* Guess a reader type from the file extension, if any.
*
* @param string $filename
*
* @return null|string
*/
private static function getReaderTypeFromExtension($filename)
{
$pathinfo = pathinfo($filename);
if (!isset($pathinfo['extension'])) {
return null;
}
switch (strtolower($pathinfo['extension'])) {
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
case 'xltx': // Excel (OfficeOpenXML) Template
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded)
return 'Xlsx';
case 'xls': // Excel (BIFF) Spreadsheet
case 'xlt': // Excel (BIFF) Template
return 'Xls';
case 'ods': // Open/Libre Offic Calc
case 'ots': // Open/Libre Offic Calc Template
return 'Ods';
case 'slk':
return 'Slk';
case 'xml': // Excel 2003 SpreadSheetML
return 'Xml';
case 'gnumeric':
return 'Gnumeric';
case 'htm':
case 'html':
return 'Html';
case 'csv':
// Do nothing
// We must not try to use CSV reader since it loads
// all files including Excel files etc.
return null;
default:
return null;
}
}
/**
* Register a writer with its type and class name.
*
* @param string $writerType
* @param string $writerClass
*/
public static function registerWriter($writerType, $writerClass)
{
if (!is_a($writerClass, Writer\IWriter::class, true)) {
throw new Writer\Exception('Registered writers must implement ' . Writer\IWriter::class);
}
self::$writers[$writerType] = $writerClass;
}
/**
* Register a reader with its type and class name.
*
* @param string $readerType
* @param string $readerClass
*/
public static function registerReader($readerType, $readerClass)
{
if (!is_a($readerClass, Reader\IReader::class, true)) {
throw new Reader\Exception('Registered readers must implement ' . Reader\IReader::class);
}
self::$readers[$readerType] = $readerClass;
}
}