在PHP中处理Excel表格,最成熟高效的方案是使用PhpSpreadsheet库,它支持读取、生成和样式设置,并兼容.xlsx和.xls格式。
为什么选择PhpSpreadsheet处理Excel表格
在PHP生态中,Excel处理库经历了几次迭代,早期开发者常用PHPExcel,但自2015年起官方已停止维护,PhpSpreadsheet作为其继承者,由PHPOffice团队维护,是目前社区最活跃的Excel处理工具。
与PHPExcel的核心差异
- 性能优化:PhpSpreadsheet采用更高效的内存管理,处理大文件时资源占用更低。
- 命名空间规范化:遵循PSR-4标准,更易于集成到现代PHP项目。
- 持续更新:每月发布新版本,修复漏洞并添加新功能,如支持最新Excel 2019格式。
其他可选方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| PhpSpreadsheet | 多数场景 | 功能全面,社区活跃 | 学习曲线稍高 |
| SimpleXLSX | 仅读取 | 轻量快速 | 不支持写入 |
| 原生CSV | 简单数据交换 | 无需库 | 不支持样式和公式 |
据开源社区统计,PhpSpreadsheet在GitHub上的星标数已超过1万,是处理Excel表格的首选库,业内专家指出,PhpSpreadsheet在架构设计上更符合现代PHP标准,建议新项目直接使用。
php读取excel表格的两种主流方法
当需要从Excel文件中提取数据时,PhpSpreadsheet提供了清晰的API,我们以读取.xlsx文件为例。
逐行读取数据
require 'vendor/autoload.php'; use PhpOfficePhpSpreadsheetIOFactory; $spreadsheet = IOFactory::load('example.xlsx'); $worksheet = $spreadsheet->getActiveSheet(); $rows = $worksheet->toArray(); // 返回二维数组
- 适用于数据量较小的文件,直接转换为数组。
- 可指定起始行和列,避免多余空白行。
读取特定单元格或区域
$highestRow = $worksheet->getHighestRow();
$highestColumn = $worksheet->getHighestColumn();
for ($row = 1; $row <= $highestRow; $row++) {
$value = $worksheet->getCell($row . 'A')->getValue();
// 处理每一行第一列
}
- 更适合需要逐行处理逻辑的场景,如数据验证或转换。
处理大文件的内存优化
当Excel文件超过10MB时,建议启用读取过滤器,PhpSpreadsheet支持ChunkReadFilter,分块读取数据,避免内存溢出。
$reader = IOFactory::createReader('Xlsx');
$reader->setReadDataOnly(true);
$reader->setReadFilter(new ChunkReadFilter(1, 100)); // 每次读取100行
读取多个工作表
$worksheetNames = $spreadsheet->getSheetNames();
foreach ($worksheetNames as $sheetName) {
$worksheet = $spreadsheet->getSheetByName($sheetName);
// 处理每个工作表
}
处理日期格式
Excel中的日期存储为序列号,需要转换成PHP时间戳才能使用。
$dateValue = $worksheet->getCell('A1')->getValue();
$timestamp = PhpOfficePhpSpreadsheetSharedDate::excelToTimestamp($dateValue);
echo date('Y-m-d', $timestamp);
php生成excel表格的完整操作指南
生成Excel表格是后台系统常见的需求,例如导出订单报表、用户列表等,PhpSpreadsheet可以轻松创建包含样式、公式和图表的工作表。
创建一个简单的工作表
$spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', 'Hello'); $sheet->setCellValue('B1', 'World');
设置单元格样式
- 字体加粗、颜色、大小:
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14); - 背景色填充:
$sheet->getStyle('A1')->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB('FF0000'); - 边框设置:
$sheet->getStyle('A1:B1')->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN);
写入数据并导出为文件
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="report.xlsx"');
$writer->save('php://output');
- 注意:在输出前确保没有其他输出(如echo、var_dump)。
常见场景:php excel表格导出时设置列宽
$sheet->getColumnDimension('A')->setWidth(20);
$sheet->getColumnDimension('B')->setWidth(30);
高级功能:使用公式
$sheet->setCellValue('C1', '=SUM(A1:A10)');
创建多个工作表
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->setTitle('一月');
$sheet2 = $spreadsheet->createSheet();
$sheet2->setTitle('二月');
php excel表格导入数据库的实战技巧
将Excel数据导入MySQL是常见需求,但需要注意数据清洗和类型转换。
读取Excel数据
$data = $worksheet->toArray(null, true, true, true);
预处理数据
- 去除空行:
$data = array_filter($data, function($row) { return array_filter($row); }); - 转换日期格式:Excel日期序列号需转换为PHP时间戳。
使用PDO批量插入
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
foreach ($data as $row) {
$stmt->execute([$row[0], $row[1]]);
}
常见问题处理
- 数据类型不匹配:Excel中数字可能被读为字符串,需强制转换。
- 特殊字符编码:确保Excel文件保存为UTF-8,否则需用
mb_convert_encoding。 - 事务管理:批量导入时使用事务可提高性能并保证数据一致性。
$pdo->beginTransaction();
try {
foreach ($data as $row) {
$stmt->execute([$row[0], $row[1]]);
}
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
}
PhpSpreadsheet让PHP处理Excel表格变得简单可控,无论是读取用户提交的报表,还是生成复杂的数据文件,它都能胜任,掌握其核心用法,你就能在实际项目中迅速实现Excel表格与PHP的交互。
Q&A:php excel table 常见问题
如何用PhpSpreadsheet读取Excel中的图片?
通过$drawing = $worksheet->getDrawingCollection()可以获取图片对象,然后使用imagepng或imagejpeg保存到本地,每个图片对象包含坐标和路径信息。
php读取excel表格时遇到内存不足怎么办?
采用读取过滤器分块读取,或设置$reader->setReadDataOnly(true)只读取数据,不加载样式信息,对于超大文件,考虑使用CSV格式转换后再处理。
如何将生成的Excel文件直接输出到浏览器下载?
使用$writer->save('php://output')前,发送正确的Content-Type和Content-Disposition头,并确保没有其他输出,调用ob_clean()和flush()可避免缓存干扰。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/498185.html



