Export Html Table To Excel With Style Using Javascript: A Comprehensive Guide

Trong thời đại dữ liệu lớn và các ứng dụng đa nền tảng, việc xuất dữ liệu từ bảng HTML sang file Excel vẫn là một nhu cầu phổ biến trong بنت các trang web doanh nghiệp, portal báo cáo, dashboard và nhiều ứng dụng khác. Dù có nhiều thư viện hỗ trợ, nhưng nếu bạn muốn kiểm soát hoàn toàn quá trình này — từ việc giữ nguyên định dạng, màu sắc, kiểu chữ cho tới tính năng ghi chú và định dạng số — thì viết một đoạn JavaScript tùy chỉnh sẽ mang lại sự linh hoạt và tùy biến cao nhất.

Trong bài viết này, chúng ta sẽ đi sâu vào cách export một bảng HTML sang file Excel (.xls hoặc .xlsx) kèm theo các style (màu nền, độ dày đường viền, font chữ, kiểu số, v.v.) mà không cần phụ thuộc vào thư viện bên ngoài. Bài viết sẽ bao gồm:

  • Giới thiệu về cấu trúc file Excel và cách các trang web có thể tạo ra nó từ phía client.
  • Một 手段 đơn giản để chuyển đổi bảng HTML thành một chuỗi XML có dạng XLS.
  • Phương pháp hiện đại hơn — sử dụng thư viện SheetJS (xlsx) để tạo file xlsx với style chi tiết.
  • Cách custom CSS sẽ được chuyển sang style trong file Excel.
  • Điều hướng các vấn đề thường gặp như định dạng số, ngày tháng, ký tự đặc biệt.
  • Ví dụ hoàn chỉnh với một bảng mẫu, bao gồm JavaScript, CSS và HTML.
  • Những mẹo tối ưu, bảo mật và triển khai thực tế.

Với độ dài 1700+ từ, bài viết sẽ cung cấp đủ thông tin chi tiết để bạn có thể triển khai ngay trong dự án của mình.

1. TJSONObject: Cấu trúc dữ liệu Excel và cách tạo file từ HTML

File Excel thực chất là một tập hợp các tài nguyên lưu trữ dữ liệu, định dạng và චức năng trong một hoặc nhiều “sheet” (bảng). Khi chúng ta muốn tạo file Excel từ phía client, một trong những cách đơn giản nhất là tạo một chuỗi XML theo chuẩn .xls (Excel 97–2003) được hỗ trợ bởi các trình duyệt hiện đại. Tuy nhiên, .xls có hạn chế về kích thước và tính năng. Để tạo file .xlsx (Excel 2007+) với định dạng phong phú, bạn có thể dùng thư viện SheetJS (còn được gọi là xlsx) – một thư viện JavaScript mạnh mẽ, hỗ trợ đọc/ghi file Excel, chuyển đổi dữ liệu và áp dụng style.

Để đơn giản, bài viết sẽ trình bày cả hai cách: cách “truyền thống” với XML (không cần thư viện) và cách sử dụng SheetJS (được khuyến nghị cho các dự án có nhu cầu mở rộng, hỗ trợ định dạng phức tạp).

1.1. Cách “truyền thống”: Tạo chuỗi XML .xls

Để tạo file Excel từ một bảng HTML, bạn có thể lấy nội dung bảng, đưa vào một template XML đã được chuẩn hóa và ingress vào một file .xls. Dưới đây là một mẫu template cơ bản:

<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <Worksheet ss:Name="Sheet1"> <Table> Nội dung bảng sẽ được chèn vào đây </Table> </Worksheet>
</Workbook>

Với cách này, bạn chỉ cần lặp qua hàng và cột trong bảng HTML, tạo các <Row> và <Cell> tương ứng. Tuy nhiên, nó có hạn chế vì:

  • Hạn chế về kiểu dữ liệu (chỉ hỗ trợ text và số).
  • Không hỗ trợ style phức tạp (định dạng ngày tháng, màu sắc, font).
  • Khó mở rộng khi bảng có nhiều cột, nhiều sheet.

