Skip to content

Commit

Permalink
Merge pull request #4257 from oleibman/htmlbool
Browse files Browse the repository at this point in the history
Html Reader/Writer Better Handling of Booleans
  • Loading branch information
oleibman authored Dec 6, 2024
2 parents 9dc82e6 + 40d0b8e commit e23c987
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org).

### Fixed

- Html Reader/Writer Better Handling of Booleans. [PR #4257](https://github.com/PHPOffice/PhpSpreadsheet/pull/4257)
- Fill Patterns/Colors When Xml Attributes are Missing. [Issue #4248](https://github.com/PHPOffice/PhpSpreadsheet/issues/4248) [PR #4250](https://github.com/PHPOffice/PhpSpreadsheet/pull/4250)
- Remove Unneccesary files from Composer Package. [PR #4262](https://github.com/PHPOffice/PhpSpreadsheet/pull/4262)
- Swapped row and column indexes in ReferenceHelper. [Issue #4246](https://github.com/PHPOffice/PhpSpreadsheet/issues/4246) [PR #4247](https://github.com/PHPOffice/PhpSpreadsheet/pull/4247)
- Fix minor break handling drawings. [Issue #4241](https://github.com/PHPOffice/PhpSpreadsheet/issues/4241) [PR #4244](https://github.com/PHPOffice/PhpSpreadsheet/pull/4244)
- Ignore cell formatting when the format is a single @. [Issue #4242](https://github.com/PHPOffice/PhpSpreadsheet/issues/4242) [PR #4243](https://github.com/PHPOffice/PhpSpreadsheet/pull/4243)
Expand Down
47 changes: 47 additions & 0 deletions src/PhpSpreadsheet/Calculation/Calculation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3141,6 +3141,53 @@ private function getLocaleFile(string $localeDir, string $locale, string $langua
return $localeFileName;
}

/** @var array<int, array<int, string>> */
private static array $falseTrueArray = [];

/** @return array<int, array<int, string>> */
public function getFalseTrueArray(): array
{
if (!empty(self::$falseTrueArray)) {
return self::$falseTrueArray;
}
if (count(self::$validLocaleLanguages) == 1) {
self::loadLocales();
}
$falseTrueArray = [['FALSE'], ['TRUE']];
foreach (self::$validLocaleLanguages as $language) {
if (str_starts_with($language, 'en')) {
continue;
}
$locale = $language;
if (str_contains($locale, '_')) {
[$language] = explode('_', $locale);
}
$localeDir = implode(DIRECTORY_SEPARATOR, [__DIR__, 'locale', null]);

try {
$functionNamesFile = $this->getLocaleFile($localeDir, $locale, $language, 'functions');
} catch (Exception $e) {
continue;
}
// Retrieve the list of locale or language specific function names
$localeFunctions = file($functionNamesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
foreach ($localeFunctions as $localeFunction) {
[$localeFunction] = explode('##', $localeFunction); // Strip out comments
if (str_contains($localeFunction, '=')) {
[$fName, $lfName] = array_map('trim', explode('=', $localeFunction));
if ($fName === 'FALSE') {
$falseTrueArray[0][] = $lfName;
} elseif ($fName === 'TRUE') {
$falseTrueArray[1][] = $lfName;
}
}
}
}
self::$falseTrueArray = $falseTrueArray;

return $falseTrueArray;
}

/**
* Set the locale code.
*
Expand Down
32 changes: 32 additions & 0 deletions src/PhpSpreadsheet/Reader/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use DOMElement;
use DOMNode;
use DOMText;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Comment;
Expand Down Expand Up @@ -271,6 +272,12 @@ protected function flushCell(Worksheet $sheet, string $column, int|string $row,
->setQuotePrefix(true);
}
}
if ($datatype === DataType::TYPE_BOOL) {
$cellContent = self::convertBoolean($cellContent);
if (!is_bool($cellContent)) {
$attributeArray['data-type'] = DataType::TYPE_STRING;
}
}

//catching the Exception and ignoring the invalid data types
try {
Expand All @@ -291,6 +298,31 @@ protected function flushCell(Worksheet $sheet, string $column, int|string $row,
$cellContent = (string) '';
}

/** @var array<int, array<int, string>> */
private static array $falseTrueArray = [];

private static function convertBoolean(?string $cellContent): bool|string
{
if ($cellContent === '1') {
return true;
}
if ($cellContent === '0' || $cellContent === '' || $cellContent === null) {
return false;
}
if (empty(self::$falseTrueArray)) {
$calc = Calculation::getInstance();
self::$falseTrueArray = $calc->getFalseTrueArray();
}
if (in_array(mb_strtoupper($cellContent), self::$falseTrueArray[1], true)) {
return true;
}
if (in_array(mb_strtoupper($cellContent), self::$falseTrueArray[0], true)) {
return false;
}

return $cellContent;
}

private function processDomElementBody(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child): void
{
$attributeArray = [];
Expand Down
64 changes: 60 additions & 4 deletions src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Comment;
use PhpOffice\PhpSpreadsheet\Document\Properties;
Expand Down Expand Up @@ -141,13 +142,22 @@ class Html extends BaseWriter
/** @var Chart[] */
private $sheetCharts;

private bool $betterBoolean = false;

private string $getTrue = 'TRUE';

private string $getFalse = 'FALSE';

/**
* Create a new HTML.
*/
public function __construct(Spreadsheet $spreadsheet)
{
$this->spreadsheet = $spreadsheet;
$this->defaultFont = $this->spreadsheet->getDefaultStyle()->getFont();
$calc = Calculation::getInstance($this->spreadsheet);
$this->getTrue = $calc->getTRUE();
$this->getFalse = $calc->getFALSE();
}

/**
Expand Down Expand Up @@ -1353,8 +1363,21 @@ private function generateRowCellDataValue(Worksheet $worksheet, Cell $cell, stri
if ($cell->getValue() instanceof RichText) {
$cellData .= $this->generateRowCellDataValueRich($cell->getValue());
} else {
$origData = $this->preCalculateFormulas ? $cell->getCalculatedValue() : $cell->getValue();
$origData2 = $this->preCalculateFormulas ? $cell->getCalculatedValueString() : $cell->getValueString();
if ($this->preCalculateFormulas) {
$origData = $cell->getCalculatedValue();
if ($this->betterBoolean && is_bool($origData)) {
$origData2 = $origData ? $this->getTrue : $this->getFalse;
} else {
$origData2 = $cell->getCalculatedValueString();
}
} else {
$origData = $cell->getValue();
if ($this->betterBoolean && is_bool($origData)) {
$origData2 = $origData ? $this->getTrue : $this->getFalse;
} else {
$origData2 = $cell->getValueString();
}
}
$formatCode = $worksheet->getParentOrThrow()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode();

$cellData = NumberFormat::toFormattedString(
Expand Down Expand Up @@ -1394,9 +1417,20 @@ private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cel
$cellData = nl2br($cellData);

// Extend CSS class?
$dataType = $cell->getDataType();
if ($this->betterBoolean && $this->preCalculateFormulas && $dataType === DataType::TYPE_FORMULA) {
$calculatedValue = $cell->getCalculatedValue();
if (is_bool($calculatedValue)) {
$dataType = DataType::TYPE_BOOL;
} elseif (is_numeric($calculatedValue)) {
$dataType = DataType::TYPE_NUMERIC;
} elseif (is_string($calculatedValue)) {
$dataType = DataType::TYPE_STRING;
}
}
if (!$this->useInlineCss && is_string($cssClass)) {
$cssClass .= ' style' . $cell->getXfIndex();
$cssClass .= ' ' . $cell->getDataType();
$cssClass .= ' ' . $dataType;
} elseif (is_array($cssClass)) {
$index = $cell->getXfIndex();
$styleIndex = 'td.style' . $index . ', th.style' . $index;
Expand All @@ -1410,7 +1444,7 @@ private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cel
$sharedStyle->getAlignment()->getHorizontal() == Alignment::HORIZONTAL_GENERAL
&& isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])
) {
$cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align'];
$cssClass['text-align'] = $this->cssStyles['.' . $dataType]['text-align'];
}
}
} else {
Expand Down Expand Up @@ -1455,6 +1489,16 @@ private function generateRowWriteCell(
$htmlx .= $this->generateRowIncludeCharts($worksheet, $coordinate);
// Column start
$html .= ' <' . $cellType;
if ($this->betterBoolean) {
$dataType = $worksheet->getCell($coordinate)->getDataType();
if ($dataType === DataType::TYPE_BOOL) {
$html .= ' data-type="' . DataType::TYPE_BOOL . '"';
} elseif ($dataType === DataType::TYPE_FORMULA && is_bool($worksheet->getCell($coordinate)->getCalculatedValue())) {
$html .= ' data-type="' . DataType::TYPE_BOOL . '"';
} elseif (is_numeric($cellData) && $worksheet->getCell($coordinate)->getDataType() === DataType::TYPE_STRING) {
$html .= ' data-type="' . DataType::TYPE_STRING . '"';
}
}
if (!$this->useInlineCss && !$this->isPdf && is_string($cssClass)) {
$html .= ' class="' . $cssClass . '"';
if ($htmlx) {
Expand Down Expand Up @@ -1910,4 +1954,16 @@ private function shouldGenerateColumn(Worksheet $sheet, string $colStr): bool

return $sheet->getColumnDimension($colStr)->getVisible();
}

public function getBetterBoolean(): bool
{
return $this->betterBoolean;
}

public function setBetterBoolean(bool $betterBoolean): self
{
$this->betterBoolean = $betterBoolean;

return $this;
}
}
Loading

0 comments on commit e23c987

Please sign in to comment.