Chuyển CSV sang Bảng HTML
Chuyển đổi CSV sang bảng HTML
Đầu vào CSV
Đầu ra HTML
Chuyển đổi CSV sang Bảng HTML là gì?
Chuyển đổi CSV sang bảng HTML lấy các giá trị phân tách bằng dấu phẩy và biến chúng thành đánh dấu HTML có cấu trúc mà trình duyệt có thể hiển thị thành bảng trực quan. Đầu ra sử dụng các phần tử bảng HTML chuẩn được định nghĩa trong HTML Living Standard: table, thead, tbody, tr, th và td. Quá trình này ánh xạ mỗi hàng CSV thành phần tử tr và mỗi trường thành ô td hoặc th.
Các tệp CSV lưu trữ dữ liệu dưới dạng văn bản thuần túy với các hàng được phân tách bằng ký tự xuống dòng và các trường được phân tách bằng dấu phân cách (thường là dấu phẩy). Mặc dù CSV hoạt động tốt cho việc lưu trữ và truyền dữ liệu giữa các ứng dụng như Excel, Google Sheets và cơ sở dữ liệu, nhưng nó không có lớp trình bày. Bảng HTML bổ sung lớp đó bằng cách bọc dữ liệu trong đánh dấu ngữ nghĩa hỗ trợ tạo kiểu bằng CSS, sắp xếp bằng JavaScript và khả năng truy cập qua các thuộc tính như scope và aria-label.
Quá trình chuyển đổi phải xử lý một số trường hợp ngoại lệ được định nghĩa trong RFC 4180: các trường có dấu ngoặc kép chứa dấu phẩy hoặc ký tự xuống dòng, dấu ngoặc kép được thoát trong các trường, và các dấu phân cách khác nhau (dấu chấm phẩy, tab, dấu gạch đứng). Một bộ chuyển đổi đúng cũng thoát các thực thể HTML trong nội dung ô, thay thế <, >, & và ký tự dấu ngoặc kép bằng các thực thể tương đương để ngăn chặn đánh dấu bị hỏng hoặc lỗ hổng XSS.
Tại sao dùng bộ chuyển đổi CSV sang Bảng HTML?
Xây dựng bảng HTML bằng tay rất tẻ nhạt và dễ mắc lỗi, đặc biệt với các tập dữ liệu có hàng chục cột hoặc hàng trăm hàng. Bộ chuyển đổi này xử lý việc phân tích cú pháp, thoát ký tự và định dạng trong một bước duy nhất.
Các trường hợp sử dụng chuyển đổi CSV sang Bảng HTML
Tài liệu tham khảo phần tử Bảng HTML
Một bảng HTML có cấu trúc tốt sử dụng các phần tử ngữ nghĩa phân tách tiêu đề, nội dung và chân trang. Trình đọc màn hình và công cụ tìm kiếm sử dụng các phần tử này để hiểu cấu trúc bảng. Nhóm các hàng bằng thead, tbody và tfoot cho phép trình duyệt áp dụng cuộn độc lập và lặp lại hàng tiêu đề trong bố cục in.
| Phần tử | Vai trò | Ghi chú |
|---|---|---|
| <table> | Table root | Wraps the entire table structure |
| <thead> | Header group | Contains header rows; browsers repeat on print page breaks |
| <tbody> | Body group | Contains data rows; enables independent scrolling with CSS |
| <tfoot> | Footer group | Summary or totals row; renders after tbody |
| <tr> | Table row | Groups cells horizontally |
| <th> | Header cell | Bold and centered by default; supports scope attribute for accessibility |
| <td> | Data cell | Standard content cell; accepts any inline or block HTML |
| <caption> | Table caption | Visible title above the table; read by screen readers first |
| <colgroup> | Column group | Applies width or style to entire columns without per-cell classes |
CSV vs Bảng HTML
CSV là định dạng truyền tải được tối ưu hóa cho sự đơn giản, trong khi HTML là định dạng trình bày được tối ưu hóa cho việc hiển thị, khả năng truy cập và tương tác trong trình duyệt.
Ví dụ mã nguồn
Dưới đây là cách chuyển đổi CSV sang bảng HTML theo chương trình trong các ngôn ngữ khác nhau. Mỗi ví dụ xử lý hàng tiêu đề riêng biệt và thoát các thực thể HTML trong nội dung ô. Các đoạn mã này sẵn sàng để đưa vào script, pipeline build hoặc endpoint API backend tạo báo cáo HTML từ dữ liệu xuất.
// CSV string → HTML table with thead/tbody
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`
function csvToHtmlTable(csv) {
const rows = csv.trim().split('\n').map(r => r.split(','))
const [headers, ...data] = rows
const ths = headers.map(h => `<th>${h}</th>`).join('')
const trs = data.map(row =>
' <tr>' + row.map(c => `<td>${c}</td>`).join('') + '</tr>'
).join('\n')
return `<table>
<thead><tr>${ths}</tr></thead>
<tbody>
${trs}
</tbody>
</table>`
}
console.log(csvToHtmlTable(csv))
// → <table><thead><tr><th>name</th>...</tr></thead><tbody>...</tbody></table>import csv, io, html
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""
reader = csv.reader(io.StringIO(csv_string))
headers = next(reader)
lines = ['<table>', ' <thead>', ' <tr>']
for h in headers:
lines.append(f' <th>{html.escape(h)}</th>')
lines += [' </tr>', ' </thead>', ' <tbody>']
for row in reader:
lines.append(' <tr>')
for cell in row:
lines.append(f' <td>{html.escape(cell)}</td>')
lines.append(' </tr>')
lines += [' </tbody>', '</table>']
print('\n'.join(lines))
# → well-formed HTML table with escaped special characters<?php
$csv = "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo";
$rows = array_map('str_getcsv', explode("\n", trim($csv)));
$headers = array_shift($rows);
echo "<table>\n <thead>\n <tr>\n";
foreach ($headers as $h) {
echo " <th>" . htmlspecialchars($h) . "</th>\n";
}
echo " </tr>\n </thead>\n <tbody>\n";
foreach ($rows as $row) {
echo " <tr>\n";
foreach ($row as $cell) {
echo " <td>" . htmlspecialchars($cell) . "</td>\n";
}
echo " </tr>\n";
}
echo " </tbody>\n</table>";
// → <table><thead>...<th>name</th>...</thead><tbody>...</tbody></table># Using awk — quick one-liner for simple CSV (no quoted fields)
awk -F, 'NR==1{print "<table><thead><tr>";for(i=1;i<=NF;i++)print "<th>"$i"</th>";print "</tr></thead><tbody>"}
NR>1{print "<tr>";for(i=1;i<=NF;i++)print "<td>"$i"</td>";print "</tr>"}
END{print "</tbody></table>"}' data.csv
# Using Python one-liner for RFC 4180-compliant parsing
python3 -c "
import csv, sys, html
r=csv.reader(sys.stdin); h=next(r)
print('<table><thead><tr>')
print(''.join(f'<th>{html.escape(c)}</th>' for c in h))
print('</tr></thead><tbody>')
for row in r:
print('<tr>'+''.join(f'<td>{html.escape(c)}</td>' for c in row)+'</tr>')
print('</tbody></table>')
" < data.csv