PHPSpreadsheet · Google Sheets API · Excel
Spreadsheets, driven by code.
Hands-on PHP tutorials for working with Excel and Google Sheets — read and
write .xlsx, convert files to JSON, stream downloads in the
browser, and insert images, formulas, and styling. Every guide ships with
code you can copy, run, and adapt.
Latest complete code
<?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // One workbook per region. In a real app this is whatever your query returns. $reports = [ 'north' => [ ['Rep', 'Units', 'Revenue'], ['Alice', 120, 4800], ['Bob', 90, 3600], ], 'south' => [ ['Rep', 'Units', 'Revenue'], ['Carol', 150, 6000], ['Dan', 70, 2800], ], 'east' => [ ['Rep', 'Units', 'Revenue'], ['Erin', 200, 8000], ], ]; // 1. A scratch directory used by this request and nobody else. $workDir = sys_get_temp_dir() . '/reports-' . bin2hex(random_bytes(8)); if (!mkdir($workDir) && !is_dir($workDir)) { exit('Could not create a working directory.'); } $zipPath = $workDir . '/reports.zip'; $zip = new ZipArchive(); if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { exit('Could not create the archive.'); } // 2. Build each workbook, save it, then add it to the archive. foreach ($reports as $region => $rows) { $spreadsheet = new Spreadsheet(); $worksheet = $spreadsheet->getActiveSheet(); $worksheet->setTitle(ucfirst($region)); $worksheet->fromArray($rows, null, 'A1'); $memberName = $region . '-sales.xlsx'; $filePath = $workDir . '/' . $memberName; (new Xlsx($spreadsheet))->save($filePath); // addFile() records a path, it does not copy the bytes yet. The file must // still exist when close() runs. $zip->addFile($filePath, $memberName); // Release the workbook before building the next one. $spreadsheet->disconnectWorksheets(); unset($spreadsheet, $worksheet); } // 3. close() is what actually writes the archive. Before this line reports.zip // is incomplete, so nothing may stream it yet. $zip->close(); // 4. Send it. The archive is a real file, so its size is known up front and the // browser can show a true progress bar. header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="reports.zip"'); header('Content-Length: ' . filesize($zipPath)); header('Cache-Control: max-age=0'); while (ob_get_level() > 0) { ob_end_clean(); } readfile($zipPath); // 5. Clean up. Nothing is left behind in the temp directory. foreach (glob($workDir . '/*') as $leftover) { unlink($leftover); } rmdir($workDir); exit;
The full script from Download Several Excel Files As One ZIP In PHP Using PHPSpreadSheet — copy, run, adapt.
Key methods
IOFactory::load()
PhpSpreadsheet
getActiveSheet()
PhpSpreadsheet
fromArray()
PhpSpreadsheet
getCalculatedValue()
PhpSpreadsheet
save('php://output')
PhpSpreadsheet
spreadsheets_values->get()
Google Sheets
spreadsheets_values->update()
Google Sheets
spreadsheets->create()
Google Sheets
json_encode()
PHP
header()
PHP
Latest articles
Download Several Excel Files As One ZIP In PHP Using PHPSpreadSheet
August 9, 2026
Set Sheet View Options In Excel Files In PHP Using PHPSpreadSheet
August 8, 2026
Set The Worksheet Tab Color In Excel Files In PHP Using PHPSpreadSheet
August 8, 2026
Rotate Text In A Cell In Excel Files In PHP Using PHPSpreadSheet
August 8, 2026
Add Data Bars, Color Scales And Icon Sets In Excel Files In PHP Using PHPSpreadSheet
August 7, 2026
Sort Rows Before Writing An Excel File In PHP Using PHPSpreadSheet
August 7, 2026
Prevent Formula Injection In Excel Exports In PHP Using PHPSpreadSheet
August 7, 2026
Create An Excel Table In PHP Using PHPSpreadSheet
August 6, 2026
Use VLOOKUP In Excel Files In PHP Using PHPSpreadSheet
August 6, 2026
Browse by technique