Overview
Comment: | TableToODS: fix bugs with 0,00 values, and use default locale than can be modified |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f4a1bc985331586e287fdc632ae10d63 |
User & Date: | bohwaz on 2023-04-08 13:26:52 |
Other Links: | manifest | tags |
Context
2023-04-08
| ||
13:27 | Implement TableToXLSX (doesn't support styles yet) check-in: a4f9c6aebb user: bohwaz tags: trunk | |
13:26 | TableToODS: fix bugs with 0,00 values, and use default locale than can be modified check-in: f4a1bc9853 user: bohwaz tags: trunk | |
13:26 | TableExport: implement XLSX export check-in: be28df917f user: bohwaz tags: trunk | |
Changes
Modified src/lib/KD2/HTML/TableToODS.php from [3fcb97742f] to [2875c39d87].
︙ | ︙ | |||
9 10 11 12 13 14 15 | use DOMNode; /** * This class takes one or more HTML tables, and convert them to a single ODS document. * * - a basic set of CSS properties are supported! | | | | 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 | use DOMNode; /** * This class takes one or more HTML tables, and convert them to a single ODS document. * * - a basic set of CSS properties are supported! * - support for colspan and rowspan * - automatic column width * - custom CSS properties * - each table is handled as a sheet, the <caption> will act as the name of the sheet * - detection of cell type, or force cell type using '-spreadsheet-cell-type' * - provide the real number via the "data-spreadsheet-value" HTML attribute * (eg. if the number is displayed as a graph, or something like that) * - provide the real date via the "data-spreadsheet-value" attribute * * What is NOT supported: * - cells using rowspan AND colspan at the same time * - formulas * * Usage: $ods = new TableToODS; $ods->import('<table...</table>'); $ods->save('file.ods'); * * Supported CSS properties: * - the following color names: black, white, red, green, blue, yellow, magenta, cyan * - 'initial' value to restore to default |
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 | protected array $rows = []; protected int $row_index = 0; protected int $col_index = 0; protected int $count = 0; protected array $columns_widths = []; public string $default_sheet_name = 'Sheet%d'; const XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'; const DATA_TYPES = [ 'number', 'date', 'currency', | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | protected array $rows = []; protected int $row_index = 0; protected int $col_index = 0; protected int $count = 0; protected array $columns_widths = []; public string $default_sheet_name = 'Sheet%d'; public string $default_locale = 'fr_FR'; const XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'; const DATA_TYPES = [ 'number', 'date', 'currency', |
︙ | ︙ | |||
299 300 301 302 303 304 305 | { // Skip rowspan while (isset($this->rows[$this->row_index][$this->col_index])) { $this->col_index++; } $value = trim($value); | > | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | { // Skip rowspan while (isset($this->rows[$this->row_index][$this->col_index])) { $this->col_index++; } $value = trim($value); $type = !empty($attributes['type']) ? $attributes['type'] : ($styles['-spreadsheet-cell-type'] ?? null); $type = $this->getCellType($value, $type); // Use real type in styles, useful to set the correct style $styles['-spreadsheet-cell-type'] = $type; $end = ''; $cell = sprintf('<table:table-cell table:style-name="%s"', $this->newStyle('cell', $styles) ?? 'Default'); |
︙ | ︙ | |||
373 374 375 376 377 378 379 | if (null !== $html) { // Break in multiple lines if required $html = preg_replace("/[\n\r]/", '', $html); $html = preg_replace('/<br[^>]*>/U', "\n", $html); $html = strip_tags($html); | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | if (null !== $html) { // Break in multiple lines if required $html = preg_replace("/[\n\r]/", '', $html); $html = preg_replace('/<br[^>]*>/U', "\n", $html); $html = strip_tags($html); $value = html_entity_decode($html, ENT_QUOTES | ENT_XML1, 'UTF-8'); } else { // Break in multiple lines if required $value = preg_replace("/[\n\r]/", '', $value); } $value = explode("\n", trim($value)); |
︙ | ︙ | |||
428 429 430 431 432 433 434 | $cells = $this->css->xpath($row, './/td|.//th'); foreach ($cells as $cell) { $attributes = [ 'colspan' => $cell->getAttribute('colspan'), 'rowspan' => $cell->getAttribute('rowspan'), | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | $cells = $this->css->xpath($row, './/td|.//th'); foreach ($cells as $cell) { $attributes = [ 'colspan' => $cell->getAttribute('colspan'), 'rowspan' => $cell->getAttribute('rowspan'), 'type' => $cell->getAttribute('data-spreadsheet-type') ?: null, ]; $value = $cell->getAttribute('data-spreadsheet-value') ?: $cell->textContent; $value = html_entity_decode($value); $value = trim($value); $html = null; |
︙ | ︙ | |||
463 464 465 466 467 468 469 | } $number_value = str_replace([' ', "\xC2\xA0"], '', trim($value)); if (is_object($value) && $value instanceof \DateTimeInterface) { return 'date'; } | | > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | } $number_value = str_replace([' ', "\xC2\xA0"], '', trim($value)); if (is_object($value) && $value instanceof \DateTimeInterface) { return 'date'; } elseif (is_int($value) || is_float($value) || (preg_match('/^-?(\d+)(?:[,.]\d+)?$/', (string) $number_value, $match) && ($match[1] == 0 || substr($match[1], 0, 1) != '0'))) { return 'number'; } elseif (preg_match('!^(?:\d\d?/\d\d?/\d\d(?:\d\d)?|\d{4}-\d{2}-\d{2})(?:\s+\d\d?[:\.]\d\d?(?:[:\.]\d\d?))?$!', $value)) { return 'date'; } elseif (preg_match('/^-?\d+(?:[,.]\d+)?\s*%$/', $number_value)) { return 'percentage'; |
︙ | ︙ | |||
548 549 550 551 552 553 554 | $out .= $this->xml; $out .= '</office:spreadsheet></office:body></office:document-content>'; return $out; } | < < < < < | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | $out .= $this->xml; $out .= '</office:spreadsheet></office:body></office:document-content>'; return $out; } protected function outputStyles(): string { $xml = ''; foreach ($this->styles as $style_name => $properties) { $type = substr($style_name, 0, strpos($style_name, '_')); $tags = []; |
︙ | ︙ | |||
810 811 812 813 814 815 816 817 | $position = $styles['-spreadsheet-currency-position'] ?? 'suffix'; if ($color === null) { $color = 'red'; } if (isset($styles['-spreadsheet-locale']) && preg_match('/^[a-z]{2}[_-][A-Z]{2}$', $styles['-spreadsheet-locale'])) { | > > | < | | | < | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | $position = $styles['-spreadsheet-currency-position'] ?? 'suffix'; if ($color === null) { $color = 'red'; } $locale = $this->default_locale; if (isset($styles['-spreadsheet-locale']) && preg_match('/^[a-z]{2}[_-][A-Z]{2}$', $styles['-spreadsheet-locale'])) { $locale = $styles['-spreadsheet-locale']; } $lang = substr($locale, 0, 2); $country = substr($locale, 3, 2); $tag_name = 'number:currency-style'; $space = '<number:text> </number:text>'; $currency = sprintf('<number:currency-symbol number:language="%s" number:country="%s">%s</number:currency-symbol>', $lang, $country, htmlspecialchars($symbol, ENT_XML1)); |
︙ | ︙ |