1.2. Cách hiện đại: Sử dụng SheetJS (xlsx)

SheetJS cho phép bạn:

  • Đọc/ghi file Excel từ/đến client.
  • Chèn dữ liệu theo dạng array hoặc object.
  • Áp dụng style chi tiết (màu nền, font, border, format).
  • Export sang nhiều định dạng (.xlsx, .csv, .xls, .html).
  • Tương thích với các browser hiện đại và Node.js.

Để sử dụng, bạn chỉ cần import thư viện (xlsx wi), chuyển bảng HTML thành một đối tượng JavaScript, rồi gọi XLSX.writeFile để tạo file. Mô tả chi tiết sẽ được trình bày trong phần 2.2.

2. Định dạng và Style: Bảo toàn CSS khi xuất sang Excel

Một trong những thách thức lớn nhất khi export bảng HTML sang Excel là việc chuyển đổi style CSS. Trong HTML, style có thể được áp dụng bằng các class, id hoặc inline. Khi chuyển sang Excel, bạn cần xác định cách mà các style này sẽ được ánh xạ sang các thuộc tính trong file Excel.

2.1. Các thuộc tính style quan trọng

  • Màu nền (background-color): Thường được ánh xạ sang fill trong Excel.
  • Font (font-family, font-size, font-weight, font-style, color): Ánh xạ sang font trong Excel.
  • Borders (border-width, border-style, border-color): Ánh xạ sang border trong Excel.
  • Text alignment (text-align, vertical-align): Ánh xạ sang alignment trong Excel.
  • Decimal places, number format, date format: Định dạng dữ liệu, cần được thiết lập qua numFmt trong Excel.

SheetJS cung cấp một API gọi là XLSX.utils.book_new() và XLSX.utils.aoa_to_sheet() để tạo sheet từ array of arrays. Sau đó, chúng ta có thể áp dụng style cho từng ô bằng cách thao tác với đối tượng ws"A1" (hoặc bất kỳ ô nào). Mô tả chi tiết cách áp dụng style sẽ được trình bày trong phần 2.2.

2.2. Sử dụng SheetJS để export bảng HTML sang Excel với style

Đầu tiên, chúng ta cần tải thư viện xlsx.full.min.js từ CDN. Dưới đây là một ví dụ minh họa:

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

Giả sử bạn códies một bảng HTML với id myTable:

<table id="myTable"> <tr><th>Name</th><th>Age</th><th>Salary</th></tr> <tr><td>Alice</td><td>30</td><td>1000</td></tr> <tr><td>Bob</td><td>25</td><td>800</td></tr>
</table>

Tiếp theo, viết một hàm JavaScript để chuyển bảng thành một sheet dữ liệu, áp dụng style, và xuất file:

function exportTableToExcel(tableId, filename = 'test.xlsx') { // Lấy bảng const table = document.getElementById(tableId); if (!table) { console.error('Không tìm thấy bảng có id', tableId); return; } // Thu thập dữ liệu từ bảng const data = ; const rows = table.querySelectorAll('tr'); rows.forEach(row => { const rowData = ; const cells = row.querySelectorAll('td, th'); cells.forEach(cell => { rowData.push(cell.textContent.trim()); }); data.push(rowData); }); // Tạo workbook và sheet const wb = XLSX.utils.book_new(); const ws = XLSX.utils.aoa_to_sheet(data); // Áp dụng style // Lấy tất cả các ô trong sheet const range = XLSX.utils.decode_range(ws'!ref'); for (let R = range.s.r; R <= range.e.r; ++R) { for (let C = range.s.c; C <= range.e.c; ++C) { const cellAddress = {c: C, r: R}; const cellRef = XLSX.utils.encode_cell(cellAddress); const cell = wscellRef; // Nếu là header (th) if (R === 0) { cell.s = { fill: {fgColor: {rgb: 'FFB0C4DE'}}, // LightSteelBlue background font: {bold: true, color: {rgb: 'FF0000FF'}}, // Blue bold text alignment: {horizontal: 'center', vertical: 'center'}, border: { top: {style: 'thin', color: {rgb: 'FF000000'}}, bottom: {style: 'thin', color: {rgb: 'FF000000'}}, left: {style: 'thin', color: {rgb: 'FF000000'}}, right: {style: 'thin', color: {rgb: 'FF000000'}} } }; } else { // For data rows, apply alternating row color const isEven = R % 2 === 0; cell.s = { fill: {fgColor: {rgb: isEven ? 'FFFFFFFF' : 'FFF0F8FF'}}, // white or AliceBlue alignment: {horizontal: 'left', vertical: 'center'}, border: { bottom: {style: 'thin', color: {rgb: 'FFCCCCCC'}}, left: {style: 'thin', color: {rgb: 'FFCCCCCC'}}, right: {style: 'thin', color: {rgb: 'FFCCCCCC'}} } }; } // Nếu là cột số, đặt format số if (C === 1 || C === 2) { // giả sử cột 1 (Age) và 2 (Salary) là số cell.z = '#,##0'; } } } // Thêm sheet vào workbook XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); // Xuất file XLSX.writeFile(wb, filename);
}

