Skip to content

Commit cbf194c

Browse files
committed
WIP Allow Xlsx Reader/Writer to Process Font Charset
Fix #2760. Maybe. I have no real way of confirming. I am not sure why it might be needed, but a comment in the issue suggests that it helps. I have asked the submitter and another participant in the discussion to let me know if it helps before moving forward.
1 parent 44c3bd5 commit cbf194c

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,11 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
655655

656656
// add style to cellXf collection
657657
$objStyle = new Style();
658-
$this->styleReader->readStyle($objStyle, $style);
658+
$this->styleReader
659+
->readStyle($objStyle, $style);
660+
foreach ($this->styleReader->getFontCharsets() as $fontName => $charset) {
661+
$excel->addFontCharset($fontName, $charset);
662+
}
659663
if ($addingFirstCellXf) {
660664
$excel->removeCellXfByIndex(0); // remove the default style
661665
$addingFirstCellXf = false;

src/PhpSpreadsheet/Reader/Xlsx/Styles.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ class Styles extends BaseParserClass
3636

3737
private string $namespace = '';
3838

39+
/** @var array<string, int> */
40+
private array $fontCharsets = [];
41+
42+
/** @return array<string, int> */
43+
public function getFontCharsets(): array
44+
{
45+
return $this->fontCharsets;
46+
}
47+
3948
public function setNamespace(string $namespace): void
4049
{
4150
$this->namespace = $namespace;
@@ -85,6 +94,13 @@ public function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml):
8594
if (isset($attr['val'])) {
8695
$fontStyle->setName((string) $attr['val']);
8796
}
97+
if (isset($fontStyleXml->charset)) {
98+
$charsetAttr = $this->getStyleAttributes($fontStyleXml->charset);
99+
if (isset($charsetAttr['val'])) {
100+
$charsetVal = (int) $charsetAttr['val'];
101+
$this->fontCharsets[$fontStyle->getName()] = $charsetVal;
102+
}
103+
}
88104
}
89105
if (isset($fontStyleXml->sz)) {
90106
$attr = $this->getStyleAttributes($fontStyleXml->sz);

src/PhpSpreadsheet/Spreadsheet.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PhpOffice\PhpSpreadsheet\Document\Properties;
99
use PhpOffice\PhpSpreadsheet\Document\Security;
1010
use PhpOffice\PhpSpreadsheet\Shared\Date;
11+
use PhpOffice\PhpSpreadsheet\Shared\Font as SharedFont;
1112
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
1213
use PhpOffice\PhpSpreadsheet\Style\Style;
1314
use PhpOffice\PhpSpreadsheet\Worksheet\Iterator;
@@ -177,6 +178,31 @@ class Spreadsheet implements JsonSerializable
177178

178179
private ?IValueBinder $valueBinder = null;
179180

181+
/** @var array<string, int> */
182+
private array $fontCharsets = [
183+
'B Nazanin' => SharedFont::CHARSET_ANSI_ARABIC,
184+
];
185+
186+
public function addFontCharset(string $fontName, int $charset): void
187+
{
188+
$this->fontCharsets[$fontName] = $charset;
189+
}
190+
191+
public function getFontCharset(string $fontName): int
192+
{
193+
return $this->fontCharsets[$fontName] ?? -1;
194+
}
195+
196+
/**
197+
* Return all fontCharsets.
198+
*
199+
* @return array<string, int>
200+
*/
201+
public function getFontCharsets(): array
202+
{
203+
return $this->fontCharsets;
204+
}
205+
180206
public function getTheme(): Theme
181207
{
182208
return $this->theme;

src/PhpSpreadsheet/Writer/Xlsx/Style.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function writeStyles(Spreadsheet $spreadsheet): string
5959
for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {
6060
$thisfont = $this->getParentWriter()->getFontHashTable()->getByIndex($i);
6161
if ($thisfont !== null) {
62-
$this->writeFont($objWriter, $thisfont);
62+
$this->writeFont($objWriter, $thisfont, $spreadsheet);
6363
}
6464
}
6565

@@ -145,7 +145,7 @@ public function writeStyles(Spreadsheet $spreadsheet): string
145145
/** @var ?Conditional */
146146
$thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i);
147147
if ($thisstyle !== null) {
148-
$this->writeCellStyleDxf($objWriter, $thisstyle->getStyle());
148+
$this->writeCellStyleDxf($objWriter, $thisstyle->getStyle(), $spreadsheet);
149149
}
150150
}
151151

@@ -284,7 +284,7 @@ private function startFont(XMLWriter $objWriter, bool &$fontStarted): void
284284
/**
285285
* Write Font.
286286
*/
287-
private function writeFont(XMLWriter $objWriter, Font $font): void
287+
private function writeFont(XMLWriter $objWriter, Font $font, Spreadsheet $spreadsheet): void
288288
{
289289
$fontStarted = false;
290290
// font
@@ -365,6 +365,12 @@ private function writeFont(XMLWriter $objWriter, Font $font): void
365365
$objWriter->startElement('name');
366366
$objWriter->writeAttribute('val', $font->getName());
367367
$objWriter->endElement();
368+
$charset = $spreadsheet->getFontCharset($font->getName());
369+
if ($charset >= 0 && $charset <= 255) {
370+
$objWriter->startElement('charset');
371+
$objWriter->writeAttribute('val', "$charset");
372+
$objWriter->endElement();
373+
}
368374
}
369375

370376
if (!empty($font->getScheme())) {
@@ -504,13 +510,13 @@ private function writeCellStyleXf(XMLWriter $objWriter, \PhpOffice\PhpSpreadshee
504510
/**
505511
* Write Cell Style Dxf.
506512
*/
507-
private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style): void
513+
private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style, Spreadsheet $spreadsheet): void
508514
{
509515
// dxf
510516
$objWriter->startElement('dxf');
511517

512518
// font
513-
$this->writeFont($objWriter, $style->getFont());
519+
$this->writeFont($objWriter, $style->getFont(), $spreadsheet);
514520

515521
// numFmt
516522
$this->writeNumFmt($objWriter, $style->getNumberFormat());

0 commit comments

Comments
 (0)