|
12 | 12 |
|
13 | 13 | class _XLSXWriter_ extends XLSXWriter |
14 | 14 | { |
15 | | - public function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $column_number, $value, $cell_format) { |
16 | | - return call_user_func_array('parent::writeCell', [&$file, $row_number, $column_number, $value, $cell_format]); |
| 15 | + public function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $column_number, $value, $cell_format, $cell_style_idx = null) { |
| 16 | + return call_user_func_array('parent::writeCell', [&$file, $row_number, $column_number, $value, $cell_format, $cell_style_idx = null]); |
17 | 17 | } |
18 | 18 | } |
19 | 19 | //Just a simple test, by no means comprehensive |
@@ -364,6 +364,59 @@ public function testRowCollapsed() { |
364 | 364 | @unlink($filename); |
365 | 365 | } |
366 | 366 |
|
| 367 | + public function testAddBorder() { |
| 368 | + $filename = tempnam("/tmp", "xlsx_writer"); |
| 369 | + |
| 370 | + $header = ["0"=>"string", "1"=>"string", "2"=>"string", "3"=>"string"]; |
| 371 | + $sheet = [ |
| 372 | + ["55", "66", "77", "88"], |
| 373 | + ["10", "11", "12", "13"], |
| 374 | + ]; |
| 375 | + |
| 376 | + $expected_borders = ["right", "left", "top", "bottom"]; |
| 377 | + $expected_border_style = "thick"; |
| 378 | + $expected_border_color_base = "ff99cc"; |
| 379 | + $expected_border_color = "FFFF99CC"; |
| 380 | + |
| 381 | + $row_options = [ |
| 382 | + "border" => implode(",", $expected_borders), |
| 383 | + "border-style" => $expected_border_style, |
| 384 | + "border-color" => "#$expected_border_color_base" , |
| 385 | + ]; |
| 386 | + |
| 387 | + $xlsx_writer = new XLSXWriter(); |
| 388 | + $xlsx_writer->writeSheetHeader("mysheet", $header); |
| 389 | + $xlsx_writer->writeSheetRow("mysheet", $sheet[0], $format = "xlsx", $delimiter = ";", $row_options); |
| 390 | + $xlsx_writer->writeSheetRow("mysheet", $sheet[1]); |
| 391 | + $xlsx_writer->writeToFile($filename); |
| 392 | + |
| 393 | + $zip = new ZipArchive(); |
| 394 | + $r = $zip->open($filename); |
| 395 | + $xml = $this->extractSheetXml($zip); |
| 396 | + $styles = $this->extractStyleXml($zip); |
| 397 | + |
| 398 | + $this->assertTrue($r); |
| 399 | + $this->assertNotEmpty(($zip->numFiles)); |
| 400 | + $this->assertNotEmpty($xml); |
| 401 | + $this->assertNotEmpty($styles); |
| 402 | + |
| 403 | + $border_styles = $styles->borders; |
| 404 | + $this->assertBorderStyle($expected_border_style, $expected_border_color, $border = $border_styles->border[1]); |
| 405 | + $this->assertFillStyle($expected_pattern = "solid", $expected_bg_color = "FF003300", $styles->fills->fill[2]); |
| 406 | + $this->assertFontStyle($expected_font_name = "Arial", $expected_is_bold = "true", $styles->fonts->font[4]); |
| 407 | + |
| 408 | + $cell_styles = $styles->cellXfs->xf; |
| 409 | + $this->assertCellStyle($expected_apply_border_string = "false", $expected_border_id = 0, $expected_fill_id = 2, $expected_font_id = 4, $cell_styles[6]); |
| 410 | + $this->assertCellStyle($expected_apply_border_string = "true", $expected_border_id = 1, $expected_fill_id = 0, $expected_font_id = 0, $cell_styles[7]); |
| 411 | + |
| 412 | + $rows = $xml->sheetData->row; |
| 413 | + $this->assertRowHasStyleIndex($rows[0], $expected_header_style = 6); |
| 414 | + $this->assertRowHasStyleIndex($rows[1], $expected_style = 7); |
| 415 | + |
| 416 | + $zip->close(); |
| 417 | + @unlink($filename); |
| 418 | + } |
| 419 | + |
367 | 420 | private function stripCellsFromSheetXML($sheet_xml) { |
368 | 421 | $output = []; |
369 | 422 |
|
@@ -411,10 +464,61 @@ private function extractSheetXml($zip) { |
411 | 464 | return null; |
412 | 465 | } |
413 | 466 |
|
| 467 | + private function extractStyleXml($zip) { |
| 468 | + for($z=0; $z < $zip->numFiles; $z++) { |
| 469 | + $inside_zip_filename = $zip->getNameIndex($z); |
| 470 | + $xml = $zip->getFromName($inside_zip_filename); |
| 471 | + if (preg_match("/styles.xml/", basename($inside_zip_filename))) { |
| 472 | + return new SimpleXMLElement($xml); |
| 473 | + } |
| 474 | + } |
| 475 | + |
| 476 | + return null; |
| 477 | + } |
| 478 | + |
414 | 479 | private function assertRowProperties($expected_height, $expected_custom_height, $expected_hidden, $expected_collapsed, $row) { |
415 | 480 | $this->assertEquals($expected_height, (string)$row['ht']); |
416 | 481 | $this->assertEquals($expected_custom_height, filter_var($row['customHeight'], FILTER_VALIDATE_BOOLEAN)); |
417 | 482 | $this->assertEquals($expected_hidden, filter_var($row['hidden'], FILTER_VALIDATE_BOOLEAN)); |
418 | 483 | $this->assertEquals($expected_collapsed, filter_var($row['collapsed'], FILTER_VALIDATE_BOOLEAN)); |
419 | 484 | } |
| 485 | + |
| 486 | + private function assertCellStyle($expected_apply_border_string, $expected_border_id, $expected_fill_id, $expected_font_id, $cell_style) { |
| 487 | + $this->assertEquals($expected_apply_border_string, $cell_style["applyBorder"]); |
| 488 | + $this->assertEquals($expected_border_id, (int)$cell_style["borderId"]); |
| 489 | + $this->assertEquals($expected_fill_id, (int)$cell_style["fillId"]); |
| 490 | + $this->assertEquals($expected_font_id, (int)$cell_style["fontId"]); |
| 491 | + } |
| 492 | + |
| 493 | + private function assertBorderStyle($expected_border_style, $expected_border_color, $border) { |
| 494 | + $this->assertEquals($expected_border_style, $border->left["style"]); |
| 495 | + $this->assertEquals($expected_border_style, $border->right["style"]); |
| 496 | + $this->assertEquals($expected_border_style, $border->top["style"]); |
| 497 | + $this->assertEquals($expected_border_style, $border->bottom["style"]); |
| 498 | + |
| 499 | + $this->assertEquals($expected_border_color, $border->left->color["rgb"]); |
| 500 | + $this->assertEquals($expected_border_color, $border->right->color["rgb"]); |
| 501 | + $this->assertEquals($expected_border_color, $border->top->color["rgb"]); |
| 502 | + $this->assertEquals($expected_border_color, $border->bottom->color["rgb"]); |
| 503 | + } |
| 504 | + |
| 505 | + private function assertFillStyle($expected_pattern, $expected_bg_color, $fill) { |
| 506 | + $this->assertEquals($expected_pattern, $fill->patternFill["patternType"]); |
| 507 | + if (!empty($expected_bg_color)) { |
| 508 | + $this->assertEquals($expected_bg_color, $fill->patternFill->bgColor["rgb"]); |
| 509 | + } |
| 510 | + } |
| 511 | + |
| 512 | + private function assertFontStyle($expected_font_name, $expected_is_bold, $font) { |
| 513 | + $this->assertEquals($expected_font_name, $font->name["val"]); |
| 514 | + if (!empty($expected_is_bold)) { |
| 515 | + $this->assertEquals($expected_is_bold, $font->b["val"]); |
| 516 | + } |
| 517 | + } |
| 518 | + |
| 519 | + private function assertRowHasStyleIndex($row, $expected_style) { |
| 520 | + foreach ($row->c as $cell) { |
| 521 | + $this->assertEquals($expected_style, (int)$cell["s"]); |
| 522 | + } |
| 523 | + } |
420 | 524 | } |
0 commit comments