Hàm trên thực hiện các bước cơ bản:

  1. Thu thập dữ liệu từ bảng.
  2. Tạo workbook và sheet.
  3. Áp dụng style cho header và dữ liệu.
  4. Định dạng số.
  5. Xuất file.

Để kích hoạt hàm, bạn có thể đặt một nút Export và gọi exportTableToExcel('myTable', 'report.xlsx') khi người dùng nhấp vào.

2.3. Bảo toàn các style CSS trong bảng

Trong thực tế, bảng HTML có thể có nhiều class và style tùy chỉnh. Để chuyển các style này sang Excel, bạn phải:

  • Phân tích các style inline hoặc class trong bảng.
  • Chuyển đổi các thuộc tính CSS sang đối tượng style Excel.
  • Áp dụng style cho từng ô trong SheetJS.

SheetJS không tự động chuyển đổi CSS, vì vậy bạn cần viết một hàm ánh xạ tùy chỉnh. Dưới đây là một ví dụ đơn giản:

function cssToExcelStyle(element) { const style = window.getComputedStyle(element); const excelStyle = {}; // Màu nền const bg = style.backgroundColor; if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') { excelStyle.fill = {fgColor: {rgb: rgbToHex(bg)}}; } // Font excelStyle.font = { name: style.fontFamily.replace(/"/g, ''), sz: parseInt(style.fontSize), color: {rgb: rgbToHex(style.color)}, bold: style.fontWeight === 'bold' || parseInt(style.fontWeight) >= 700, italic: style.fontStyle === 'italic', }; // Định dạng số (đơn giản) if (style.textAlign === 'right') { excelStyle.numFmt = '#,##0.00'; immigrant? // Example; adjust as needed } // Border const borders = {}; const sides = 'Top', 'Bottom', 'Left', 'Right'; sides.forEach(side => { const width = style`border${side}Width`; const styleVal = style`border${side}Style`; const color = style`border${side}Color`; if (width && styleVal && color && width !== '0px') { bordersside.toLowerCase() = { style: styleVal, color: {rgb: rgbToHex(color)} }; } }); if (Object.keys(borders).length) excelStyle.border = borders; return excelStyle;
} function rgbToHex(rgb) { // rgb or rgba const result = rgb.match(/\d+/g); if (!result) return 'FFFFFF'; return result.slice(0,3).map(v => { const hex = parseInt(v).toString(16); return hex.length === 1 ? '0' + hex : hex; }).join('').toUpperCase();
}

Hàm cssToExcelStyle sẽ lấy style tính toán của một phần tử và chuyển đổi sang định dạng Excel. Khi lặp qua các ô, bạn có thể gọi hàm này và gán vào wsref.s = cssToExcelStyle(cell). Tuy nhiên, để tối ưu, bạn nên chỉ áp dụng style hedge cho các ô cần thiết, tránh lặp lại style không cần thiết.

3. Xử lý dữ liệu phức tạp: Định dạng ngày tháng, số, ký tự đặc biệt

