初始化
This commit is contained in:
commit
e66c90cd95
|
|
@ -0,0 +1,202 @@
|
||||||
|
<!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>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue