Documentation Index
Fetch the complete documentation index at: https://mintlify.com/PHPOffice/PhpSpreadsheet/llms.txt
Use this file to discover all available pages before exploring further.
Overview
PhpSpreadsheet provides writers for various output formats. Each writer implements the IWriter interface and supports different features and options.
Writer Comparison
| Format | Class | Charts | Formulas | Pre-calc | Formatting | Images |
|---|
| Xlsx | Writer\Xlsx | ✓ | ✓ | ✓ | Full | ✓ |
| Xls | Writer\Xls | - | ✓ | - | Limited | ✓ |
| Ods | Writer\Ods | - | ✓ | ✓ | Good | ✓ |
| Csv | Writer\Csv | - | ✓ | ✓ | None | - |
| Html | Writer\Html | ✓ | ✓ | ✓ | CSS | ✓ |
| Pdf | Writer\Pdf\* | ✓ | ✓ | ✓ | CSS | ✓ |
Xlsx Writer
Format: Office Open XML Spreadsheet (.xlsx)
Class: PhpOffice\PhpSpreadsheet\Writer\Xlsx
The primary writer for modern Excel files with full feature support.
Basic Usage
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$writer = new Xlsx($spreadsheet);
$writer->save('output.xlsx');
Features
- Complete formatting preservation
- Formulas
- Charts (when enabled)
- Data validation
- Conditional formatting
- Images and drawings
- Hyperlinks
- Page setup
- Multiple worksheets
- Named ranges
- Cell comments
- Merged cells
Xlsx Options
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$writer = new Xlsx($spreadsheet);
// Disable formula pre-calculation
$writer->setPreCalculateFormulas(false);
// Include charts
$writer->setIncludeCharts(true);
// Office 2003 compatibility mode
$writer->setOffice2003Compatibility(true);
// Restrict column widths to Excel UI limit (255)
$writer->setRestrictMaxColumnWidth(true);
// Enable disk caching for large files
$writer->setUseDiskCaching(true, '/tmp/cache');
$writer->save('output.xlsx');
// Since PhpSpreadsheet 4.0.0, control force full calculation
$writer = new Xlsx($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->setForceFullCalc(false); // Default is false
$writer->save('output.xlsx');
Prior to version 4.0.0, disabling pre-calculation could cause Excel to not auto-recalculate formulas. The setForceFullCalc(false) setting (now the default) prevents this issue.
Xls Writer
Format: Excel Binary File Format (.xls)
Class: PhpOffice\PhpSpreadsheet\Writer\Xls
Writes legacy Excel files for compatibility with Excel 97-2003.
Basic Usage
use PhpOffice\PhpSpreadsheet\Writer\Xls;
$writer = new Xls($spreadsheet);
$writer->save('output.xls');
Features
- Cell data and formulas
- Basic formatting (fonts, colors, borders)
- Multiple worksheets
- Named ranges
- Images
Limitations
The Xls (BIFF) format has significant limitations:
- Maximum 65,536 rows (65K limit)
- Maximum 256 columns
- Limited styling options
- No chart support
- File size limitations
- Large spreadsheets may have performance issues
When to Use Xls
Only use Xls format when:
- Compatibility with Excel 97-2003 is required
- Target users don’t have Excel 2007 or later
- Working with legacy systems
Otherwise, use Xlsx format for better features and performance.
Ods Writer
Format: OpenDocument Spreadsheet (.ods)
Class: PhpOffice\PhpSpreadsheet\Writer\Ods
Writes OpenOffice and LibreOffice Calc compatible files.
Basic Usage
use PhpOffice\PhpSpreadsheet\Writer\Ods;
$writer = new Ods($spreadsheet);
$writer->save('output.ods');
Ods Options
$writer = new Ods($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save('output.ods');
Csv Writer
Format: Comma Separated Values (.csv)
Class: PhpOffice\PhpSpreadsheet\Writer\Csv
Writes plain text CSV files. No formatting is preserved.
Basic Usage
use PhpOffice\PhpSpreadsheet\Writer\Csv;
$writer = new Csv($spreadsheet);
$writer->save('output.csv');
CSV Options
$writer = new Csv($spreadsheet);
// Set delimiter
$writer->setDelimiter(';');
// Set enclosure
$writer->setEnclosure('"');
// Control enclosure usage
$writer->setEnclosureRequired(false); // Only when necessary
// Set line ending
$writer->setLineEnding("\r\n");
// Set which sheet to export
$writer->setSheetIndex(0);
// Disable formula pre-calculation
$writer->setPreCalculateFormulas(false);
$writer->save('output.csv');
UTF-8 with BOM
Add BOM for Excel compatibility:
$writer = new Csv($spreadsheet);
$writer->setUseBOM(true);
$writer->save('output.csv');
Use BOM when the CSV contains non-ASCII characters or starts with “ID” to ensure Excel opens it correctly.
Output Encoding
$writer = new Csv($spreadsheet);
$writer->setUseBOM(false);
$writer->setOutputEncoding('SJIS-WIN'); // Japanese Shift-JIS
$writer->save('output.csv');
Variable Columns
Allow different column counts per row:
$writer = new Csv($spreadsheet);
$writer->setVariableColumns(true);
$writer->save('output.csv');
Html Writer
Format: HTML (.html, .htm)
Class: PhpOffice\PhpSpreadsheet\Writer\Html
Generates HTML tables with CSS styling.
Basic Usage
use PhpOffice\PhpSpreadsheet\Writer\Html;
$writer = new Html($spreadsheet);
$writer->save('output.html');
By default, only the first worksheet is exported.
Html Options
$writer = new Html($spreadsheet);
// Write all worksheets
$writer->writeAllSheets();
// Or write specific sheet
$writer->setSheetIndex(2);
// Set images root URL
$writer->setImagesRoot('https://example.com/images/');
// Disable formula pre-calculation
$writer->setPreCalculateFormulas(false);
// Include charts
$writer->setIncludeCharts(true);
$writer->save('output.html');
Generate HTML Parts
Generate specific sections for embedding:
$writer = new Html($spreadsheet);
// Get individual parts
$header = $writer->generateHTMLHeader();
$styles = $writer->generateStyles(false); // false = no <style> tags
$sheetData = $writer->generateSheetData();
$footer = $writer->generateHTMLFooter();
// Build custom HTML
echo $header;
echo '<style type="text/css">' . $styles . '</style>';
echo '<div class="spreadsheet-container">';
echo $sheetData;
echo '</div>';
echo $footer;
Edit HTML Callback
Modify generated HTML before saving:
function customizeHtml(string $html): string
{
// Change border style
$html = str_replace(
'{border: 1px solid black;}',
'{border: 2px dashed red;}',
$html
);
// Add custom class
$html = str_replace('<table', '<table class="data-table"', $html);
return $html;
}
$writer = new Html($spreadsheet);
$writer->setEditHtmlCallback('customizeHtml');
$writer->save('output.html');
Embedding in Web Pages
Generate only the sheet data for embedding:
$writer = new Html($spreadsheet);
// In your web page
echo '<div class="spreadsheet">';
echo $writer->generateSheetData();
echo '</div>';
// Include styles in your CSS
echo '<style>' . $writer->generateStyles(false) . '</style>';
Common Writer Methods
All writers implement these methods from IWriter:
// Pre-calculate formulas
$writer->setPreCalculateFormulas(true);
$isPreCalc = $writer->getPreCalculateFormulas();
// Include charts
$writer->setIncludeCharts(true);
$includeCharts = $writer->getIncludeCharts();
// Disk caching
$writer->setUseDiskCaching(true, '/tmp/cache');
$useDiskCache = $writer->getUseDiskCaching();
$cacheDir = $writer->getDiskCachingDirectory();
// Save
$writer->save('output.xlsx');
$writer->save('output.xlsx', $flags);
Using Flags
Writers support flags for common options:
use PhpOffice\PhpSpreadsheet\Writer\IWriter;
// Single flag
$writer->save('output.xlsx', IWriter::SAVE_WITH_CHARTS);
// Multiple flags
$writer->save(
'output.xlsx',
IWriter::SAVE_WITH_CHARTS | IWriter::DISABLE_PRECALCULATE_FORMULAE
);
For CSV, HTML, and PDF exports, control number formatting:
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
// English format: 1,234.56
StringHelper::setDecimalSeparator('.');
StringHelper::setThousandsSeparator(',');
// German format: 1.234,56
StringHelper::setDecimalSeparator(',');
StringHelper::setThousandsSeparator('.');
// French format: 1 234,56
StringHelper::setDecimalSeparator(',');
StringHelper::setThousandsSeparator(' ');
$writer = new Csv($spreadsheet);
$writer->save('output.csv');
These are global settings that affect all CSV, HTML, and PDF writers.
Streaming Output
Direct to Browser
// Excel (Xlsx)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="report.xlsx"');
header('Cache-Control: max-age=0');
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
exit;
// CSV
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename="data.csv"');
$writer = new Csv($spreadsheet);
$writer->save('php://output');
exit;
// HTML
header('Content-Type: text/html; charset=utf-8');
$writer = new Html($spreadsheet);
$writer->save('php://output');
exit;
Capture to Variable
ob_start();
$writer->save('php://output');
$content = ob_get_contents();
ob_end_clean();
// $content now contains the file data
file_put_contents('/path/to/file.xlsx', $content);
Registering Custom Writers
Register your own writer implementation:
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\IWriter;
class MyCustomWriter implements IWriter
{
// Implement IWriter interface
}
IOFactory::registerWriter('Custom', MyCustomWriter::class);
$writer = IOFactory::createWriter($spreadsheet, 'Custom');
$writer->save('output.custom');
Large Files
For large spreadsheets:
$writer = new Xlsx($spreadsheet);
// Disable pre-calculation
$writer->setPreCalculateFormulas(false);
// Use disk caching
$writer->setUseDiskCaching(true, sys_get_temp_dir());
// Don't include charts if not needed
$writer->setIncludeCharts(false);
$writer->save('large-file.xlsx');
Memory Management
// After saving
$writer->save('output.xlsx');
// Free memory
$spreadsheet->disconnectWorksheets();
unset($spreadsheet, $writer);
gc_collect_cycles();
Best Practices
Format Selection
- Xlsx - Use for modern Excel with all features
- Xls - Only for legacy Excel 97-2003 compatibility
- Csv - Simple data exchange, no formatting
- Html - Web display and email
- Pdf - Read-only distribution (see PDF Export page)
- Ods - OpenOffice/LibreOffice compatibility
Performance
- Disable formula pre-calculation for large files
- Use disk caching for files > 50MB
- Only include charts when necessary
- Write CSV for fastest output
Compatibility
- Test output files in target applications
- Use BOM for CSV with special characters
- Consider Office 2003 compatibility if needed
- Verify number formats for international users