纯前端导出表格数据 -- csv格式 (含表格末尾的自动合计行)

简介: 纯前端导出表格数据 -- csv格式 (含表格末尾的自动合计行)

核心代码详见代码中的注释

<template>
  <div class="page">
    <el-button type="primary" size="small" @click="exportOut">导出</el-button>
    <div class="tableBox">
      <el-table
        :data="tableData"
        border
        :summary-method="getSummaries"
        show-summary
      >
        <el-table-column
          v-for="(item, index) in tableTitleList"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          align="center"
        >
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sumRow: {},
      tableTitleList: [
        {
          label: "序号",
          prop: "id",
          width: 100,
        },
        {
          label: "姓名",
          prop: "name",
        },
        {
          label: "射击次数",
          prop: "total",
        },
        {
          label: "命中次数",
          prop: "hitNum",
        },
        {
          label: "命中率",
          prop: "hitRate",
        },
      ],
      tableData: [
        {
          id: "1",
          name: "张三",
          total: 100,
          hitNum: 10,
          hitRate: "10%",
        },
        {
          id: "2",
          name: "王五",
          total: 100,
          hitNum: 20,
          hitRate: "20%",
        },
      ],
    };
  },
  methods: {
    // 导出为 csv 格式的文件
    exportOut() {
      // 生成时间戳,避免每次导出的文件重名
      let timeStamp = new Date().getTime();
      // 在数据末尾添加合计行
      let data = [...this.tableData, this.sumRow];
      downloadCsv(this.tableTitleList, data, `导出的数据_${timeStamp}.csv`);
    },
    // 自定义末尾的合计逻辑
    getSummaries(param) {
      const { columns, data } = param;
      const sumDic = {};
      columns.forEach((column, index) => {
        // 第 1 列
        if (index === 0) {
          sumDic[column.property] = "合计";
          return;
        }

        // 需特殊计算的列
        if (column.property === "hitRate") {
          sumDic[column.property] =
            ((sumDic["hitNum"] / sumDic["total"]) * 100).toFixed(2) + "%";
          return;
        }

        // 其他列默认求和
        const values = data.map((item) => Number(item[column.property]));
        if (!values.every((value) => isNaN(value))) {
          // 可以求和的列
          sumDic[column.property] = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + curr;
            } else {
              return prev;
            }
          }, 0);
        } else {
          // 无法求和的列
          sumDic[column.property] = "——";
        }
      });

      // 指定列添加单位
      sumDic["total"] += " 次";
      sumDic["hitNum"] += " 次";
      // 获取末尾的合计行
      this.sumRow = sumDic;
      return Object.values(sumDic);
    },
  },
};

// 纯js导出 csv 格式文件
function downloadCsv(header, data, fileName = "导出结果.csv") {
  if (
    !header ||
    !data ||
    !Array.isArray(header) ||
    !Array.isArray(data) ||
    !header.length ||
    !data.length
  ) {
    return;
  }
  var csvContent = "data:text/csv;charset=utf-8,\ufeff";
  const _header = header.map((h) => h.label).join(",");
  const keys = header.map((item) => item.prop);
  csvContent += _header + "\n";
  data.forEach((item, index) => {
    let dataString = "";
    for (let i = 0; i < keys.length; i++) {
      dataString += item[keys[i]] + ",";
    }
    csvContent +=
      index < data.length
        ? dataString.replace(/,$/, "\n")
        : dataString.replace(/,$/, "");
  });
  const a = document.createElement("a");
  a.href = encodeURI(csvContent);
  a.download = fileName;
  a.click();
  window.URL.revokeObjectURL(csvContent);
}
</script>

<style scoped>
.page {
  padding: 30px;
}
.tableBox {
  margin: 20px 0px;
}
</style> 
目录
相关文章
|
1月前
|
存储 监控 安全
前端框架的数据驱动方式如何保证数据的安全性?
总之,前端框架的数据驱动方式需要综合运用多种手段来保证数据的安全性。从传输、存储、访问控制到防范攻击等各个方面进行全面考虑和实施,以确保用户数据的安全可靠。同时,不断加强安全管理和技术创新,以应对不断变化的安全挑战。
107 60
|
1月前
|
前端开发 API
前端界面生成PDF并导出下载
【10月更文挑战第21天】利用合适的第三方库,你可以在前端轻松实现界面生成 PDF 并导出下载的功能,为用户提供更方便的文档分享和保存方式。你还可以根据具体的需求进一步优化和定制生成的 PDF 文件,以满足不同的业务场景要求。
|
2月前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
2月前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
2月前
|
NoSQL 前端开发 MongoDB
前端的全栈之路Meteor篇(三):运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例
MiniMongo 是 Meteor 框架中的客户端数据库组件,模拟了 MongoDB 的核心功能,允许前端开发者使用类似 MongoDB 的 API 进行数据操作。通过 Meteor 的数据同步机制,MiniMongo 与服务器端的 MongoDB 实现实时数据同步,确保数据一致性,支持发布/订阅模型和响应式数据源,适用于实时聊天、项目管理和协作工具等应用场景。
|
2月前
|
存储 前端开发 API
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
123 0
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
187 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
49 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。