203 lines
7.6 KiB
HTML
203 lines
7.6 KiB
HTML
<!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>
|