mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-22 08:09:15 +00:00
d46b7b3e9d
Fix #3918, sort of. Xlsx cells use the default style when they omit the `s` tag, or when `s="0"` is specified. LibreOffice does not honor Alignment in the default Style unless the cell explicitly uses the second form, even though it honors other default Styles (e.g. bold font) when `s` is omitted. Gnumeric seems to have the same problem. A bug report has been filed with LibreOffice. In the meantime, this PR adds to Xlsx Writer an optional boolean property `explicitStyle0` with setter and getter. Default is false, which will continue the current behavior by adding an `s` tag only when the cell uses a non-default style (this is how Excel itself behaves). When set to true, Xlsx Writer will explicity write `s="0"` for all cells using default style. This will allow users to create an Xlsx spreadsheet with default alignment of cells that will show up correctly when the spreadsheet is viewed with LibreOffice. Technically speaking, it is *probably* safe to always use `true`, except that the spreadsheet size will be a bit larger. However, my hope is that this is a temporary measure which can go away when the vendors have had a chance to fix their problems, hence the `false` default.
107 lines
4.3 KiB
PHP
107 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
|
use PhpOffice\PhpSpreadsheet\Shared\File;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class ExplicitStyle0Test extends TestCase
|
|
{
|
|
private string $outputFile = '';
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
if ($this->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('<c r="A1" t="s"><v>0</v></c>', $data, 'no s attribute in c tag');
|
|
self::assertStringContainsString('<c r="A2" s="1" t="s"><v>1</v></c>', $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('<c r="A1" s="0" t="s"><v>0</v></c>', $data, 'has s attribute in c tag');
|
|
self::assertStringContainsString('<c r="A2" s="1" t="s"><v>1</v></c>', $data);
|
|
}
|
|
}
|
|
}
|