Export Html Table To Excel With Style Javascript
Export Html Table To Excel With Style Javascript

Excel hỗ trợ nhiều kiểu dữ liệu, trong đó ngày tháng và số là hai trong số quan trọng nhất. Khi xuất dữ liệu từ HTML sang Excel, bạn cần đảm bảo định dạng đúng để tránh dữ liệu bị đọc sai.

3.1. Định dạng ngày tháng

Trong bảng HTML, ngày tháng thường được lưu dưới dạng chuỗi dd/mm/yyyy hoặc mm/dd/yyyy. Để Excel nhận dạng đúng, bạn có thể:

  • Chuyển chuỗi thành đối tượng Date trong JavaScript.
  • Chỉ định z (number format) cho ô vào Excel.

Ví dụ:

// Giả sử cell chứa ngày tháng dưới dạng '31/12/2026'
const dateStr = cell.textContent.trim();
const parts = dateStr.split('/');
const dateObj = new Date(`${parts2}-${parts1}-${parts0}`); // yyyy-mm-dd // Khi tạo cell trong SheetJS
const cell = { t: 'd', v: dateObj };
cell.z = 'dd/mm/yyyy'; // Định dạng hiển thị
wsref = cell;

3.2. Định dạng số

Excel mặc định sẽ tự động nhận dạng số, nhưng nếu bạn muốn định dạng số có dấu phẩy, dấu thập phân, phần trăm, bạn có thể đặt z cho ô.

cell.z = '#,##0.00'; // Hai chữ số thập phân
cell.z = '0%'; // Phần trăm

3.3. Ký tự đặc biệt và encoding

Để tránh lỗi khi xuất file, hãy đảm bảo:

  • Dùng encodeURIComponent khi cần.
  • Chuyển đổi ký tự đặc biệt sang Unicode.
  • Đảm bảo xlsx.full.min.js đã được tải đúng phiên bản.

4. Bài thực hành: Export bảng HTML sang Excel với style chi tiết

Trong phần này, chúng ta sẽ tạo một trang web mẫu hoàn chỉnh: một bảng HTML có nhiều style, một nút Export, và toàn bộ đoạn JavaScript thực hiện chuyển đổi. Bài viết sẽ được chia thành các phần:

  • HTML: Định nghĩa bảng, nút Export.
  • CSS: Style cho bảng (màu nền, font, border).
  • JavaScript: Hàm export, chuyển style, xuất file.

4.1. HTML

<!DOCTYPE html>
<html lang="vi">
<head> <meta charset="UTF-8"> <title>Export HTML Table to Excel with Style</title> <link rel="stylesheet" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body> <h1>Bảng dữ liệu mẫu</h1> <table id="myTable"> <thead> <tr> <th bako="text-align:center;background:#ffc107;color:#ffffff">STT</th> <th>Họ và Tên</th> <th>Tuổi</th> <th באַקומען="text-align:right;background:#28a745;color:#ffffff">Lương (VNĐ)</th> <th>Ngày Nhận</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Nguyễn Văn A</td> <td>30</td> <td>10,000,000</td> <td>15/08/2026</td> </tr> <tr> <td>2</td> <td>Trần Thị B</td> <td>28</td> <td>8,500,000</td> <td>20/08/2026</td> </tr> <tr> <td>3</td> <td>Lê Văn C</td> <td>35</td> <td>12,000,000</td> <td>05/09/2026</td> roofing? </tr> </tbody> </table> <button id="exportBtn">Export to Excel</button> <script src="script.js"></script>
</body>
</html>

4.2. CSS (style.css)

body { font-family: Arial, sans-serif; margin: 20px;
} table { width: 100%; border-collapse: collapse;
} th, td { padding: 8px 12px; border: 1px solid #dddddd; text-align: left;
} th { background-color: #f2f2f2;
} tr:nth-child(even) { background-color: #fafafa;
}

4.3. JavaScript (script.js)

// Hàm chuyển đổi RGB sang HEX
function rgbToHex(rgb) { const result = rgb.match(/\d+/g); if (!result) return 'FFFFFF'; return result.slice(0, 3).map(v => { const hex = parseInt(v).toString(16); return hex.length === 1 ? '0' + hex : hex; }).join('').toUpperCase();
} // Hàm chuyển đổi style CSS sang Excel
function cssToExcelStyle(element) { const style = window.getComputedStyle(element); const excelStyle = {}; // Màu nền const bg = style.backgroundColor; if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') { excelStyle.fill = {fgColor: {rgb: rgbToHex(bg)}}; } // તરફ excelStyle.font = { name: style.fontFamily.replace(/"/g, ''), sz: parseInt(style.fontSize), color: {rgb: rgbToHex(style.color)}, bold: style.fontWeight === 'bold' || parseInt(style.fontWeight) >= 700, italic: style.fontStyle === 'italic', }; // Địnhigent excelStyle.alignment = { horizontal: style.textAlign, vertical: style.verticalAlign || 'center', }; // Border const borders = {}; const sides = 'Top', 'Bottom', 'Left', 'Right'; sides.forEach(side =>ীক্ষা { const width = style`border${side}Width`; const styleVal = style`border${side}Style`; const color = style`border${side}Color`; if (width && styleVal && color && width !== '0px') { bordersside.toLowerCase().Low { style: styleVal, color: {rgb: rgbToHex(color)} }; } }); if (Object.keys(borders).length) excelStyle.border = borders; return excelStyle;
} // Hàm export
function exportTableToExcel(tableId, filename = 'report.xlsx') { const table = document.getElementById(tableId); if (!table) { console.error('Không tìm thấy bảng có id', tableId); return; } const data = ; const rows = table.querySelectorAll('trodesk'); rows.forEach(row => { const rowData = ; const cells = row.querySelectorAll('td, th'); cells.forEach(cell => { rowData.push(cell.textContent.trim()); }); data.push(rowData); }); const wb = XLSX.utils.book_new(); const ws = XLSX.utils.aoa_to_sheet(data); // Áp dụng style const range = XLSX.utils.decode_range(ws'!ref'); for (let R = range.s.r; R <= range.e.r; ++R) { for (let C = range.s.c; C <= range.e.c; ++C) { const cellAddress軟 {c: C, r: R}; const cellRef = XLSX.utils.encode_cell(cellAddress); const cell = wscellRef; // Lấy phần tử trong bảng để lấy style const tableCell = table.rowsR 데.cellsC; if (tableCell) { const style = cssToExcelStyle(tableCell); cell.s = style; } // Định dạng số, ngày if (C === 2) { // Tuổi cell.z = '#,##0'; } if (C === 3) { // Lương cell.z = '#,##0'; } if (C === 4) { // Ngày nhận const dateStr = cell.v.trim(); const parts = dateStr.split('/'); if (parts.length === 3) { const dateObj = new Date(`${parts2}-${parts1}-${parts0}`); cell.t = 'd'; cell.v = dateObj; cell.z = 'dd/mm/yyyy'; } } } } XLSX.utils.book_append_sheet(wb, ws, 'Bảng Dữ Liệu'); XLSX.writeFile(wb, filename);
} // Gắn sự kiện
document.getElementById('exportBtn').addEventListener('click', () => { exportTableToExcel('myTable', 'bảng-dữ-liệu.xlsx');
});

Kết quả: Khi người dùng nhấn nút “Export to Excel”, file bảng-dữ-liệu.xlsx sẽ được tải về. Khi mở file trong Excel, bảng sẽ giữ nguyên màu nền, font chữ, border, và định dạng số/điểm trong Excel. Các ô ngày tháng sẽ được hiển thị dưới dạng ngày thực, không phải chuỗi văn bản.

5. Tối ưu và mở rộng: Đa sheet, dữ liệu lớn, bảo mật

5.1. Đưa nhiều sheet vào workbook

SheetJS cho phép bạn thêm nhiều sheet vào cùng một workbook. Khi cần xuất nhiều bảng, bạn có thể gọi XLSX.utils.aoa_to_sheet(data) cho mỗi bảng, rồi XLSX.utils.book_append_sheet(wb, ws, sheetName). Ví dụ:

// Giả sử có 2 bảng: myTable1, myTable2
exportTableToExcelWithMultipleSheets पछ
function exportMultipleSheets() { const wb = XLSX.utils.book_new(); {id:'myTable1', name:'Sheet1'}, {id:'myTable2', name:'Sheet2'} .forEach(item => { const table = document.getElementById(item.id); const data = ; const rows = table.querySelectorAll('tr'); rows.forEach(row => { const rowData = ; const cells = row.querySelectorAll('td, th'); cells.forEach(cell => rowData.push(cell.textContent.trim())); data.push(rowData); }); const ws = XLSX.utils.aoa_to_sheet(data); XLSX.utils.book_append_sheet(wb, ws, item.name); }); XLSX.writeFile(wb, 'multi-sheet.xlsx');
}

5.2. Xử lý dữ liệu lớn (> 10k dòng)

SheetJS hỗ trợ “streaming” khi viết file bằng phương thức XLSX.write với bookType: 'xlsx' và bookSST: true. Tuy nhiên, vì JavaScript chạy trong trình duyệt, bộ nhớ vẫn có giới hạn. Để tránh tràn bộ nhớ, bạn có thể:

  • Phân trang dữ liệu trước khi export.
  • Sử dụng Web Workers để xử lý dữ liệu trong thread khác.
  • Trả về file từ server (Node.js) thay vì client.

5.3. Bảo mật và quyền truy cập

Khi xuất dữ liệu nhạy cảm, bạn nên:

  • Kiểm tra quyền của người dùng trên server trước khi gửi dữ liệu.
  • Đặt mật khẩu cho file Excel (SheetJS hỗ trợ password trong XLSX.writeFile).
  • Không lưu file tạm trên server, chỉ tạo file và chuyển tiếp ngay.

6. Kết luận và những lời khuyên thực hành

Export bảng HTML sang Excel với style không chỉ giúp người dùng lưu trữ dữ liệu một cách tiện lợi mà còn giúp công việc báo cáo trở nên chuyên nghiệp hơn. Dưới đây là một số lời khuyên:

  • Sử dụng thư viện SheetJS: Đó là thư viện mạnh nhất, hỗ trợ đầy đủ các tính năng và có cộng đồng lớn. Nếu bạn cần tính năng phức tạp (định dạng ngày, màu sắc, tính năng bảo mật) thì không nên tự viết code từ đầu.
  • Phân tách logic: Tránh viết logic chuyển đổi style trực tiếp trong hàm export. Tạo một hàm riêng để chuyển đổi CSS sang Excel style giúp code dễ bảo trì.
  • Kiểm tra dữ liệu: Đảm bảo dữ liệu không chứa ký tự đặc biệt hoặc chuỗi có thể gây lỗi khi Excel mở file.
  • Tối ưu: Khi dữ liệu lớn, hãy xử lý từng chunk, hoặc chuyển sang server-side.
  • Bảo mật: Nếu dữ liệu nhạy cảm, hãy đặt mật khẩu hoặc tạo file trên server và gửi link tải xuống.

Với những kiến thức và ví dụ trên, hy vọng bạn có thể triển khai tính năng export bảng HTML sang Excel với style một cách dễ dàng và linh hoạt trong các dự án của mình. Chúc bạn thành công!

⚠️
LƯU Ý QUAN TRỌNG: Miễn trừ trách nhiệm: Mặc dù chúng tôi luôn nỗ lực để đảm bảo tính chính xác và cập nhật của thông tin, nhưng các quy định về giáo dục và tuyển sinh có thể thay đổi theo thời gian. BigSchool không chịu trách nhiệm về bất kỳ sai sót nào hoặc kết quả phát sinh từ việc sử dụng thông tin trên trang này. Độc giả nên liên hệ trực tiếp với nhà trường hoặc cơ quan chức năng để có thông tin mới nhất. Ngoài ra, BigSchool tuyệt đối không bán sản phẩm, khóa học hay cung cấp dịch vụ được nhắc đến trong bài.

Viết một bình luận