vue2把后端响应数据保存ex表格

在 Vue 中实现点击按钮将后端响应的数据导出为 .xlsx 文件,可以使用 axios 进行数据请求,并结合 xlsxfile-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-saversaveAs(): 将 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("导出失败,请检查数据或重试!");
    }
}

使用这个方法
image
image
显示效果
image

作者:freps

出处:https://www.cnblogs.com/freps/p/18653325

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   LL。。。  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示