6
6
7
7
use Box \Spout \Common \Entity \Style \CellAlignment ;
8
8
use Box \Spout \Common \Entity \Style \Color ;
9
- use Box \Spout \Reader \Wrapper \XMLReader ;
10
9
use Box \Spout \Writer \Common \Creator \Style \StyleBuilder ;
11
10
use Box \Spout \Writer \Common \Creator \WriterEntityFactory ;
12
11
use PHPUnit \Framework \TestCase ;
13
12
use Yokai \Batch \Bridge \Box \Spout \Writer \FlatFileWriter ;
14
13
use Yokai \Batch \Bridge \Box \Spout \Writer \Options \CSVOptions ;
15
14
use Yokai \Batch \Bridge \Box \Spout \Writer \Options \ODSOptions ;
16
15
use Yokai \Batch \Bridge \Box \Spout \Writer \Options \XLSXOptions ;
16
+ use Yokai \Batch \Bridge \Box \Spout \Writer \WriteToSheetItem ;
17
17
use Yokai \Batch \Exception \BadMethodCallException ;
18
18
use Yokai \Batch \Exception \RuntimeException ;
19
19
use Yokai \Batch \Exception \UnexpectedValueException ;
@@ -35,7 +35,6 @@ public function testWrite(
35
35
string $ expectedContent
36
36
): void {
37
37
$ file = self ::WRITE_DIR . '/ ' . $ filename ;
38
-
39
38
self ::assertFileDoesNotExist ($ file );
40
39
41
40
$ writer = new FlatFileWriter (new StaticValueParameterAccessor ($ file ), $ options (), $ headers );
@@ -219,6 +218,58 @@ public function types(): \Generator
219
218
yield [$ type , $ options ];
220
219
}
221
220
}
221
+
222
+ /**
223
+ * @dataProvider multipleSheetsOptions
224
+ */
225
+ public function testWriteMultipleSheets (string $ type , callable $ options ): void
226
+ {
227
+ $ file = self ::WRITE_DIR . '/multiple-sheets. ' . $ type ;
228
+ self ::assertFileDoesNotExist ($ file );
229
+
230
+ $ writer = new FlatFileWriter (new StaticValueParameterAccessor ($ file ), $ options ());
231
+ $ writer ->setJobExecution (JobExecution::createRoot ('123456789 ' , 'export ' ));
232
+
233
+ $ writer ->initialize ();
234
+ $ writer ->write ([
235
+ WriteToSheetItem::array ('English ' , ['John ' , 'Doe ' ]),
236
+ WriteToSheetItem::array ('Français ' , ['Jean ' , 'Aimar ' ]),
237
+ WriteToSheetItem::row ('English ' , WriterEntityFactory::createRowFromArray (['Jack ' , 'Doe ' ])),
238
+ WriteToSheetItem::row ('Français ' , WriterEntityFactory::createRowFromArray (['Jacques ' , 'Ouzi ' ])),
239
+ ]);
240
+ $ writer ->flush ();
241
+
242
+ if ($ type === 'csv ' ) {
243
+ self ::assertFileContents ($ file , <<<CSV
244
+ John,Doe
245
+ Jean,Aimar
246
+ Jack,Doe
247
+ Jacques,Ouzi
248
+ CSV );
249
+ } else {
250
+ self ::assertSheetContents ($ file , 'English ' , <<<CSV
251
+ John,Doe
252
+ Jack,Doe
253
+ CSV );
254
+ self ::assertSheetContents ($ file , 'Français ' , <<<CSV
255
+ Jean,Aimar
256
+ Jacques,Ouzi
257
+ CSV );
258
+ }
259
+ }
260
+
261
+ public function multipleSheetsOptions (): \Generator
262
+ {
263
+ $ types = [
264
+ 'csv ' => fn () => new CSVOptions (),
265
+ 'xlsx ' => fn () => new XLSXOptions ('English ' ),
266
+ 'ods ' => fn () => new ODSOptions ('English ' ),
267
+ ];
268
+ foreach ($ types as $ type => $ options ) {
269
+ yield [$ type , $ options ];
270
+ }
271
+ }
272
+
222
273
/**
223
274
* @dataProvider wrongOptions
224
275
*/
@@ -283,15 +334,55 @@ private static function assertFileContents(string $filePath, string $inlineData)
283
334
$ pathToSheetFile = $ filePath . '#xl/worksheets/sheet1.xml ' ;
284
335
$ xmlContents = file_get_contents ('zip:// ' . $ pathToSheetFile );
285
336
foreach ($ strings as $ string ) {
286
- self ::assertStringContainsString ($ string , $ xmlContents );
337
+ self ::assertStringContainsString (" <t> $ string</t> " , $ xmlContents );
287
338
}
288
339
break ;
289
340
290
341
case 'ods ' :
291
- $ xmlReader = new XMLReader ();
292
- $ xmlReader ->openFileInZip ($ filePath , 'content.xml ' );
293
- $ xmlReader ->readUntilNodeFound ('table:table ' );
294
- $ sheetXmlAsString = $ xmlReader ->readOuterXml ();
342
+ $ sheetContent = file_get_contents ('zip:// ' . $ filePath . '#content.xml ' );
343
+ if (!preg_match ('#<table:table[^>]+>[\s\S]*?<\/table:table># ' , $ sheetContent , $ matches )) {
344
+ self ::fail ('No sheet found in file " ' . $ filePath . '". ' );
345
+ }
346
+ $ sheetXmlAsString = $ matches [0 ];
347
+ foreach ($ strings as $ string ) {
348
+ self ::assertStringContainsString ("<text:p> $ string</text:p> " , $ sheetXmlAsString );
349
+ }
350
+ break ;
351
+ }
352
+ }
353
+
354
+ private static function assertSheetContents (string $ filePath , string $ sheet , string $ inlineData ): void
355
+ {
356
+ $ type = \strtolower (\pathinfo ($ filePath , PATHINFO_EXTENSION ));
357
+ $ strings = array_merge (...array_map ('str_getcsv ' , explode (PHP_EOL , $ inlineData )));
358
+
359
+ switch ($ type ) {
360
+ case 'csv ' :
361
+ $ fileContents = file_get_contents ($ filePath );
362
+ foreach ($ strings as $ string ) {
363
+ self ::assertStringContainsString ($ string , $ fileContents );
364
+ }
365
+ break ;
366
+
367
+ case 'xlsx ' :
368
+ $ workbookContent = file_get_contents ('zip:// ' . $ filePath . '#xl/workbook.xml ' );
369
+ if (!preg_match ('#<sheet name=" ' . $ sheet . '" sheetId="([0-9]+)"# ' , $ workbookContent , $ matches )) {
370
+ self ::fail ('Sheet ' . $ sheet . ' was not found in file " ' . $ filePath . '". ' );
371
+ }
372
+ $ sheetFilename = 'sheet ' . $ matches [1 ];
373
+ $ sheetContent = file_get_contents ('zip:// ' . $ filePath . '#xl/worksheets/ ' . $ sheetFilename . '.xml ' );
374
+ foreach ($ strings as $ string ) {
375
+ self ::assertStringContainsString ("<t> $ string</t> " , $ sheetContent );
376
+ }
377
+ break ;
378
+
379
+ case 'ods ' :
380
+ $ sheetContent = file_get_contents ('zip:// ' . $ filePath . '#content.xml ' );
381
+ $ regex = '#<table:table.+table:name=" ' . $ sheet . '">[\s\S]*?<\/table:table># ' ;
382
+ if (!preg_match ($ regex , $ sheetContent , $ matches )) {
383
+ self ::fail ('Sheet ' . $ sheet . ' was not found in file " ' . $ filePath . '". ' );
384
+ }
385
+ $ sheetXmlAsString = $ matches [0 ];
295
386
foreach ($ strings as $ string ) {
296
387
self ::assertStringContainsString ("<text:p> $ string</text:p> " , $ sheetXmlAsString );
297
388
}
0 commit comments