export( 'Feuille test', ['Nom', 'Email'], [ ['Alpha', 'alpha@test.fr'], ['Beta', null], ], ); self::assertNotSame('', $binary); // Un fichier XLSX (OOXML) est une archive ZIP : signature "PK\x03\x04". self::assertStringStartsWith("PK\x03\x04", $binary); $grid = $this->grid($binary); self::assertSame(['Nom', 'Email'], $grid[0]); self::assertSame('Alpha', $grid[1][0]); self::assertSame('alpha@test.fr', $grid[1][1]); self::assertSame('Beta', $grid[2][0]); // Cellule null a l'ecriture -> vide a la relecture. self::assertNull($grid[2][1]); } public function testExportAcceptsGeneratorRows(): void { $rows = (static function (): Generator { yield ['L1']; yield ['L2']; })(); $grid = $this->grid(new PhpSpreadsheetExporter()->export('Gen', ['H'], $rows)); self::assertSame('H', $grid[0][0]); self::assertSame('L1', $grid[1][0]); self::assertSame('L2', $grid[2][0]); } public function testLongOrInvalidSheetTitleIsSanitized(): void { // Titre > 31 caracteres + caracteres interdits par Excel ([ ] : * etc.). $binary = new PhpSpreadsheetExporter()->export( str_repeat('A', 50).'[]:*?/\\', ['H'], [['x']], ); $title = $this->load($binary)->getActiveSheet()->getTitle(); self::assertLessThanOrEqual(31, mb_strlen($title)); self::assertStringNotContainsString('[', $title); self::assertStringNotContainsString(':', $title); } /** * Relit le binaire XLSX et renvoie la grille de cellules (ligne 0 = entete). * * @return array> */ private function grid(string $binary): array { return $this->load($binary)->getActiveSheet()->toArray(); } private function load(string $binary): Spreadsheet { $tmp = tempnam(sys_get_temp_dir(), 'xlsx_test_'); self::assertIsString($tmp); file_put_contents($tmp, $binary); try { return IOFactory::load($tmp); } finally { @unlink($tmp); } } }