PHP实现MySQL双表关联数据导出为Excel/CSV的技术问询
PHP实现机构与多所有者信息合并导出CSV方案
核心思路
要实现两表合并导出,关键是按机构分组收集所有所有者信息,再将机构基础信息与多组所有者字段拼接成单行。由于所有者数量不固定,需先统计最大所有者数来动态生成表头,确保所有机构的行结构一致。
具体代码修改方案
假设你已有PDO数据库连接,替换原单表导出代码为以下逻辑:
<?php // 1. 数据库连接(替换为你的实际连接信息) $pdo = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8', 'username', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 2. 关联查询机构与所有者数据 $stmt = $pdo->query(" SELECT ibd.id AS institute_id, ibd.institute_name, ibd.city, iod.owner_name, iod.owner_email, iod.owner_phone FROM institute_basic_details ibd LEFT JOIN institute_owners_details iod ON ibd.id = iod.institute_id ORDER BY ibd.id "); // 3. 按机构ID分组整理数据(避免重名机构冲突) $instituteData = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $instId = $row['institute_id']; if (!isset($instituteData[$instId])) { $instituteData[$instId] = [ 'name' => $row['institute_name'], 'city' => $row['city'], 'owners' => [] ]; } // 跳过空所有者数据 if (!empty($row['owner_name'])) { $instituteData[$instId]['owners'][] = [ 'name' => $row['owner_name'], 'email' => $row['owner_email'], 'phone' => $row['owner_phone'] ]; } } // 4. 统计最大所有者数量,生成动态表头 $maxOwnerCount = 0; foreach ($instituteData as $inst) { $count = count($inst['owners']); if ($count > $maxOwnerCount) { $maxOwnerCount = $count; } } // 5. 构造CSV表头 $header = ['机构名称', '机构城市']; for ($i = 1; $i <= $maxOwnerCount; $i++) { $header[] = "所有者{$i}姓名"; $header[] = "所有者{$i}邮箱"; $header[] = "所有者{$i}手机号"; } // 6. 输出CSV文件 header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="institute_owners.csv"'); $output = fopen('php://output', 'w'); // 写入表头 fputcsv($output, $header); // 写入每行数据 foreach ($instituteData as $inst) { $row = [$inst['name'], $inst['city']]; // 追加所有者信息 foreach ($inst['owners'] as $owner) { $row[] = $owner['name']; $row[] = $owner['email']; $row[] = $owner['phone']; } // 补全空列,确保每行字段数与表头一致 $missingCols = ($maxOwnerCount - count($inst['owners'])) * 3; for ($i = 0; $i < $missingCols; $i++) { $row[] = ''; } fputcsv($output, $row); } fclose($output); exit; ?>
关键注意事项
- 机构唯一标识:用表1的主键
institute_id分组,比名称+城市更可靠,避免重名机构导致数据混乱。 - 编码处理:确保数据库连接和CSV输出都用
utf8或utf8mb4,防止中文乱码。 - 空值兼容:通过
LEFT JOIN保留无所有者的机构,空所有者列自动填充空字符串。 - 性能优化:如果数据量极大,可考虑分批查询或用
GROUP_CONCAT在SQL层拼接所有者信息(需注意group_concat_max_len配置限制)。
内容的提问来源于stack exchange,提问作者Dr M L M J
相关产品推荐
相关产品推荐

