在业务系统中,当需要将多个数据库表的数据分别导出为独立的Excel文件,并且统一提供给用户下载时,手动逐个导出再打包的方式效率极低,通过PHP编写自动化脚本可以高效完成这一任务。整个流程主要分为四个步骤:连接数据库并获取目标表的数据、将每个表的数据生成对应的Excel文件、将所有Excel文件打包为zip压缩包、输出压缩包供用户下载。

环境准备
实现该功能需要PHP环境开启PDO扩展用于数据库操作,开启zip扩展用于打包文件,同时需要准备生成Excel文件的依赖。这里我们使用纯PHP生成Excel内容,不依赖第三方类库,降低环境要求。
核心实现步骤
1. 连接数据库并获取目标表列表
首先通过PDO连接数据库,获取需要导出的所有表名,示例代码如下:
<?php
// 数据库配置
$db_host = '127.0.0.1';
$db_name = 'test_db';
$db_user = 'root';
$db_pass = '123456';
$db_charset = 'utf8mb4';
try {
// 连接数据库
$pdo = new PDO(
"mysql:host=$db_host;dbname=$db_name;charset=$db_charset",
$db_user,
$db_pass,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
} catch (PDOException $e) {
die("数据库连接失败:" . $e->getMessage());
}
// 获取所有需要导出的表名,这里示例导出指定的三个表,也可以查询所有表
$export_tables = ['user_info', 'order_list', 'product_info'];
?>
2. 生成单个表的Excel文件
Excel文件本质是符合格式的XML文件,这里我们用简单的方式生成兼容Excel的CSV格式内容,再保存为xls后缀的文件,Excel可以直接打开。生成单个表Excel文件的函数如下:
<?php
/**
* 生成单个表的Excel文件
* @param PDO $pdo 数据库连接对象
* @param string $table_name 表名
* @param string $file_path 文件保存路径
* @return bool 是否生成成功
*/
function generateTableExcel($pdo, $table_name, $file_path) {
// 查询表的所有数据
$stmt = $pdo->query("SELECT * FROM `$table_name`");
$data = $stmt->fetchAll();
if (empty($data)) {
// 表无数据,生成空文件
file_put_contents($file_path, '');
return true;
}
// 获取表头(字段名)
$headers = array_keys($data[0]);
// 拼接Excel内容,使用制表符分隔,换行使用rn
$excel_content = '';
// 写入表头
$excel_content .= implode("t", $headers) . "rn";
// 写入数据行
foreach ($data as $row) {
$excel_content .= implode("t", $row) . "rn";
}
// 保存文件,指定UTF-8 BOM头,避免中文乱码
file_put_contents($file_path, "xEFxBBxBF" . $excel_content);
return true;
}
?>
3. 批量生成Excel文件并打包为zip
遍历所有需要导出的表,逐个生成Excel文件,然后使用ZipArchive类将所有文件打包:
<?php
// 临时目录,用于存放生成的Excel文件
$temp_dir = __DIR__ . '/temp_excel/';
if (!is_dir($temp_dir)) {
mkdir($temp_dir, 0777, true);
}
// 生成的Excel文件路径数组
$excel_files = [];
// 遍历表生成Excel
foreach ($export_tables as $table) {
$excel_path = $temp_dir . $table . '.xls';
generateTableExcel($pdo, $table, $excel_path);
$excel_files[] = $excel_path;
}
// 打包为zip文件
$zip_path = $temp_dir . 'db_tables_export_' . date('YmdHis') . '.zip';
$zip = new ZipArchive();
if ($zip->open($zip_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
foreach ($excel_files as $file) {
// 添加文件到zip,第二个参数是zip中的文件名
$zip->addFile($file, basename($file));
}
$zip->close();
} else {
die("创建zip文件失败");
}
?>
4. 输出zip文件供用户下载
设置正确的HTTP响应头,将生成的zip文件输出到浏览器,同时清理临时文件:
<?php
// 设置下载响应头
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($zip_path) . '"');
header('Content-Length: ' . filesize($zip_path));
// 输出文件内容
readfile($zip_path);
// 清理临时文件
foreach ($excel_files as $file) {
unlink($file);
}
unlink($zip_path);
rmdir($temp_dir);
// 关闭数据库连接
$pdo = null;
exit;
?>
注意事项
- 导出大表数据时,需要注意PHP的内存限制和执行时间限制,可以通过
ini_set('memory_limit', '512M')和set_time_limit(0)调整。 - 表名和字段名如果有关键字,需要用反引号包裹,避免SQL语法错误。
- 生成的Excel文件是CSV格式改后缀,复杂格式需求可以替换为PhpSpreadsheet等第三方类库生成标准xlsx文件。
- 临时目录需要有写入权限,否则无法生成文件和打包。
完整流程整合
将以上所有代码片段整合后,完整的执行流程就是先连接数据库,再批量生成Excel,接着打包,最后输出下载,整个过程中临时文件会在下载完成后自动清理,不会占用服务器空间。