使用 Yii、Laravel 等框架查詢資料庫時,預設返回帶欄位名的關聯陣列。但匯出 Excel、CSV 或對接無表頭的第三方 API 時,往往需要純索引陣列(鍵名為 0,1,2...)並單獨提取表頭。本文提供一個通用的 excelDataFormat() 方法實現此轉換。
<?php
/**
* 將關聯陣列集合轉換為 Excel 適用格式
* @param array $data 二維關聯陣列 [['id'=>1,'name'=>'A'], ['id'=>2,'name'=>'B']]
* @return array ['excel_title' => ['id','name'], 'excel_cells' => [[1,'A'],[2,'B']]]
*/
public function excelDataFormat(array $data): array {
if (empty($data)) {
return ['excel_title' => [], 'excel_cells' => []];
}
// 提取表頭(取第一行鍵名)
$titles = array_keys($data[0]);
// 提取純值陣列(去除鍵名)
$cells = array_map('array_values', $data);
return [
'excel_title' => $titles,
'excel_cells' => $cells
];
}
// 使用範例
$raw = [
['id' => 1, 'username' => 'alice', 'email' => 'alice@example.com'],
['id' => 2, 'username' => 'bob', 'email' => 'bob@example.com'],
];
$formatted = excelDataFormat($raw);
/*
結果:
[
'excel_title' => ['id', 'username', 'email'],
'excel_cells' => [
[1, 'alice', 'alice@example.com'],
[2, 'bob', 'bob@example.com']
]
]
*/
function formatForExcel(array $data, array $columnMap = [], string $sheetName = 'Sheet1'): array {
// $columnMap = ['db_field' => 'Excel 表頭', ...] 若為空則使用原鍵名
if (empty($data)) return ['sheets' => []];
$titles = $columnMap ? array_values($columnMap) : array_keys($data[0]);
$fields = $columnMap ? array_keys($columnMap) : array_keys($data[0]);
$cells = [];
foreach ($data as $row) {
$line = [];
foreach ($fields as $field) {
$line[] = $row[$field] ?? '';
}
$cells[] = $line;
}
return [
'sheets' => [
$sheetName => [
'titles' => $titles,
'cells' => $cells
]
]
];
}
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$formatted = excelDataFormat($rawData);
// 寫入表頭
$sheet->fromArray($formatted['excel_title'], null, 'A1');
// 寫入數據(從第 2 行開始)
$sheet->fromArray($formatted['excel_cells'], null, 'A2');
// 可選:自動欄寬、樣式設定
foreach (range('A', $sheet->getHighestColumn()) as $col) {
$sheet->getColumnDimension($col)->setAutoSize(true);
}
$writer = new Xlsx($spreadsheet);
$writer->save('export.xlsx');
array_keys($data[0]) 可能導致列錯位。建議先統一鍵名順序或使用欄位映射。CSV 格式避免記憶體溢位。