PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception

Rows or columns overflow! Excel5 has limit to 65535 rows and

Error message

Rows or columns overflow! Excel5 has limit to 65535 rows and 255 columns. Use XLSX instead.

What it means

The legacy Xls (BIFF8) binary format supports at most 65,536 rows and 256 columns per worksheet. During save, the Xls writer iterates the sheet's sorted cell coordinates and throws as soon as one cell has a row number above 65536 or a column beyond 'IV' (the checks are 0-based: row index > 65535, column index > 255). Only cells that actually exist are checked - empty rows/columns beyond the data never trigger it.

Source

Thrown at src/PhpSpreadsheet/Writer/Xls/Worksheet.php:364

            $this->writeRow(
                $rowDimension->getRowIndex() - 1,
                (int) $rowDimension->getRowHeight(),
                $xfIndex,
                !$rowDimension->getVisible(),
                $rowDimension->getOutlineLevel()
            );
        }

        // Write Cells
        foreach ($phpSheet->getCellCollection()->getSortedCoordinates() as $coordinate) {
            /** @var Cell $cell */
            $cell = $phpSheet->getCellCollection()->get($coordinate);
            $row = $cell->getRow() - 1;
            $column = Coordinate::columnIndexFromString($cell->getColumn()) - 1;

            // Don't break Excel break the code!
            if ($row > 65535 || $column > 255) {
                throw new WriterException('Rows or columns overflow! Excel5 has limit to 65535 rows and 255 columns. Use XLSX instead.');
            }

            // Write cell value
            $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs

            $cVal = $cell->getValue();
            if ($cVal instanceof RichText && (string) $cVal === '') {
                $cVal = '';
            }
            if ($cVal instanceof RichText) {
                $arrcRun = [];
                $str_pos = 0;
                $elements = $cVal->getRichTextElements();
                foreach ($elements as $element) {
                    // FONT Index
                    $str_fontidx = 0;
                    if ($element instanceof Run) {
                        $getFont = $element->getFont();

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Use the Xlsx or Csv writer instead of Xls when data exceeds the limit (as the message itself suggests)
  2. Split the dataset across multiple worksheets, each within 65,536 rows x 256 columns
  3. Trim the data: remove out-of-range cells or apply a write filter before save
  4. Fix runaway loops that accidentally write to coordinates outside the intended range

Example fix

// before
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);
$writer->save('out.xls');

// after
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('out.xlsx');
Defensive patterns

Strategy: validation

Validate before calling

const XLS_MAX_ROW = 65536, XLS_MAX_COL = 256; // BIFF8 limits

foreach ($spreadsheet->getAllSheets() as $sheet) {
    [$col, $row] = Coordinate::coordinateFromString($sheet->getHighestColumn() . '1');
    $maxRow = (int) $sheet->getHighestRow();
    $maxCol = Coordinate::columnIndexFromString($sheet->getHighestColumn());
    if ($maxRow > XLS_MAX_ROW || $maxCol > XLS_MAX_COL) {
        throw new RangeException(sprintf(
            "Sheet '%s' is %dx%d; Xls supports %dx%d. Use the Xlsx writer.",
            $sheet->getTitle(), $maxCol, $maxRow, XLS_MAX_COL, XLS_MAX_ROW
        ));
    }
}

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);

Try / catch

try {
    $writer->save('out.xls');
} catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
    if (str_contains($e->getMessage(), 'Rows or columns overflow')) {
        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); // fallback format
        $writer->save('out.xlsx');
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Any cell at row 65537+ or column 'IW'+ in any worksheet, then ->save('out.xls'); typically after importing a large Xlsx/CSV (Xlsx allows 1,048,576 rows) or generating a big report into a workbook exported as Xls.

Common situations: Migrating an export from Xlsx to Xls because a downstream legacy system requires .xls; large CSV imports saved back out as Xls; loop bugs (e.g. transposed row/column variables) writing stray cells at extreme coordinates.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/ed4e93bf806b443c. Report an issue: GitHub.