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);
+ }
+ }
+}