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
- Give each table a unique generated name before attaching, e.g. $table->setName(sprintf('Table%d', ++$i))
- Scan the workbook first (getWorksheetIterator + getTableCollection) and rename or remove the colliding table
- 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
- Generate table names with a counter or uuid suffix instead of constants
- Centralize table creation in one helper that guarantees name uniqueness
- When copying sheets, rename cloned tables before attaching them
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
- Workbook already contains a worksheet named '{$worksheet->ge
- Workbook already contains a worksheet named '{$worksheet->ge
- No table range is defined.
- Column is outside of current table range.
- Column is not within the table range.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/5b945db49b585f64.
Report an issue: GitHub.