CSV to HTML 표 변환기
CSV를 HTML 테이블로 변환
CSV 입력
HTML 출력
CSV to HTML 테이블 변환이란?
CSV to HTML 테이블 변환은 쉼표로 구분된 값을 브라우저가 시각적 표로 렌더링할 수 있는 구조화된 HTML 마크업으로 변환합니다. 출력은 HTML Living Standard에 정의된 표준 HTML 테이블 요소인 table, thead, tbody, tr, th, td를 사용합니다. 이 과정에서 각 CSV 행은 tr 요소에, 각 필드는 td 또는 th 셀에 매핑됩니다.
CSV 파일은 행이 줄바꿈으로 구분되고 필드가 구분자(일반적으로 쉼표)로 구분되는 일반 텍스트로 데이터를 저장합니다. CSV는 Excel, Google Sheets, 데이터베이스 같은 애플리케이션 간 데이터 저장 및 전송에는 적합하지만 표현 계층이 없습니다. HTML 테이블은 CSS로 스타일링하고, JavaScript로 정렬하고, scope 및 aria-label 같은 속성으로 접근성을 지원하는 시맨틱 마크업으로 데이터를 감싸 그 계층을 추가합니다.
변환 시 RFC 4180에서 정의한 여러 엣지 케이스를 처리해야 합니다. 쉼표나 줄바꿈을 포함하는 따옴표 필드, 필드 내 이스케이프된 큰따옴표, 다양한 구분자(세미콜론, 탭, 파이프)가 이에 해당합니다. 올바른 변환기는 셀 내용의 HTML 엔티티도 이스케이프하여 <, >, &, 따옴표 문자를 해당 엔티티 형식으로 치환함으로써 깨진 마크업이나 XSS 취약점을 방지합니다.
CSV to HTML 테이블 변환기를 사용하는 이유
HTML 테이블을 직접 작성하는 것은 특히 수십 개의 열이나 수백 개의 행을 가진 데이터셋에서는 지루하고 오류가 발생하기 쉽습니다. 이 변환기는 파싱, 이스케이프, 서식 지정을 한 번에 처리합니다.
CSV to HTML 테이블 활용 사례
HTML 테이블 요소 참조
잘 구조화된 HTML 테이블은 헤더, 본문, 푸터를 분리하는 시맨틱 요소를 사용합니다. 화면 읽기 프로그램과 검색 엔진은 이러한 요소를 사용하여 테이블 구조를 이해합니다. thead, tbody, tfoot으로 행을 그룹화하면 브라우저가 독립적인 스크롤을 적용하고 인쇄 레이아웃에서 헤더 행을 반복할 수 있습니다.
| 요소 | 역할 | 비고 |
|---|---|---|
| <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 HTML 테이블
CSV는 단순성에 최적화된 전송 형식이고, HTML은 브라우저에서의 렌더링, 접근성, 인터랙티브성에 최적화된 표현 형식입니다.
코드 예제
다양한 언어로 CSV를 HTML 테이블로 프로그래밍 방식으로 변환하는 방법입니다. 각 예제는 헤더 행을 별도로 처리하고 셀 내용의 HTML 엔티티를 이스케이프합니다. 이 코드 조각들은 스크립트, 빌드 파이프라인, 데이터 내보내기에서 HTML 보고서를 생성하는 백엔드 API 엔드포인트에 바로 사용할 수 있습니다.
// 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