1414 */
1515abstract class IOFactory
1616{
17+ public const READER_XLSX = 'Xlsx ' ;
18+ public const READER_XLS = 'Xls ' ;
19+ public const READER_XML = 'Xml ' ;
20+ public const READER_ODS = 'Ods ' ;
21+ public const READER_SYLK = 'Slk ' ;
22+ public const READER_SLK = 'Slk ' ;
23+ public const READER_GNUMERIC = 'Gnumeric ' ;
24+ public const READER_HTML = 'Html ' ;
25+ public const READER_CSV = 'Csv ' ;
26+
27+ public const WRITER_XLSX = 'Xlsx ' ;
28+ public const WRITER_XLS = 'Xls ' ;
29+ public const WRITER_ODS = 'Ods ' ;
30+ public const WRITER_CSV = 'Csv ' ;
31+ public const WRITER_HTML = 'Html ' ;
32+
1733 private static $ readers = [
18- ' Xlsx ' => Reader \Xlsx::class,
19- ' Xls ' => Reader \Xls::class,
20- ' Xml ' => Reader \Xml::class,
21- ' Ods ' => Reader \Ods::class,
22- ' Slk ' => Reader \Slk::class,
23- ' Gnumeric ' => Reader \Gnumeric::class,
24- ' Html ' => Reader \Html::class,
25- ' Csv ' => Reader \Csv::class,
34+ self :: READER_XLSX => Reader \Xlsx::class,
35+ self :: READER_XLS => Reader \Xls::class,
36+ self :: READER_XML => Reader \Xml::class,
37+ self :: READER_ODS => Reader \Ods::class,
38+ self :: READER_SLK => Reader \Slk::class,
39+ self :: READER_GNUMERIC => Reader \Gnumeric::class,
40+ self :: READER_HTML => Reader \Html::class,
41+ self :: READER_CSV => Reader \Csv::class,
2642 ];
2743
2844 private static $ writers = [
29- ' Xls ' => Writer \Xls::class,
30- ' Xlsx ' => Writer \Xlsx::class,
31- ' Ods ' => Writer \Ods::class,
32- ' Csv ' => Writer \Csv::class,
33- ' Html ' => Writer \Html::class,
45+ self :: WRITER_XLS => Writer \Xls::class,
46+ self :: WRITER_XLSX => Writer \Xlsx::class,
47+ self :: WRITER_ODS => Writer \Ods::class,
48+ self :: WRITER_CSV => Writer \Csv::class,
49+ self :: WRITER_HTML => Writer \Html::class,
3450 'Tcpdf ' => Writer \Pdf \Tcpdf::class,
3551 'Dompdf ' => Writer \Pdf \Dompdf::class,
3652 'Mpdf ' => Writer \Pdf \Mpdf::class,
@@ -70,20 +86,28 @@ public static function createReader(string $readerType): IReader
7086 * Loads Spreadsheet from file using automatic Reader\IReader resolution.
7187 *
7288 * @param string $filename The name of the spreadsheet file
89+ * @param int $flags the optional second parameter flags may be used to identify specific elements
90+ * that should be loaded, but which won't be loaded by default, using these values:
91+ * IReader::LOAD_WITH_CHARTS - Include any charts that are defined in the loaded file
92+ * @param string[] $readers An array of Readers to use to identify the file type. By default, load() will try
93+ * all possible Readers until it finds a match; but this allows you to pass in a
94+ * list of Readers so it will only try the subset that you specify here.
95+ * Values in this list can be any of the constant values defined in the set
96+ * IOFactory::READER_*.
7397 */
74- public static function load (string $ filename , int $ flags = 0 ): Spreadsheet
98+ public static function load (string $ filename , int $ flags = 0 , ? array $ readers = null ): Spreadsheet
7599 {
76- $ reader = self ::createReaderForFile ($ filename );
100+ $ reader = self ::createReaderForFile ($ filename, $ readers );
77101
78102 return $ reader ->load ($ filename , $ flags );
79103 }
80104
81105 /**
82106 * Identify file type using automatic IReader resolution.
83107 */
84- public static function identify (string $ filename ): string
108+ public static function identify (string $ filename, ? array $ readers = null ): string
85109 {
86- $ reader = self ::createReaderForFile ($ filename );
110+ $ reader = self ::createReaderForFile ($ filename, $ readers );
87111 $ className = get_class ($ reader );
88112 $ classType = explode ('\\' , $ className );
89113 unset($ reader );
@@ -93,14 +117,32 @@ public static function identify(string $filename): string
93117
94118 /**
95119 * Create Reader\IReader for file using automatic IReader resolution.
120+ *
121+ * @param string[] $readers An array of Readers to use to identify the file type. By default, load() will try
122+ * all possible Readers until it finds a match; but this allows you to pass in a
123+ * list of Readers so it will only try the subset that you specify here.
124+ * Values in this list can be any of the constant values defined in the set
125+ * IOFactory::READER_*.
96126 */
97- public static function createReaderForFile (string $ filename ): IReader
127+ public static function createReaderForFile (string $ filename, ? array $ readers = null ): IReader
98128 {
99129 File::assertFile ($ filename );
100130
131+ $ testReaders = self ::$ readers ;
132+ if ($ readers !== null ) {
133+ $ readers = array_map ('strtoupper ' , $ readers );
134+ $ testReaders = array_filter (
135+ self ::$ readers ,
136+ function (string $ readerType ) use ($ readers ) {
137+ return in_array (strtoupper ($ readerType ), $ readers , true );
138+ },
139+ ARRAY_FILTER_USE_KEY
140+ );
141+ }
142+
101143 // First, lucky guess by inspecting file extension
102144 $ guessedReader = self ::getReaderTypeFromExtension ($ filename );
103- if ($ guessedReader !== null ) {
145+ if (( $ guessedReader !== null ) && array_key_exists ( $ guessedReader , $ testReaders ) ) {
104146 $ reader = self ::createReader ($ guessedReader );
105147
106148 // Let's see if we are lucky
@@ -110,11 +152,11 @@ public static function createReaderForFile(string $filename): IReader
110152 }
111153
112154 // If we reach here then "lucky guess" didn't give any result
113- // Try walking through all the options in self::$autoResolveClasses
114- foreach (self :: $ readers as $ type => $ class ) {
155+ // Try walking through all the options in self::$readers (or the selected subset)
156+ foreach ($ testReaders as $ readerType => $ class ) {
115157 // Ignore our original guess, we know that won't work
116- if ($ type !== $ guessedReader ) {
117- $ reader = self ::createReader ($ type );
158+ if ($ readerType !== $ guessedReader ) {
159+ $ reader = self ::createReader ($ readerType );
118160 if ($ reader ->canRead ($ filename )) {
119161 return $ reader ;
120162 }
0 commit comments