Để upload dữ liệu từ file Excel lên database MySQL (sử dụng phpMyAdmin để quản lý) thông qua PHP, chúng ta sẽ sử dụng thư viện PhpSpreadsheet (đây là phiên bản kế nhiệm của PHPExcel, được khuyến khích sử dụng vì PHPExcel đã ngừng phát triển).
Tổng quan các bước thực hiện
- Cài đặt PhpSpreadsheet: Sử dụng Composer để cài đặt thư viện.
- Tạo form upload file Excel: Một form HTML đơn giản để người dùng chọn file.
- Xử lý file Excel bằng PHP: Đọc dữ liệu từ file Excel, sau đó kết nối đến database và lưu dữ liệu vào bảng.
- Cấu trúc database: Chuẩn bị bảng trong database để lưu trữ dữ liệu.
Bắt đầu thực hiện
Bước 1: Cài đặt PhpSpreadsheet
Đảm bảo bạn đã cài đặt Composer. Nếu chưa, bạn có thể tải về từ
Mở Terminal hoặc Command Prompt, điều hướng đến thư mục dự án PHP của bạn và chạy lệnh sau:
composer require phpoffice/phpspreadsheet
Lệnh này sẽ tải xuống PhpSpreadsheet và các dependencies của nó vào thư mục vendor/
trong dự án của bạn.
Bước 2: Chuẩn bị Database (phpMyAdmin)
Giả sử bạn muốn upload dữ liệu từ Excel vào một bảng có tên là san_pham
với các cột như ma_san_pham
, ten_san_pham
, gia
, so_luong
.
Đăng nhập vào phpMyAdmin, chọn database của bạn và chạy truy vấn SQL sau để tạo bảng:
CREATE TABLE san_pham (
id INT AUTO_INCREMENT PRIMARY KEY,
ma_san_pham VARCHAR(50) NOT NULL,
ten_san_pham VARCHAR(255) NOT NULL,
gia DECIMAL(10, 2) NOT NULL,
so_luong INT NOT NULL
);
Bước 3: Tạo Form Upload (index.php)
Tạo một file index.php
(hoặc bất kỳ tên nào bạn muốn) với nội dung sau. File này sẽ chứa form để người dùng upload file Excel.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Upload Dữ liệu Excel</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; background-color: #f4f4f4; }
.container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); max-width: 500px; margin: auto; }
h2 { text-align: center; color: #333; }
form { display: flex; flex-direction: column; }
input[type="file"] { margin-bottom: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
input[type="submit"] { background-color: #007bff; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
input[type="submit"]:hover { background-color: #0056b3; }
.message { margin-top: 20px; padding: 10px; border-radius: 4px; }
.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
</style>
</head>
<body>
<div class="container">
<h2>Upload Dữ liệu từ Excel lên Database</h2>
<?php
session_start();
if (isset($_SESSION['message'])) {
echo '<div class="message ' . $_SESSION['message_type'] . '">' . $_SESSION['message'] . '</div>';
unset($_SESSION['message']);
unset($_SESSION['message_type']);
}
?>
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="excel_file">Chọn file Excel (.xlsx, .xls):</label>
<input type="file" name="excel_file" id="excel_file" accept=".xlsx, .xls" required>
<input type="submit" name="submit" value="Upload Dữ liệu">
</form>
</div>
</body>
</html>
Bước 4: Xử lý Upload và Lưu Database (upload.php)
Tạo một file upload.php
trong cùng thư mục với index.php
. File này sẽ chứa logic để đọc file Excel và đẩy dữ liệu vào database.
<?php
session_start();
require 'vendor/autoload.php'; // Tự động load thư viện PhpSpreadsheet
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Exception;
// Cấu hình Database
$servername = "localhost";
$username = "root"; // Thay đổi nếu khác
$password = ""; // Thay đổi nếu khác
$dbname = "ten_database_cua_ban"; // Thay đổi thành tên database của bạn
// Tạo kết nối
$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die("Kết nối database thất bại: " . $conn->connect_error);
}
if (isset($_POST['submit']) && isset($_FILES['excel_file'])) {
$file_mimes = array(
'application/vnd.ms-excel',
'application/octet-stream',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/zip',
'application/excel',
'application/x-excel',
'application/x-msexcel'
);
if (in_array($_FILES['excel_file']['type'], $file_mimes)) {
$arr_file = explode('.', $_FILES['excel_file']['name']);
$extension = end($arr_file);
if ('xlsx' == $extension) {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
} else {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
}
try {
$spreadsheet = $reader->load($_FILES['excel_file']['tmp_name']);
$worksheet = $spreadsheet->getActiveSheet();
$highestRow = $worksheet->getHighestRow();
$success_count = 0;
$error_count = 0;
// Bắt đầu từ hàng thứ 2 nếu hàng đầu tiên là tiêu đề
for ($row = 2; $row <= $highestRow; ++$row) {
$ma_san_pham = $worksheet->getCellByColumnAndRow(1, $row)->getValue(); // Cột A
$ten_san_pham = $worksheet->getCellByColumnAndRow(2, $row)->getValue(); // Cột B
$gia = $worksheet->getCellByColumnAndRow(3, $row)->getValue(); // Cột C
$so_luong = $worksheet->getCellByColumnAndRow(4, $row)->getValue(); // Cột D
// Kiểm tra dữ liệu hợp lệ (có thể thêm các kiểm tra khác tùy ý)
if (!empty($ma_san_pham) && !empty($ten_san_pham) && is_numeric($gia) && is_numeric($so_luong)) {
// Chuẩn bị câu lệnh SQL để tránh SQL Injection
$stmt = $conn->prepare("INSERT INTO san_pham (ma_san_pham, ten_san_pham, gia, so_luong) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssdi", $ma_san_pham, $ten_san_pham, $gia, $so_luong);
if ($stmt->execute()) {
$success_count++;
} else {
$error_count++;
// Có thể ghi log lỗi ở đây nếu cần
}
$stmt->close();
} else {
$error_count++;
}
}
if ($success_count > 0) {
$_SESSION['message'] = "Upload dữ liệu thành công! Đã thêm {$success_count} bản ghi. Có {$error_count} bản ghi bị lỗi.";
$_SESSION['message_type'] = "success";
} else {
$_SESSION['message'] = "Không có bản ghi nào được thêm. Vui lòng kiểm tra lại file Excel và dữ liệu.";
$_SESSION['message_type'] = "error";
}
// Đóng kết nối database
$conn->close();
header("Location: index.php");
exit();
} catch (Exception $e) {
$_SESSION['message'] = 'Lỗi khi đọc file Excel: ' . $e->getMessage();
$_SESSION['message_type'] = "error";
header("Location: index.php");
exit();
}
} else {
$_SESSION['message'] = 'Vui lòng chỉ upload file Excel (.xlsx hoặc .xls).';
$_SESSION['message_type'] = "error";
header("Location: index.php");
exit();
}
}
?>
Giải thích code upload.php
:
require 'vendor/autoload.php';
: Đây là dòng quan trọng để tải tự động tất cả các class của PhpSpreadsheet mà bạn đã cài đặt qua Composer.- Cấu hình Database: Thay đổi
$servername
,$username
,$password
,$dbname
phù hợp với thông tin database của bạn. - Kiểm tra file upload:
- Kiểm tra xem file có được submit hay không (
isset($_POST['submit']) && isset($_FILES['excel_file'])
). - Kiểm tra
MIME type
của file để đảm bảo đó là file Excel.
- Kiểm tra xem file có được submit hay không (
- Đọc file Excel:
- Xác định loại file (
.xlsx
hay.xls
) để chọnReader
phù hợp (Xlsx
hoặcXls
). $reader->load($_FILES['excel_file']['tmp_name'])
: Tải file Excel tạm thời lên bộ nhớ.$spreadsheet->getActiveSheet()
: Lấy worksheet (sheet) hiện tại trong file Excel.$worksheet->getHighestRow()
: Lấy số hàng cuối cùng chứa dữ liệu.
- Xác định loại file (
- Lặp qua từng hàng và lấy dữ liệu:
- Vòng lặp
for ($row = 2; $row <= $highestRow; ++$row)
: Bắt đầu từ hàng thứ 2, giả định hàng đầu tiên là tiêu đề (header) của các cột. $worksheet->getCellByColumnAndRow(1, $row)->getValue()
: Lấy giá trị của ô tại cột 1 (tương ứng với cột A trong Excel) và hàng$row
. Tương tự cho các cột khác.
- Vòng lặp
- Chèn dữ liệu vào Database:
- Sử dụng Prepared Statements (
$conn->prepare()
,$stmt->bind_param()
,$stmt->execute()
) để chèn dữ liệu vào database. Điều này cực kỳ quan trọng để ngăn chặn các cuộc tấn công SQL Injection. bind_param("ssdi", ...)
: "ssdi" chỉ định kiểu dữ liệu của các tham số tương ứng:s
cho string (chuỗi),d
cho double (số thực),i
cho integer (số nguyên).
- Sử dụng Prepared Statements (
- Thông báo kết quả: Sử dụng
$_SESSION
để truyền thông báo thành công hoặc lỗi về trangindex.php
. header("Location: index.php"); exit();
: Điều hướng người dùng trở lại trangindex.php
sau khi quá trình xử lý hoàn tất.
Cách sử dụng
- Cấu trúc thư mục: Đảm bảo các file của bạn có cấu trúc tương tự như sau:
your_project/ ├── vendor/ (thư mục được tạo bởi Composer) ├── index.php ├── upload.php ├── composer.json (tự động tạo khi chạy composer require) ├── composer.lock (tự động tạo khi chạy composer require)
- Khởi động Web Server: Đảm bảo bạn đã khởi động Apache/Nginx và MySQL (thường đi kèm với XAMPP, WAMP, MAMP).
- Tạo file Excel: Tạo một file Excel (.xlsx hoặc .xls) với các cột dữ liệu tương ứng với cấu trúc bảng
san_pham
của bạn (ví dụ: Mã sản phẩm, Tên sản phẩm, Giá, Số lượng). Dữ liệu mẫu: | Mã sản phẩm | Tên sản phẩm | Giá | Số lượng | | :---------- | :---------------- | :----- | :------- | | SP001 | Laptop ABC | 1500.00 | 10 | | SP002 | Điện thoại XYZ | 800.50 | 25 | | SP003 | Chuột không dây | 25.99 | 100 | - Truy cập trang web: Mở trình duyệt và truy cập
http://localhost/your_project/index.php
(thayyour_project
bằng tên thư mục dự án của bạn). - Upload file: Chọn file Excel và nhấn "Upload Dữ liệu".
Bạn sẽ thấy thông báo thành công hoặc thất bại trên trang index.php
và dữ liệu sẽ được thêm vào bảng san_pham
trong phpMyAdmin.
Lưu ý quan trọng
- Bảo mật: Luôn sử dụng Prepared Statements để ngăn chặn SQL Injection. Kiểm tra kỹ loại file và kích thước file upload.
- Xử lý lỗi: PhpSpreadsheet có thể ném ra các ngoại lệ (exceptions) nếu có vấn đề với file Excel. Luôn bao bọc code đọc file bằng
try-catch
block. - Hiệu suất: Với file Excel rất lớn (hàng chục nghìn hàng trở lên), việc đọc toàn bộ file vào bộ nhớ có thể gây tràn RAM. PhpSpreadsheet có các phương pháp xử lý file lớn hơn (ví dụ: đọc từng phần, sử dụng Cell Caching) mà bạn có thể tìm hiểu thêm trong tài liệu của PhpSpreadsheet.
- Định dạng dữ liệu: Đảm bảo định dạng dữ liệu trong file Excel khớp với kiểu dữ liệu của các cột trong database để tránh lỗi khi chèn. Ví dụ: cột
gia
trong database làDECIMAL
, nên trong Excel bạn nên nhập số. - Tùy chỉnh: Bạn có thể tùy chỉnh code
upload.php
để đọc các cột khác nhau, xử lý nhiều sheet, hoặc thêm các quy tắc kiểm tra dữ liệu phức tạp hơn tùy theo yêu cầu của bạn.
Chúc bạn thành công!
0 Reviews