vue2把后端响应数据保存ex表格
在 Vue 中实现点击按钮将后端响应的数据导出为 .xlsx
文件,可以使用 axios
进行数据请求,并结合 xlsx
和 file-saver
库完成文件的生成和下载。
以下是完整实现步骤:
1. 安装依赖库#
运行以下命令安装所需的库:
npm install xlsx file-saver axios
2. 创建导出功能#
组件代码示例#
<template>
<div>
<button @click="exportExcel">导出数据为 Excel 文件</button>
</div>
</template>
<script>
import axios from "axios";
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
export default {
name: "ExportExcel",
methods: {
async exportExcel() {
try {
// 发送请求获取后端数据
const response = await axios.get("/api/v1/data-to-export", {
responseType: "json", // 确保返回的数据是 JSON 格式
});
// 假设后端返回的数据结构如下:
// response.data = [
// { name: "张三", age: 25, city: "杭州" },
// { name: "李四", age: 30, city: "上海" }
// ]
const data = response.data;
// 将数据转换为工作表格式
const worksheet = XLSX.utils.json_to_sheet(data);
// 创建工作簿并添加工作表
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "活跃数据");
// 将工作簿转换为 Blob 对象
const excelBuffer = XLSX.write(workbook, {
bookType: "xlsx",
type: "array",
});
// 使用 file-saver 保存文件
const blob = new Blob([excelBuffer], {
type: "application/octet-stream",
});
saveAs(blob, "活跃数据.xlsx");
} catch (error) {
console.error("导出失败:", error);
}
},
},
};
</script>
<style scoped>
button {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>
3. 后端响应接口#
确保后端接口返回 JSON 格式的数据。例如:
Node.js 示例#
app.get("/api/v1/data-to-export", (req, res) => {
const data = [
{ name: "张三", age: 25, city: "杭州" },
{ name: "李四", age: 30, city: "上海" },
];
res.json(data);
});
4. 功能解析#
axios.get()
: 从后端获取数据。XLSX.utils.json_to_sheet()
: 将 JSON 数据转换为工作表。XLSX.utils.book_new()
和XLSX.utils.book_append_sheet()
: 创建工作簿并附加工作表。XLSX.write()
: 将工作簿转换为二进制数据。file-saver
的saveAs()
: 将 Blob 对象保存为文件并触发下载。
5. 效果#
点击按钮时,将触发请求,获取后端数据,并生成并下载 .xlsx
文件。下载文件名为 活跃数据.xlsx
。
如果有更多需求(如文件格式或数据处理),可以在转换前对数据进行处理或增加其他逻辑。
6.项目中使用#
<template>
<div>
<button style="margin-left: 95%;border: none;background-color: white;color: blue;" @click="refresh">刷新</button>
<el-divider></el-divider>
<div style="height: 160px;">
<el-row :gutter="20">
<el-col :span="4">
<div>
<el-statistic :value="data.newly_added_users_yesterday" title="昨日新增用户"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.retain_the_next_day" title="次日留存"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.day3_retention" title="3日留存"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.day7_retention" title="7日留存"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.day30_retention" title="30日留存"></el-statistic>
</div>
</el-col>
</el-row>
<hr style="width: 90%;margin-top: 2%;margin-bottom: 2%;">
<el-col :span="4">
<div>
<el-statistic :value="data.next_day_retention_rate" title="次日留存率"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.day3_retention_rate" title="3日留存率"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.Dday7_retention_rate" title="7日留存率"></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div>
<el-statistic :value="data.day30_retention_rate" title="30日留存率"></el-statistic>
</div>
</el-col>
</div>
<el-divider></el-divider>
<div class="container">
<p style="margin-right: 2%;">{{ date }}</p>
<button style="border: none;background-color: white;color: blue;" @click="exportAsExc">导出</button>
</div>
<div style="border: 1px solid #e0e6f1;">
<DateSelection style="margin-top: 2%;" />
<div style="width: 100%;height: 400px;">
<BarChart :chart-data="barChartData" />
</div>
</div>
</div>
</template>
<script>
import BarChart from './components/BarChart.vue';
import DateSelection from './components/DateSelection.vue';
import { retentionDataBase } from '@/api/basic';
import { saveAs } from "file-saver";
import { mapGetters } from 'vuex';
export default {
components: {
BarChart,
DateSelection
},
computed: {
...mapGetters({
getGraphData: 'retentionOverview/getGraphData'
})
},
data() {
return {
data: {
day3_retention: 0,
day3_retention_rate: 0,
day7_retention: 0,
Dday7_retention_rate: 0,
day30_retention: 0,
day30_retention_rate: 0,
newly_added_users_yesterday: 0,
next_day_retention_rate: 0,
retain_the_next_day: 0
},
date: "",
like: true,
value1: 4154.564,
value2: 1314,
title: "总用户",
barChartData: {
xAxisData: ['12-13', '12-14', '12-15', '12-17', '12-18', '12-19', '12-20', '12-21', '12-22', '12-23', '12-24', '12-25'],
seriesData: [120, 200, 150, 80, 70, 110, 130, 123, 32, 12, 20, 60]
}
};
},
mounted() {
this.date = "更新时间:" + new Date().toLocaleString();
this.retentionDataBase();
},
methods: {
exportAsExc() {
import("xlsx").then((XLSX) => {
try {
if (!this.getGraphData || this.getGraphData.length === 0) {
this.$message.error("没有数据可导出");
return;
}
// 将数据转换为工作表格式
const worksheet = XLSX.utils.json_to_sheet(this.getGraphData);
// 创建工作簿并添加工作表
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "活跃数据");
// 将工作簿转换为 Blob 对象
const excelBuffer = XLSX.write(workbook, {
bookType: "xlsx",
type: "array",
});
// 使用 file-saver 保存文件
const blob = new Blob([excelBuffer], {
type: "application/octet-stream",
});
saveAs(blob, "活跃数据.xlsx");
this.$message.success("数据导出成功!");
} catch (error) {
console.error("导出失败:", error);
this.$message.error("导出失败,请检查数据或重试!");
}
});
},
refresh() {
location.reload();
this.date = "更新时间:" + new Date().toLocaleString();
},
retentionDataBase() {
retentionDataBase().then(res => {
this.data = res;
console.log(res);
}).catch(error => {
console.error('Error fetching list data:', error);
});
},
}
};
</script>
<style lang="scss">
.like {
cursor: pointer;
font-size: 25px;
display: inline-block;
}
.container {
display: flex;
justify-content: flex-end;
}
</style>
7.封装成一个方法#
/**
* 把后端返回数据导出为excel类型文件
*/
import { saveAs } from "file-saver";
import * as XLSX from "xlsx";
export function exportExcel(data, fileName, onSuccess, onError) {
try {
if (!data || data.length === 0) {
if (onError) onError("没有数据可导出");
return;
}
// 将数据转换为工作表格式
const worksheet = XLSX.utils.json_to_sheet(data);
// 创建工作簿并添加工作表
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "活跃数据");
// 将工作簿转换为 Blob 对象
const excelBuffer = XLSX.write(workbook, {
bookType: "xlsx",
type: "array",
});
// 使用 file-saver 保存文件
const blob = new Blob([excelBuffer], {
type: "application/octet-stream",
});
saveAs(blob, fileName + ".xlsx");
if (onSuccess) onSuccess("数据导出成功!");
} catch (error) {
console.error("导出失败:", error);
if (onError) onError("导出失败,请检查数据或重试!");
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix