PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Workbook already contains a table named '{$this->name}'

Error message

Workbook already contains a table named '{$this->name}'

What it means

Thrown by Table::setWorksheet() (reached via Worksheet::addTable()) when the table's name, compared case-insensitively with StringHelper::strToUpper, already exists in the table collection of any worksheet in the parent workbook. Excel requires table names to be unique across the whole workbook, so PhpSpreadsheet enforces workbook-wide uniqueness at the moment the table is attached. The check only runs when the name is non-empty and the target worksheet is non-null.

Source

Thrown at src/PhpSpreadsheet/Worksheet/Table.php:350

     */
    public function getWorksheet(): ?Worksheet
    {
        return $this->workSheet;
    }

    /**
     * Set Table's Worksheet.
     */
    public function setWorksheet(?Worksheet $worksheet = null): self
    {
        if ($this->name !== '' && $worksheet !== null) {
            $spreadsheet = $worksheet->getParentOrThrow();
            $tableName = StringHelper::strToUpper($this->name);

            foreach ($spreadsheet->getWorksheetIterator() as $sheet) {
                foreach ($sheet->getTableCollection() as $table) {
                    if (StringHelper::strToUpper($table->getName()) === $tableName) {
                        throw new PhpSpreadsheetException("Workbook already contains a table named '{$this->name}'");
                    }
                }
            }
        }

        $this->workSheet = $worksheet;
        $this->autoFilter->setParent($worksheet);

        return $this;
    }

    /**
     * Get all Table Columns.
     *
     * @return Table\Column[]
     */
    public function getColumns(): array
    {

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Give each table a unique generated name before attaching, e.g. $table->setName(sprintf('Table%d', ++$i))
  2. Scan the workbook first (getWorksheetIterator + getTableCollection) and rename or remove the colliding table
  3. Never call addTable()/setWorksheet() twice for the same name; reuse the existing Table object or unset it from the source sheet first

Example fix

// before
foreach ($dataSheets as $i => $sheet) {
    $table = new Table('A1:E10');
    $table->setName('SalesTable');
    $sheet->addTable($table); // throws on 2nd iteration
}

// after
foreach ($dataSheets as $i => $sheet) {
    $table = new Table('A1:E10');
    $table->setName('SalesTable' . ($i + 1));
    $sheet->addTable($table);
}
Defensive patterns

Strategy: validation

Validate before calling

function tableExists(Spreadsheet $spreadsheet, string $name): bool
{
    $name = StringHelper::strToUpper($name); // or mb_strtoupper($name)
    foreach ($spreadsheet->getWorksheetIterator() as $sheet) {
        foreach ($sheet->getTableCollection() as $table) {
            if (mb_strtoupper($table->getName()) === $name) {
                return true;
            }
        }
    }

    return false;
}

if (!tableExists($spreadsheet, $newName)) {
    $sheet->addTable($table);
}

Try / catch

try {
    $sheet->addTable($table);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    if (str_contains($e->getMessage(), 'Workbook already contains a table')) {
        $table->setName($table->getName() . '_' . uniqid());
        $sheet->addTable($table);
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling $worksheet->addTable($table) or $table->setWorksheet($sheet) while any sheet in $worksheet->getParentOrThrow() already has a table with the same name; re-adding a cloned table to another sheet without renaming it; matching names with different case such as 'Sales' vs 'SALES'.

Common situations: Creating tables in a loop with a hardcoded name like 'Table1'; loading an existing xlsx that already contains a table and appending another with the same name; copying worksheets that carry tables. Often appears right after a refactor that moved addTable() inside a loop.

Related errors


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