设计思路
创建一个现代简约的界面,包含上传区域和表格显示区域
使用SheetJS库解析Excel文件
添加响应式设计,确保在不同设备上良好显示
实现拖放上传功能,提升用户体验
下面是完整实现代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Excel在线查看器</title>
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background-color: white;
border-radius: 12px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
header {
background: linear-gradient(135deg, #4b6cb7 0%, #182848 100%);
color: white;
padding: 25px;
text-align: center;
}
h1 {
font-size: 2.2rem;
margin-bottom: 10px;
}
.description {
font-size: 1.1rem;
opacity: 0.9;
max-width: 700px;
margin: 0 auto;
}
.upload-section {
padding: 30px;
text-align: center;
border-bottom: 1px solid #eee;
}
.upload-area {
border: 3px dashed #4b6cb7;
border-radius: 10px;
padding: 40px;
margin: 20px auto;
max-width: 600px;
background-color: #f8fafd;
transition: all 0.3s;
cursor: pointer;
}
.upload-area:hover, .upload-area.dragover {
background-color: #e8eff9;
border-color: #2b5bb5;
}
.upload-icon {
font-size: 50px;
color: #4b6cb7;
margin-bottom: 15px;
}
.upload-text {
margin-bottom: 20px;
font-size: 1.2rem;
}
.browse-btn {
display: inline-block;
background: linear-gradient(135deg, #4b6cb7 0%, #182848 100%);
color: white;
padding: 12px 25px;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s;
border: none;
}
.browse-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(75, 108, 183, 0.3);
}
#file-input {
display: none;
}
.display-section {
padding: 20px;
overflow: auto;
}
.excel-info {
margin-bottom: 15px;
padding: 10px;
background-color: #f0f4f8;
border-radius: 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
th, td {
border: 1px solid #ddd;
padding: 12px 15px;
text-align: left;
}
th {
background-color: #4b6cb7;
color: white;
position: sticky;
top: 0;
}
tr:nth-child(even) {
background-color: #f8fafd;
}
tr:hover {
background-color: #e8f0fe;
}
.no-data {
text-align: center;
padding: 40px;
color: #777;
font-style: italic;
}
.sheet-selector {
margin-bottom: 15px;
padding: 8px 15px;
border-radius: 6px;
border: 1px solid #ddd;
background-color: white;
font-size: 1rem;
}
.instructions {
padding: 20px;
background-color: #f8fafd;
border-radius: 8px;
margin-top: 20px;
}
.instructions h3 {
margin-bottom: 10px;
color: #4b6cb7;
}
.instructions ul {
padding-left: 20px;
}
.instructions li {
margin-bottom: 8px;
}
@media (max-width: 768px) {
.upload-area {
padding: 20px;
}
h1 {
font-size: 1.8rem;
}
table {
font-size: 0.9rem;
}
th, td {
padding: 8px 10px;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Excel在线查看器</h1>
<p class="description">上传您的Excel文件,无需安装任何软件即可在线查看内容</p>
</header>
<div class="upload-section">
<div class="upload-area" id="drop-area">
<div class="upload-icon">📊</div>
<p class="upload-text">拖放Excel文件到此处,或点击下方按钮选择文件</p>
<input type="file" id="file-input" accept=".xlsx, .xls, .csv">
<button class="browse-btn" onclick="document.getElementById('file-input').click()">选择Excel文件</button>
</div>
</div>
<div class="display-section">
<div class="excel-info">
<div id="file-info">尚未选择文件</div>
<select class="sheet-selector" id="sheet-selector" style="display: none;"></select>
</div>
<div id="table-container">
<div class="no-data">请上传Excel文件以查看内容</div>
</div>
<div class="instructions">
<h3>使用说明</h3>
<ul>
<li>支持.xlsx、.xls和.csv格式的Excel文件</li>
<li>您的文件仅在浏览器中处理,不会上传到任何服务器</li>
<li>如果Excel文件包含多个工作表,可以使用上方下拉菜单切换</li>
<li>最大支持10MB的文件</li>
</ul>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const dropArea = document.getElementById('drop-area');
const fileInput = document.getElementById('file-input');
const tableContainer = document.getElementById('table-container');
const fileInfo = document.getElementById('file-info');
const sheetSelector = document.getElementById('sheet-selector');
let workbook = null;
// 防止默认拖放行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// 高亮拖放区域
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dropArea.classList.add('dragover');
}
function unhighlight() {
dropArea.classList.remove('dragover');
}
// 处理文件拖放
dropArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
// 处理文件选择
fileInput.addEventListener('change', function() {
handleFiles(this.files);
});
function handleFiles(files) {
if (files.length === 0) return;
const file = files[0];
if (!isExcelFile(file)) {
alert('请选择Excel文件(.xlsx, .xls, .csv)');
return;
}
if (file.size > 10 * 1024 * 1024) {
alert('文件大小不能超过10MB');
return;
}
fileInfo.textContent = `文件: ${file.name} (${formatFileSize(file.size)})`;
const reader = new FileReader();
reader.onload = function(e) {
const data = new Uint8Array(e.target.result);
processExcelData(data);
};
reader.readAsArrayBuffer(file);
}
function isExcelFile(file) {
const allowedExtensions = ['.xlsx', '.xls', '.csv'];
const fileName = file.name.toLowerCase();
return allowedExtensions.some(ext => fileName.endsWith(ext));
}
function formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' bytes';
else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
else return (bytes / 1048576).toFixed(1) + ' MB';
}
function processExcelData(data) {
try {
workbook = XLSX.read(data, {type: 'array'});
// 显示工作表选择器(如果有多个工作表)
if (workbook.SheetNames.length > 1) {
sheetSelector.style.display = 'block';
sheetSelector.innerHTML = '';
workbook.SheetNames.forEach((name, index) => {
const option = document.createElement('option');
option.value = index;
option.textContent = name;
sheetSelector.appendChild(option);
});
sheetSelector.addEventListener('change', function() {
displaySheet(this.value);
});
} else {
sheetSelector.style.display = 'none';
}
// 显示第一个工作表
displaySheet(0);
} catch (e) {
console.error('处理Excel文件时出错:', e);
alert('处理Excel文件时出错,请确保文件格式正确');
}
}
function displaySheet(sheetIndex) {
if (!workbook) return;
const worksheet = workbook.Sheets[workbook.SheetNames[sheetIndex]];
const jsonData = XLSX.utils.sheet_to_json(worksheet, {header: 1});
if (jsonData.length === 0) {
tableContainer.innerHTML = '<div class="no-data">此工作表为空</div>';
return;
}
// 创建表格
let tableHTML = '<table><thead>';
// 添加表头(使用第一行数据)
tableHTML += '<tr>';
jsonData[0].forEach(cell => {
tableHTML += `<th>${cell}</th>`;
});
tableHTML += '</tr></thead><tbody>';
// 添加表格数据(跳过第一行)
for (let i = 1; i < jsonData.length; i++) {
tableHTML += '<tr>';
jsonData[i].forEach(cell => {
tableHTML += `<td>${cell}</td>`;
});
tableHTML += '</tr>';
}
tableHTML += '</tbody></table>';
tableContainer.innerHTML = tableHTML;
}
});
</script>
</body>
</html>
