1.效果
2.实现代码
首先要加载Handsontable,在示例中我是cdn的方式引入的,vue的话需要下载插件
let hot = null;
var exportPlugin = null;
function showHandsontable(param) {
const container = document.getElementById("hot-container");
// 如果已有实例,先销毁
if (hot) {
hot.destroy();
}
hot = new Handsontable(container, {
data: [], // 初始为空
colHeaders: true, // 动态列头
rowHeaders: true, // 动态行头
width: "100%",
height: 800,
licenseKey: "non-commercial-and-evaluation", // 免费版许可证
contextMenu: true, // 启用右键菜单
manualColumnResize: true, // 允许调整列宽
manualRowResize: true, // 允许调整行高
filters: true, // 启用筛选
dropdownMenu: true, // 启用下拉菜单
columnSorting: true, // 启用列排序
stretchH: "all", // 列宽自适应
afterChange: function (changes, source) {
if (source === "edit") {
console.log("数据已修改:", changes);
}
},
});
}
showHandsontable();
点击后开始加载数据,注意colHeaders,rowHeaders,是行和列的名称,是数组格式
updateSettings:更新表格数据和表头
loadData:重新加载数据
document
.getElementById("load-data")
.addEventListener("click", async function () {
try {
const response = await mockApiCall();
console.log(response, "这时候弄-");
// 更新表格数据和表头
hot.updateSettings({
colHeaders: response.headers.columns,
rowHeaders: response.headers.rows,
});
hot.loadData(response.data);
exportPlugin = hot.getPlugin("exportFile");
console.log("数据加载成功");
} catch (error) {
console.error("加载数据失败:", error);
}
3.下载表格
主要用到downloadFile和hot.getPlugin("exportFile")下载格式为csv,目前在Handsontable官网没有看到可以下载xlsx格式的,可能需要xlsx插件
button.addEventListener("click", () => {
//下载表格的数据
exportPlugin.downloadFile("csv", {
bom: false,
columnDelimiter: ",",
columnHeaders: true,//显示表头
exportHiddenColumns: true,
exportHiddenRows: true,
fileExtension: "csv",
filename: "Handsontable-CSV-file_[YYYY]-[MM]-[DD]",
mimeType: "text/csv",
rowDelimiter: "\r\n",
rowHeaders: true,
});
//改为下载报表接口数据
});
4.完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>动态表格示例 - Handsontable</title>
<!-- <script src="./handsontable.full.min.js"></script>
<link rel="stylesheet" href="./handsontable.full.min.css" /> -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/handsontable/15.0.0/handsontable.full.min.js"
integrity="sha512-3Os2SFklHFmIWzqQsBOmpA9fYBiar8ASBI4hqgeUKttdJ6lDWli7W+JmXyN8exab8NOpiYT441s6hfqX6Tx+WA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/handsontable/15.0.0/handsontable.full.min.css"
integrity="sha512-reELraG6l/OUbRy0EnDh2RxkanfohOkWJX7afyUG1aGHv49SA9uqrAcJOMhyCNW6kcwbnhePc6JKcdUsQxmjvw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
#hot-container {
margin-top: 20px;
}
.controls {
margin-bottom: 10px;
}
button {
padding: 8px 12px;
margin-right: 10px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>动态表格示例</h1>
<div class="controls">
<button id="load-data">加载数据</button>
<button id="export-file">下载表格</button>
</div>
<div id="hot-container"></div>
<!-- <script src="app.js"></script> -->
<script type="text/javascript">
let hot = null;
var exportPlugin = null;
function showHandsontable(param) {
const container = document.getElementById("hot-container");
// 如果已有实例,先销毁
if (hot) {
hot.destroy();
}
hot = new Handsontable(container, {
data: [], // 初始为空
colHeaders: true, // 动态列头
rowHeaders: true, // 动态行头
width: "100%",
height: 800,
licenseKey: "non-commercial-and-evaluation", // 免费版许可证
contextMenu: true, // 启用右键菜单
manualColumnResize: true, // 允许调整列宽
manualRowResize: true, // 允许调整行高
filters: true, // 启用筛选
dropdownMenu: true, // 启用下拉菜单
columnSorting: true, // 启用列排序
stretchH: "all", // 列宽自适应
afterChange: function (changes, source) {
if (source === "edit") {
console.log("数据已修改:", changes);
}
},
});
}
showHandsontable();
// 加载数据按钮事件
document
.getElementById("load-data")
.addEventListener("click", async function () {
try {
const response = await mockApiCall();
console.log(response, "这时候弄-");
// 更新表格数据和表头
hot.updateSettings({
colHeaders: response.headers.columns,
rowHeaders: response.headers.rows,
});
hot.loadData(response.data);
exportPlugin = hot.getPlugin("exportFile");
console.log("数据加载成功");
} catch (error) {
console.error("加载数据失败:", error);
}
});
function mockApiCall() {
return new Promise((resolve) => {
// 模拟网络延迟
setTimeout(() => {
const mockData = {
headers: {
columns: ["ID", "姓名", "年龄", "部门", "薪资"],
rows: Array.from({ length: 15 }, (_, i) => `员工${i + 1}`),
},
data: Array.from({ length: 15 }, (_, i) => [
i + 1000,
`员工${i + 1}`,
Math.floor(Math.random() * 20) + 20,
["研发部", "市场部", "人事部", "财务部"][
Math.floor(Math.random() * 4)
],
(Math.random() * 10000 + 5000).toFixed(2),
]),
};
resolve(mockData);
}, 500);
});
}
const button = document.querySelector("#export-file");
button.addEventListener("click", () => {
//下载表格的数据
exportPlugin.downloadFile("csv", {
bom: false,
columnDelimiter: ",",
columnHeaders: false,
exportHiddenColumns: true,
exportHiddenRows: true,
fileExtension: "csv",
filename: "Handsontable-CSV-file_[YYYY]-[MM]-[DD]",
mimeType: "text/csv",
rowDelimiter: "\r\n",
rowHeaders: true,
});
//改为下载报表接口数据
});
</script>
</body>
</html>
文章到此结束,希望对你有所帮助~