Vue项目中如何实现表格选中数据的 Excel 导出

一、安装

npm install xlsx

二、核心代码

javascript 复制代码
<template>
  <div class="statistics-container">
      <el-button type="primary" @click="handleExportSelected">导出选中</el-button>
      <el-table
        :data="tableData"
        border
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="index" label="序号" width="90" />
        <el-table-column prop="nickName" label="昵称" width="170" />
        <el-table-column prop="username" label="账号名" width="150" />
      </el-table>
  </div>
</template>

 <script lang="ts" setup>
import * as XLSX from "xlsx";
// 表格数据
const tableData = ref([]);

// 选中项
const selectedRows = ref<any[]>([]);
const handleSelectionChange = (val: any[]) => {
  selectedRows.value = val;
};
// 导出选中
const handleExportSelected = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请先选择要导出的数据");
    return;
  }

  // 准备导出数据
  const exportData = selectedRows.value.map((item) => {
    return {
      用户ID: item.userId,
      客户昵称: item.nickName,
      账号名: item.username,
    };
  });

  // 创建工作簿
  const ws = XLSX.utils.json_to_sheet(exportData);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "列表数据");

  // 导出文件
  const fileName = `列表数据_选中_${new Date().getTime()}.xlsx`;
  XLSX.writeFile(wb, fileName);

  ElMessage.success(`成功导出${selectedRows.value.length}条数据`);
};
</script>

三、设置表头样式、实现列宽自适应

安装xlsx-js-style,设置单元格样式

npm install xlsx-js-style

javascript 复制代码
import XLSX from "xlsx-js-style";
// 导出选中
const handleExportSelected = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请先选择要导出的数据");
    return;
  }

  // 准备导出数据
  const exportData = selectedRows.value.map((item) => {
    return {
      用户ID: item.userId,
      客户昵称: item.nickName,
      账号名: item.username,
    };
  });

  // 创建工作簿
  const ws = XLSX.utils.json_to_sheet(exportData);
  // 设置表头样式
  const headerStyle = {
    font: {
      name: "Arial",
      sz: 12,
      bold: true,
      color: { rgb: "000000" },
    },
    fill: {
      fgColor: { rgb: "f3fff1" },
    },
    alignment: {
      horizontal: "center",
      vertical: "center",
    },
    border: {
      top: { style: "thin", color: { rgb: "000000" } },
      bottom: { style: "thin", color: { rgb: "000000" } },
      left: { style: "thin", color: { rgb: "000000" } },
      right: { style: "thin", color: { rgb: "000000" } },
    },
  };

  // 应用表头样式
  const range = XLSX.utils.decode_range(ws["!ref"]);

  for (let col = range.s.c; col <= range.e.c; col++) {
    const cell = ws[XLSX.utils.encode_cell({ r: 0, c: col })];
    if (cell) {
      cell.s = headerStyle;
    }
  }

  // 设置列宽自适应
  const colWidths = [];
  for (let col = range.s.c; col <= range.e.c; col++) {
    let maxWidth = 10;
    for (let row = range.s.r; row <= range.e.r; row++) {
      const cell = ws[XLSX.utils.encode_cell({ r: row, c: col })];
      if (cell && cell.v) {
        const cellLength = cell.v.toString().length;
        if (cellLength > maxWidth) {
          maxWidth = cellLength;
        }
      }
    }
    // 限制最大宽度为50,最小宽度为20
    colWidths.push({ wch: Math.min(Math.max(maxWidth + 2, 20), 50) });
  }
  ws["!cols"] = colWidths;

  const wb = XLSX.utils.book_new();
  console.log(ws);

  XLSX.utils.book_append_sheet(wb, ws, "列表数据");

  // 导出文件
  const fileName = `列表数据_选中_${new Date().getTime()}.xlsx`;
  XLSX.writeFile(wb, fileName);

  ElMessage.success(`成功导出${selectedRows.value.length}条数据`);
};

四、效果展示

相关推荐
java1234_小锋1 小时前
【技术专题】HTML5 网页技术 - HTML5 Canvas 基础以及动画入门
前端·html·html5
知了学历孙老师4 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu6 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说7 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
程序员老赵8 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot8 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot8 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
狒狒AI9 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc
修炼的dance9 小时前
浏览器里导出H.265,8.5秒和55.5秒差在硬件
前端
补码缩写9 小时前
WebCodecs选编码器,探测之后还要验解码和播放
前端