-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Closed
Description
Description:
The PhpSpreadsheet Xls writer incorrectly uses 1-based
column indices when writing the BIFF8 DIMENSIONS record
(0x0200), causing an extra empty column to appear in the
generated XLS files. According to the [Microsoft BIFF8
specification](https://learn.microsoft.com/en-us/openspecs/
office_file_formats/ms-xls/5fd3837c-9f3d-4952-8a85-ad93ddb3
7ced), the DIMENSIONS record requires 0-based column
indices.
Root Cause:
In src/PhpSpreadsheet/Writer/Xls/Worksheet.php
, the
constructor calculates column indices using:
$maxC = $this->phpSheet->getHighestColumn();
$this->firstColumnIndex =
Coordinate::columnIndexFromString($minC);
$this->lastColumnIndex =
Coordinate::columnIndexFromString($maxC);
The problem is that Coordinate::columnIndexFromString()
returns 1-based indices (e.g., 'A' = 1, 'G' = 7), but the
BIFF8 DIMENSIONS record expects 0-based indices (e.g., 'A'
= 0, 'G' = 6).
Impact:
When converting XLS files to CSV or text format, an extra
empty column appears with a trailing comma/delimiter on
each row.
Steps to Reproduce:
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// Create 7 columns (A-G)
$sheet->setCellValue('A1', 'Column A');
$sheet->setCellValue('B1', 'Column B');
$sheet->setCellValue('C1', 'Column C');
$sheet->setCellValue('D1', 'Column D');
$sheet->setCellValue('E1', 'Column E');
$sheet->setCellValue('F1', 'Column F');
$sheet->setCellValue('G1', 'Column G');
$writer = new Xls($spreadsheet);
$writer->save('test.xls');
// Inspect DIMENSIONS record - shows colMic=1, colMac=8
(should be colMic=0, colMac=7)
Expected Behavior:
- For 7 columns (A-G), DIMENSIONS record should have:
colMic = 0, colMac = 7
- XLS file should contain exactly 7 columns when converted
to CSV/text
Actual Behavior:
- DIMENSIONS record has: colMic = 1, colMac = 8
- XLS file appears to have 8 columns, resulting in trailing
commas in CSV conversion
Specification Reference:
According to
https://learn.microsoft.com/en-us/openspecs/office_file_for
mats/ms-xls/5fd3837c-9f3d-4952-8a85-ad93ddb37ced:
colMic: A ColU structure that specifies the first column in
the sheet that contains a used cell.
colMac: An unsigned integer that specifies the zero-based
index of the column after the last column in the sheet that
contains a used cell.
Proposed Fix:
In src/PhpSpreadsheet/Writer/Xls/Worksheet.php, convert the
column indices to 0-based:
$maxC = $this->phpSheet->getHighestColumn();
$this->firstColumnIndex =
Coordinate::columnIndexFromString($minC) - 1;
$this->lastColumnIndex =
Coordinate::columnIndexFromString($maxC) - 1;
Environment:
- PhpSpreadsheet version: latest
- PHP version: 8.3
- Operating System: Windows
Workaround:
Binary post-processing of the XLS file to correct the
DIMENSIONS record after generation.
Metadata
Metadata
Assignees
Labels
No labels