在 Web 開發中,將 Excel 或 CSV 格式的數據導入 MySQL 資料庫,或是將資料庫數據導出為 Excel 供用戶下載,是極為常見的業務需求。本文將通過原生 PHP 代碼示例,詳細講解如何構建一個包含文件上傳、數據解析、資料庫寫入以及數據導出下載的完整功能模塊。
首先需要一個支持文件上傳的 HTML 表單,關鍵在於設置 enctype="multipart/form-data" 屬性。
<form action="" method="post" enctype="multipart/form-data">
<p>導入 CSV 數據:<input type="file" name="MyFile"> <input type="submit" value="提交導入"></p>
</form>
PHP 腳本接收文件後,將其移動到可讀目錄,隨後使用 fgetcsv() 逐行讀取並寫入資料庫。
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['MyFile'])) {
$fname = $_FILES['MyFile']['tmp_name']; // 直接使用臨時文件路徑
// 資料庫連接 (建議使用 PDO 或 MySQLi 預處理語句防止 SQL 注入)
$mysqli = new mysqli("localhost", "root", "123456", "test");
if ($mysqli->connect_error) {
die("連接失敗: " . $mysqli->connect_error);
}
$mysqli->set_charset("utf8mb4");
if (($handle = fopen($fname, "r")) !== FALSE) {
$stmt = $mysqli->prepare("INSERT INTO `test` (`Weight`, `zone1`, `zone2`) VALUES (?, ?, ?)");
while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
// 數據校驗:確保欄位數量正確
if (count($data) >= 3) {
$stmt->bind_param("sss", $data[0], $data[1], $data[2]);
$stmt->execute();
}
}
fclose($handle);
$stmt->close();
echo "數據導入成功!";
}
$mysqli->close();
}
?>
核心要點:
fgetcsv() 解析 CSV,自動處理引號、逗號等特殊字符。通過設置 HTTP Header 強制瀏覽器下載,並輸出 Tab 分隔的文本內容,Excel 可直接識別為 .xls 文件。
<?php
// 配置資料庫連接
$DB_Server = "localhost";
$DB_Username = "root";
$DB_PassWord = "";
$DB_DBName = "ishop";
$DB_TBLName = "oi_mall_payment";
$Connect = @mysqli_connect($DB_Server, $DB_Username, $DB_PassWord, $DB_DBName) or die("無法連接數據庫");
mysqli_query($Connect, "SET NAMES 'utf8'"); // 統一使用 UTF-8
// 設置下載 Header
$savename = date("YmdHis");
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename={$savename}.xls");
header("Pragma: no-cache");
header("Expires: 0");
// 導出標題行
$title = "數據庫: $DB_DBName, 數據表: $DB_TBLName, 導出時間: " . date("Y-m-d H:i:s");
echo $title . "\n";
$sql = "SELECT * FROM `$DB_TBLName`";
$result = mysqli_query($Connect, $sql) or die("查詢失敗: " . mysqli_error($Connect));
// 輸出欄位名
$fields = mysqli_fetch_fields($result);
foreach ($fields as $field) {
echo $field->name . "\t";
}
echo "\n";
// 輸出數據行
while ($row = mysqli_fetch_row($result)) {
$line = "";
foreach ($row as $value) {
// 處理 NULL 值及特殊字符轉義
$line .= (isset($value) && $value !== "") ? str_replace("\t", " ", $value) : "NULL";
$line .= "\t";
}
echo trim($line) . "\n";
}
mysqli_free_result($result);
mysqli_close($Connect);
exit(); // 確保無額外輸出
?>
LOAD DATA INFILE SQL 語句,速度比 PHP 循環插入快數十倍;或使用事務批量提交(每 500-1000 條提交一次)。若需支持真正的 .xlsx 格式、樣式設置、圖表等高級功能,強烈推薦使用成熟的 Composer 包: