首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 實現 Excel/CSV 數據與 MySQL 資料庫的高效導入導出

     編輯:MySQL 資料庫相關知識

前言

在 Web 開發中,將 Excel 或 CSV 格式的數據導入 MySQL 資料庫,或是將資料庫數據導出為 Excel 供用戶下載,是極為常見的業務需求。本文將通過原生 PHP 代碼示例,詳細講解如何構建一個包含文件上傳、數據解析、資料庫寫入以及數據導出下載的完整功能模塊。

一、 CSV 數據導入 MySQL 實戰

1. 前端上傳表單

首先需要一個支持文件上傳的 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>

2. 後端處理邏輯

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,自動處理引號、逗號等特殊字符。
  • 強烈建議使用預處理語句 替代字符串拼接,有效防止 SQL 注入並提升批量插入性能。
  • 生產環境需加入事務控制、錯誤日誌記錄及大文件分塊處理機制。

二、 MySQL 數據導出為 Excel (舊版 .xls 格式)

通過設置 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(); // 確保無額外輸出
?>

三、 進階建議與現代化替代方案

1. 大數據量優化

  • 導入: 使用 LOAD DATA INFILE SQL 語句,速度比 PHP 循環插入快數十倍;或使用事務批量提交(每 500-1000 條提交一次)。
  • 導出: 避免一次性查詢所有數據導致內存溢出,應使用游標或分頁查詢(LIMIT offset, size)流式輸出。

2. 現代庫推薦

若需支持真正的 .xlsx 格式、樣式設置、圖表等高級功能,強烈推薦使用成熟的 Composer 包:

  • PhpSpreadsheet (PHPExcel 繼任者):功能最全面,支持讀寫多種格式。
  • Box/Spout:專為大文件流式讀寫設計,內存佔用極低,速度極快。

3. 安全性檢查清單

  1. 驗證文件 MIME 類型與副檔名,防止惡意腳本上傳。
  2. 限制上傳文件大小。
  3. 所有 SQL 操作使用參數綁定。
  4. 導出文件名進行清理,防止 Header 注入攻擊。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved