web_export_xlsx/index.html

203 lines
7.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON数据导出为XLSX</title>
<!-- 引入Tailwind CSS -->
<script src="./tailwindcss.3.4.17.js"></script>
<!-- 引入Font Awesome -->
<!-- <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"> -->
<!-- 引入SheetJS库用于处理Excel文件 -->
<script src="./xlsx.full.min.js"></script>
<!-- 配置Tailwind自定义颜色和字体 -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#10B981',
neutral: '#64748B',
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<!-- 自定义工具类 -->
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.transition-custom {
transition: all 0.3s ease;
}
.shadow-custom {
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.02);
}
}
</style>
</head>
<body class="bg-gray-50 font-sans text-gray-800 min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- 页面标题 -->
<header class="mb-10 text-center">
<h1 class="text-[clamp(1.8rem,5vw,2.5rem)] font-bold text-gray-800 mb-3 tracking-tight">
JSON数据转XLSX工具
</h1>
<p class="text-neutral text-lg max-w-2xl mx-auto">
查看数据表格并导出为Excel文件方便进行进一步的数据处理和分析
</p>
</header>
<!-- 主内容区 -->
<main class="bg-white rounded-xl shadow-custom p-6 md:p-8 mb-8 transform hover:shadow-lg transition-custom">
<!-- 数据表格 -->
<!-- 导出按钮 -->
<div class="flex justify-center">
<button id="export-btn" class="bg-primary hover:bg-primary/90 text-white font-medium py-3 px-6 rounded-lg shadow-md flex items-center transition-custom transform hover:scale-105 active:scale-95 focus:outline-none focus:ring-2 focus:ring-primary/50">
<i class="fa fa-download mr-2"></i>
导出为XLSX文件
</button>
</div>
</main>
<!-- 页脚 -->
<footer class="text-center text-neutral text-sm">
<p>© 数据导出工具 | 使用SheetJS和Tailwind CSS构建</p>
</footer>
</div>
<!-- 成功提示框 -->
<div id="success-toast" class="fixed bottom-6 right-6 bg-secondary text-white px-6 py-3 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 flex items-center">
<i class="fa fa-check-circle mr-2"></i>
<span>文件导出成功!</span>
</div>
<script>
// 数据
const data = [
{ "name": "小王", "age": 18 },
{ "name": "小刘", "age": 18 },
{ "name": "小赵", "age": 18 }
];
// DOM元素
const tableBody = document.getElementById('data-table-body');
const exportBtn = document.getElementById('export-btn');
const successToast = document.getElementById('success-toast');
// 填充表格数据
function populateTable() {
tableBody.innerHTML = '';
data.forEach((item, index) => {
const row = document.createElement('tr');
row.className = index % 2 === 0 ? 'bg-white' : 'bg-gray-50';
row.classList.add('hover:bg-gray-100', 'transition-custom');
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">${item.name}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-500">${item.age}</div>
</td>
`;
tableBody.appendChild(row);
// 添加淡入动画
setTimeout(() => {
row.classList.add('opacity-100');
row.classList.remove('opacity-0', 'translate-y-2');
}, 50 * index);
});
}
// 导出为XLSX文件
function exportToXLSX() {
// 创建工作簿
const wb = XLSX.utils.book_new();
// 转换数据为工作表
// 调整数据键名以匹配中文表头
const formattedData = data.map(item => ({
"姓名": item.name,
"年龄": item.age
}));
const ws = XLSX.utils.json_to_sheet(formattedData);
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "人员信息");
// 生成并下载文件
XLSX.writeFile(wb, "人员信息表.xlsx");
// 显示成功提示
showSuccessToast();
}
// 显示成功提示
function showSuccessToast() {
successToast.classList.remove('translate-y-20', 'opacity-0');
successToast.classList.add('translate-y-0', 'opacity-100');
// 3秒后隐藏提示
setTimeout(() => {
successToast.classList.remove('translate-y-0', 'opacity-100');
successToast.classList.add('translate-y-20', 'opacity-0');
}, 3000);
}
// 事件监听
exportBtn.addEventListener('click', exportToXLSX);
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
populateTable();
// 为导出按钮添加点击波纹效果
exportBtn.addEventListener('click', function(e) {
const ripple = document.createElement('span');
const x = e.clientX - e.target.getBoundingClientRect().left;
const y = e.clientY - e.target.getBoundingClientRect().top;
ripple.style.width = ripple.style.height = Math.max(e.target.offsetWidth, e.target.offsetHeight) + 'px';
ripple.style.left = x - (parseInt(ripple.style.width) / 2) + 'px';
ripple.style.top = y - (parseInt(ripple.style.height) / 2) + 'px';
ripple.classList.add('ripple', 'absolute', 'bg-white', 'opacity-30', 'rounded-full', 'transform', 'scale-0', 'transition-transform', 'duration-600');
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
</script>
<style>
/* 波纹效果样式 */
#export-btn {
position: relative;
overflow: hidden;
}
/* 表格行初始状态(用于动画) */
#data-table-body tr {
opacity: 0;
transform: translateY(2px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
</style>
</body>
</html>