作为 IT 工程师,我将为您提供一个完整的解决方案,使用 PHP 自动将 CSV 和 Excel 文件数据导入到 MySQL 和 PostgreSQL 数据库中。
首先确保安装了以下 PHP 扩展: - PDO (用于数据库连接) - pdo_mysql (MySQL 驱动) - pdo_pgsql (PostgreSQL 驱动) - php_fileinfo (文件类型检测)
对于 Excel 文件处理,推荐使用 PhpSpreadsheet 库:
composer require phpoffice/phpspreadsheet
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
class DataImporter {
private $db;
private $dbType;
public function __construct($dbType, $host, $dbname, $username, $password) {
$this->dbType = strtolower($dbType);
try {
if ($this->dbType === 'mysql') {
$this->db = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
} elseif ($this->dbType === 'postgresql') {
$this->db = new PDO("pgsql:host=$host;dbname=$dbname", $username, $password);
} else {
throw new Exception("Unsupported database type: $dbType");
}
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
}
public function importFile($filePath, $tableName, $hasHeader = true) {
$fileType = $this->detectFileType($filePath);
try {
$data = $this->parseFile($filePath, $fileType, $hasHeader);
if (empty($data)) {
throw new Exception("No data found in the file");
}
$this->importToDatabase($tableName, $data, $hasHeader);
return ['success' => true, 'message' => 'Data imported successfully', 'count' => count($data)];
} catch (Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
}
private function detectFileType($filePath) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $filePath);
finfo_close($finfo);
switch ($mime) {
case 'text/plain':
case 'text/csv':
return 'csv';
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
return 'xlsx';
case 'application/vnd.ms-excel':
return 'xls';
default:
throw new Exception("Unsupported file type: $mime");
}
}
private function parseFile($filePath, $fileType, $hasHeader) {
$data = [];
if ($fileType === 'csv') {
$handle = fopen($filePath, 'r');
if (!$handle) {
throw new Exception("Failed to open CSV file");
}
if ($hasHeader) {
$headers = fgetcsv($handle);
}
while (($row = fgetcsv($handle)) !== false) {
if ($hasHeader) {
$data[] = array_combine($headers, $row);
} else {
$data[] = $row;
}
}
fclose($handle);
} else {
// Handle Excel files
$spreadsheet = IOFactory::load($filePath);
$sheet = $spreadsheet->getActiveSheet();
$rows = $sheet->toArray();
if ($hasHeader) {
$headers = array_shift($rows);
foreach ($rows as $row) {
$data[] = array_combine($headers, $row);
}
} else {
$data = $rows;
}
}
return $data;
}
private function importToDatabase($tableName, $data, $hasHeader) {
if (empty($data)) {
return;
}
// Start transaction
$this->db->beginTransaction();
try {
$firstRow = reset($data);
if ($hasHeader) {
// Associative array (with headers)
$columns = array_keys($firstRow);
$placeholders = implode(', ', array_fill(0, count($columns), '?'));
$columnsStr = implode(', ', $columns);
$stmt = $this->db->prepare("INSERT INTO $tableName ($columnsStr) VALUES ($placeholders)");
foreach ($data as $row) {
$values = array_values($row);
$stmt->execute($values);
}
} else {
// Numeric array (no headers)
$columnCount = count($firstRow);
$placeholders = implode(', ', array_fill(0, $columnCount, '?'));
$stmt = $this->db->prepare("INSERT INTO $tableName VALUES ($placeholders)");
foreach ($data as $row) {
$stmt->execute($row);
}
}
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
throw $e;
}
}
}
// 使用示例
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['data_file'])) {
$uploadDir = 'uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
$fileName = basename($_FILES['data_file']['name']);
$filePath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['data_file']['tmp_name'], $filePath)) {
try {
// 配置数据库连接 - 根据需要修改
$dbType = 'mysql'; // 或 'postgresql'
$host = 'localhost';
$dbname = 'your_database';
$username = 'your_username';
$password = 'your_password';
$importer = new DataImporter($dbType, $host, $dbname, $username, $password);
// 执行导入
$result = $importer->importFile($filePath, 'your_table_name', true);
if ($result['success']) {
echo "Successfully imported {$result['count']} records.";
} else {
echo "Error: " . $result['message'];
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
// 清理上传的文件
unlink($filePath);
} else {
echo "Failed to upload file.";
}
}
?>
<!-- 简单的文件上传表单 -->
<!DOCTYPE html>
<html>
<head>
<title>Data Importer</title>
</head>
<body>
<h1>Import CSV/Excel to Database</h1>
<form method="post" enctype="multipart/form-data">
<input type="file" name="data_file" required>
<button type="submit">Import</button>
</form>
</body>
</html>
文件上传安全:
SQL 注入防护:
数据验证:
批量插入优化:
INSERT INTO table VALUES (...), (...), ...
数据转换:
进度显示:
日志记录:
这个解决方案提供了从文件上传到数据库导入的完整流程,可以根据具体需求进行进一步定制和扩展。