diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php index 4a81ab861..26c185e1f 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/src/PhpSpreadsheet/Writer/Xlsx.php @@ -134,6 +134,8 @@ class Xlsx extends BaseWriter private Worksheet $writerPartWorksheet; + private bool $explicitStyle0 = false; + /** * Create a new Xlsx Writer. */ @@ -699,4 +701,21 @@ class Xlsx extends BaseWriter return $data; } + + public function getExplicitStyle0(): bool + { + return $this->explicitStyle0; + } + + /** + * This may be useful if non-default Alignment is part of default style + * and you think you might want to open the spreadsheet + * with LibreOffice or Gnumeric. + */ + public function setExplicitStyle0(bool $explicitStyle0): self + { + $this->explicitStyle0 = $explicitStyle0; + + return $this; + } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 49d1ef67f..a14ff2812 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -28,6 +28,8 @@ class Worksheet extends WriterPart private string $evalError = ''; + private bool $explicitStyle0; + /** * Write worksheet to XML format. * @@ -38,6 +40,7 @@ class Worksheet extends WriterPart */ public function writeWorksheet(PhpspreadsheetWorksheet $worksheet, array $stringTable = [], bool $includeCharts = false): string { + $this->explicitStyle0 = $this->getParentWriter()->getExplicitStyle0(); $this->numberStoredAsText = ''; $this->formula = ''; $this->twoDigitTextYear = ''; @@ -1441,7 +1444,11 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('r', $cellAddress); // Sheet styles - self::writeAttributeIf($objWriter, (bool) $xfi, 's', "$xfi"); + if ($xfi) { + $objWriter->writeAttribute('s', "$xfi"); + } elseif ($this->explicitStyle0) { + $objWriter->writeAttribute('s', '0'); + } // If cell value is supplied, write cell value if ($writeValue) { diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/ExplicitStyle0Test.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/ExplicitStyle0Test.php new file mode 100644 index 000000000..57312dfba --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/ExplicitStyle0Test.php @@ -0,0 +1,106 @@ +outputFile !== '') { + unlink($this->outputFile); + $this->outputFile = ''; + } + } + + public function testWithoutExplicitStyle0(): void + { + $spreadsheet = new Spreadsheet(); + $defaultStyle = $spreadsheet->getDefaultStyle(); + $defaultStyle->getFont()->setBold(true); + $defaultStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->getCell('A1')->setValue('bold'); + $sheet->getCell('A2')->setValue('italic'); + $sheet->getStyle('A2')->getFont()->setItalic(true); + $writer = new XlsxWriter($spreadsheet); + $this->outputFile = File::temporaryFilename(); + $writer->save($this->outputFile); + $spreadsheet->disconnectWorksheets(); + + $reader = new XlsxReader(); + $spreadsheet2 = $reader->load($this->outputFile); + $sheet2 = $spreadsheet2->getActiveSheet(); + $styleA1 = $sheet2->getStyle('A1'); + self::assertTrue($styleA1->getFont()->getBold()); + self::assertFalse($styleA1->getFont()->getItalic()); + self::assertSame(Alignment::HORIZONTAL_CENTER, $styleA1->getAlignment()->getHorizontal()); + $styleA2 = $sheet2->getStyle('A2'); + self::assertTrue($styleA1->getFont()->getBold()); + self::assertTrue($styleA1->getFont()->getItalic()); + self::assertSame(Alignment::HORIZONTAL_CENTER, $styleA1->getAlignment()->getHorizontal()); + $spreadsheet2->disconnectWorksheets(); + + $file = 'zip://'; + $file .= $this->outputFile; + $file .= '#xl/worksheets/sheet1.xml'; + $data = file_get_contents($file); + if ($data === false) { + self::fail('Unable to read file'); + } else { + self::assertStringContainsString('0', $data, 'no s attribute in c tag'); + self::assertStringContainsString('1', $data); + } + } + + public function testWithExplicitStyle0(): void + { + $spreadsheet = new Spreadsheet(); + $defaultStyle = $spreadsheet->getDefaultStyle(); + $defaultStyle->getFont()->setBold(true); + $defaultStyle->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->getCell('A1')->setValue('bold'); + $sheet->getCell('A2')->setValue('italic'); + $sheet->getStyle('A2')->getFont()->setItalic(true); + $writer = new XlsxWriter($spreadsheet); + $writer->setExplicitStyle0(true); + $this->outputFile = File::temporaryFilename(); + $writer->save($this->outputFile); + $spreadsheet->disconnectWorksheets(); + + $reader = new XlsxReader(); + $spreadsheet2 = $reader->load($this->outputFile); + $sheet2 = $spreadsheet2->getActiveSheet(); + $styleA1 = $sheet2->getStyle('A1'); + self::assertTrue($styleA1->getFont()->getBold()); + self::assertFalse($styleA1->getFont()->getItalic()); + self::assertSame(Alignment::HORIZONTAL_CENTER, $styleA1->getAlignment()->getHorizontal()); + $styleA2 = $sheet2->getStyle('A2'); + self::assertTrue($styleA1->getFont()->getBold()); + self::assertTrue($styleA1->getFont()->getItalic()); + self::assertSame(Alignment::HORIZONTAL_CENTER, $styleA1->getAlignment()->getHorizontal()); + $spreadsheet2->disconnectWorksheets(); + + $file = 'zip://'; + $file .= $this->outputFile; + $file .= '#xl/worksheets/sheet1.xml'; + $data = file_get_contents($file); + if ($data === false) { + self::fail('Unable to read file'); + } else { + self::assertStringContainsString('0', $data, 'has s attribute in c tag'); + self::assertStringContainsString('1', $data); + } + } +}