Drupal 7 專案中導入 Excel 數據是常見需求。利用成熟的 PHPExcel 庫(現建議遷移至 PhpSpreadsheet),結合 Drupal 表單 API 與資料庫抽象層,可構建健壯的導入功能。
sites/all/libraries/PHPExcel/libraries_load('PHPExcel') 自動載入require_once 'sites/all/libraries/PHPExcel/PHPExcel/IOFactory.php';function excel_upload_form_submit($form, &$form_state) {
set_time_limit(0); // 防止大文件超時
if ($file = file_save_upload('file')) {
$timestamp = time();
$insertRows = $paseRows = $row = 0;
// 目標表字段映射
$fields = ['dbfield1', 'dbfield2', 'dbfield3', 'dbfield4', 'dbfield5'];
require_once 'sites/all/libraries/PHPExcel/PHPExcel/IOFactory.php';
// 自動識別 Excel 版本
$PHPReader = new PHPExcel_Reader_Excel2007();
if (!$PHPReader->canRead($file->filepath)) {
$PHPReader = new PHPExcel_Reader_Excel5();
if (!$PHPReader->canRead($file->filepath)) {
drupal_set_message(t('非有效 Excel 文件'), 'error');
return;
}
}
$PHPExcel = $PHPReader->load($file->filepath);
$sheet = $PHPExcel->getSheet(0);
$highestColumn = $sheet->getHighestColumn(); // 如 'F'
$colCount = PHPExcel_Cell::columnIndexFromString($highestColumn); // 數字索引 0-based
$rowCount = $sheet->getHighestRow();
// 從第 2 行開始(跳過表頭)
for ($rowIndex = 2; $rowIndex <= $rowCount; $rowIndex++) {
$rowData = [];
$valid = true;
for ($colIndex = 0; $colIndex <= $colCount; $colIndex++) {
$cell = $sheet->getCellByColumnAndRow($colIndex, $rowIndex)->getValue();
$cell = trim($cell);
// 處理富文本單元格
if ($cell instanceof PHPExcel_RichText) {
$cell = $cell->__toString();
}
// 第一列為空視為無效行
if ($colIndex === 0 && !intval($cell)) {
$paseRows++;
$valid = false;
break;
}
$rowData[] = $cell;
}
if ($valid && $rowData) {
// 使用 Drupal DB API 安全插入
$placeholders = implode(', ', array_fill(0, count($fields), '%s'));
$query = "INSERT INTO {db_import} (" . implode(', ', $fields) . ", created) VALUES ($placeholders, %d)";
$args = array_merge($rowData, [$timestamp]);
db_query($query, $args);
$insertRows++;
}
$row++;
}
drupal_set_message(t('文件 @file 導入成功,共解析 @total 行,新增 @insert 行,跳過 @skip 行', [
'@file' => $file->filename,
'@total' => $row,
'@insert' => $insertRows,
'@skip' => $paseRows
]));
} else {
drupal_set_message(t('未找到上傳文件'), 'error');
$form_state['redirect'] = 'admin/content/db/import';
}
}
PHPExcel_Cell::columnIndexFromString() 將 'A'→0, 'Z'→25, 'AA'→26PHPExcel_RichText 對象,需 __toString() 取純文本{table} 自動加表前綴,佔位符 %s %d 防注入PHPExcel_CachedObjectStorageFactory 緩存到磁盤/內存Batch API 分批執行,避免 PHP 超時/內存溢出db_transaction() 中,失敗全量回滾遵循 Drupal 開發規範,結合成熟庫,可快速構建企業級 Excel 導入功能。