如何用JavaScript读取CSV/XLSX文件转HTML表格并解决CSV空列问题
问题诱因
- 文件类型校验未兼容CSV:现有代码仅放行
.xlsx/.xls格式对应的MIME类型,CSV文件默认会被拦截,若你自行修改过校验规则,后续解析逻辑也未做CSV适配。 - 空列核心来源:
- CSV文件本身行尾可能存在多余逗号,XLSX库在
header:1模式下解析时,会将末尾逗号对应生成空元素,渲染为多余空列。 - 部分UTF-8编码的CSV带BOM头,用
ArrayBuffer方式读取时BOM不会被自动过滤,会导致首行数组出现多余空元素。 - 非UTF-8编码的CSV(如GBK编码的中文CSV)用
ArrayBuffer解析时容易出现乱码、空值,进而产生空列。
- CSV文件本身行尾可能存在多余逗号,XLSX库在
修复方案
按以下步骤修改代码即可同时兼容CSV和xlsx/xls格式:
- 扩展文件类型校验规则,新增CSV格式的后缀判断,避免合法CSV被拦截。
- 解析完成后手动过滤每行的空值元素,消除多余空列。
- 针对CSV文件优化读取方式,自动处理编码和BOM问题。
完整修改后代码
<!DOCTYPE HTML> <html> <head> <script type="text/javascript" src="https://unpkg.com/xlsx@0.15.1/dist/xlsx.full.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h2 class="text-center mt-4 mb-4">用JavaScript将Excel/CSV转为HTML表格</h2> <div class="card"> <div class="card-header"><b>选择文件</b></div> <div class="card-body"> <input type="file" id="excel_file" accept=".xlsx,.xls,.csv" /> </div> </div> <div id="excel_data" class="mt-5"></div> </div> </body> </html> <script> const excel_file = document.getElementById('excel_file'); excel_file.addEventListener('change', (event) => { const file = event.target.files[0]; // 扩展文件校验,支持CSV const allowedExt = ['xlsx', 'xls', 'csv']; const fileExt = file.name.split('.').pop().toLowerCase(); if (!allowedExt.includes(fileExt)) { document.getElementById('excel_data').innerHTML = '<div class="alert alert-danger">仅允许.xlsx、.xls或.csv格式文件</div>'; excel_file.value = ''; return false; } const reader = new FileReader(); // CSV文件用文本模式读取处理编码问题,Excel文件用ArrayBuffer读取 if (fileExt === 'csv') { reader.readAsText(file, 'UTF-8'); } else { reader.readAsArrayBuffer(file); } reader.onload = function(event) { let work_book; if (fileExt === 'csv') { work_book = XLSX.read(event.target.result, { type: 'string' }); } else { const data = new Uint8Array(reader.result); work_book = XLSX.read(data, { type: 'array' }); } const sheet_name = work_book.SheetNames; let sheet_data = XLSX.utils.sheet_to_json(work_book.Sheets[sheet_name[0]], { header: 1, skipEmptyLines: true // 自动跳过空行 }); // 核心修复:过滤每行的空值元素,消除多余空列 sheet_data = sheet_data.map(row => row.filter(cell => { return cell != null && String(cell).trim() !== ''; })).filter(row => row.length > 0); // 过滤全空行 if (sheet_data.length > 0) { let table_output = '<table class="table table-striped table-bordered">'; for (let row = 0; row < sheet_data.length; row++) { table_output += '<tr>'; // 新增Serial列 if (row == 0) { table_output += '<th>Serial</th>' } else { table_output += '<td>' + row + '</td>' } // 渲染内容列 for (let cell = 0; cell < sheet_data[row].length; cell++) { if (row == 0) { table_output += '<th>' + sheet_data[row][cell] + '</th>'; } else { table_output += '<td>' + sheet_data[row][cell] + '</td>'; } } table_output += '</tr>'; } table_output += '</table>'; document.getElementById('excel_data').innerHTML = table_output; } excel_file.value = ''; } }); </script>
内容的提问来源于stack exchange,提问作者WEI ZHUANG GOH
相关产品推荐
相关产品推荐

