Xlsx Reader Better Namespace Handling Phase 1 Second Bugfix (#2303)

* Xlsx Reader Better Namespace Handling Phase 1 Second Bugfix

See issue #2301. The main problem in that issue had been introduced with 18.0 and had already ben fixed in master. However there was a subsequent problem that had been introduced in master, an undotted i uncrossed t with namespace handling. When using namespaces, need to call attributes() to access the attributes before trying to access them directly. Failure to do so in parseRichText caused fonts declared in Rich Text elements to be ignored.

* Add An Assertion

Addresses problem in 2301 that had already been fixed.
This commit is contained in:
oleibman 2021-09-27 16:59:45 -07:00 committed by GitHub
parent f2cd62a9ef
commit 90b9decb8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 32 deletions

View File

@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Phase 1 of better namespace handling for Xlsx, resolving many open issues.
[PR #2173](https://github.com/PHPOffice/PhpSpreadsheet/pull/2173)
[PR #2204](https://github.com/PHPOffice/PhpSpreadsheet/pull/2204)
[PR #2303](https://github.com/PHPOffice/PhpSpreadsheet/pull/2303)
- Add ability to extract images if source is a URL. [Issue #1997](https://github.com/PHPOffice/PhpSpreadsheet/issues/1997) [PR #2072](https://github.com/PHPOffice/PhpSpreadsheet/pull/2072)
- Support for passing flags in the Reader `load()` and Writer `save()`methods, and through the IOFactory, to set behaviours. [PR #2136](https://github.com/PHPOffice/PhpSpreadsheet/pull/2136)
- See [documentation](https://phpspreadsheet.readthedocs.io/en/latest/topics/reading-and-writing-to-file/) for details

View File

@ -1675,46 +1675,63 @@ class Xlsx extends BaseReader
} else {
$objText = $value->createTextRun(StringHelper::controlCharacterOOXML2PHP((string) $run->t));
if (isset($run->rPr->rFont['val'])) {
$objText->getFont()->setName((string) $run->rPr->rFont['val']);
$attr = $run->rPr->rFont->attributes();
if (isset($attr['val'])) {
$objText->getFont()->setName((string) $attr['val']);
}
if (isset($run->rPr->sz['val'])) {
$objText->getFont()->setSize((float) $run->rPr->sz['val']);
$attr = $run->rPr->sz->attributes();
if (isset($attr['val'])) {
$objText->getFont()->setSize((float) $attr['val']);
}
if (isset($run->rPr->color)) {
$objText->getFont()->setColor(new Color(Styles::readColor($run->rPr->color)));
}
if (
(isset($run->rPr->b['val']) && self::boolean((string) $run->rPr->b['val'])) ||
(isset($run->rPr->b) && !isset($run->rPr->b['val']))
) {
$objText->getFont()->setBold(true);
}
if (
(isset($run->rPr->i['val']) && self::boolean((string) $run->rPr->i['val'])) ||
(isset($run->rPr->i) && !isset($run->rPr->i['val']))
) {
$objText->getFont()->setItalic(true);
}
if (isset($run->rPr->vertAlign, $run->rPr->vertAlign['val'])) {
$vertAlign = strtolower((string) $run->rPr->vertAlign['val']);
if ($vertAlign == 'superscript') {
$objText->getFont()->setSuperscript(true);
}
if ($vertAlign == 'subscript') {
$objText->getFont()->setSubscript(true);
if (isset($run->rPr->b)) {
$attr = $run->rPr->b->attributes();
if (
(isset($attr['val']) && self::boolean((string) $attr['val'])) ||
(!isset($attr['val']))
) {
$objText->getFont()->setBold(true);
}
}
if (isset($run->rPr->u) && !isset($run->rPr->u['val'])) {
$objText->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE);
} elseif (isset($run->rPr->u, $run->rPr->u['val'])) {
$objText->getFont()->setUnderline((string) $run->rPr->u['val']);
if (isset($run->rPr->i)) {
$attr = $run->rPr->i->attributes();
if (
(isset($attr['val']) && self::boolean((string) $attr['val'])) ||
(!isset($attr['val']))
) {
$objText->getFont()->setItalic(true);
}
}
if (
(isset($run->rPr->strike['val']) && self::boolean((string) $run->rPr->strike['val'])) ||
(isset($run->rPr->strike) && !isset($run->rPr->strike['val']))
) {
$objText->getFont()->setStrikethrough(true);
if (isset($run->rPr->vertAlign)) {
$attr = $run->rPr->vertAlign->attributes();
if (isset($attr['val'])) {
$vertAlign = strtolower((string) $attr['val']);
if ($vertAlign == 'superscript') {
$objText->getFont()->setSuperscript(true);
}
if ($vertAlign == 'subscript') {
$objText->getFont()->setSubscript(true);
}
}
}
if (isset($run->rPr->u)) {
$attr = $run->rPr->u->attributes();
if (!isset($attr['val'])) {
$objText->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE);
} else {
$objText->getFont()->setUnderline((string) $attr['val']);
}
}
if (isset($run->rPr->strike)) {
$attr = $run->rPr->strike->attributes();
if (
(isset($attr['val']) && self::boolean((string) $attr['val'])) ||
(!isset($attr['val']))
) {
$objText->getFont()->setStrikethrough(true);
}
}
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
class Issue2301Test extends \PHPUnit\Framework\TestCase
{
/**
* @var string
*/
private static $testbook = 'tests/data/Reader/XLSX/issue.2301.xlsx';
public static function testReadRichText(): void
{
$spreadsheet = IOFactory::load(self::$testbook);
$sheet = $spreadsheet->getActiveSheet();
$value = $sheet->getCell('B45')->getValue();
self::assertInstanceOf(RichText::class, $value);
$richtext = $value->getRichTextElements();
$font = $richtext[1]->getFont();
self::assertNotNull($font);
self::assertSame('Arial CE', $font->getName());
self::assertSame(9.0, $font->getSize());
self::assertSame('protected', $sheet->getCell('BT10')->getStyle()->getProtection()->getHidden());
}
}

Binary file not shown.