vue3实现纯前端表格数据的导出与导入

打印 上一主题 下一主题

主题 909|帖子 909|积分 2727

项目场景:

我期望告竣在纯前端环境下举行 excel 表格文件的下载操作,与此同时,对所下载的表格文件的样式加以调整与优化,使其出现出更符合需求的外观和格式结构,从而满意特定的展示与使用要求。

表格数据导出


1、安装 xlsx-js-style

提示:这里形貌项目中碰到的问题:
先安装库 xlsx-js-style
  1. npm install xlsx-js-style
复制代码

2、自界说组件

   自界说组件,这里附全部代码,设置单元格格式代码也在其中
  1. <script lang="ts" setup>
  2. import { computed, nextTick, ref, watch } from "vue"
  3. import * as XLSX from "xlsx-js-style"
  4. interface Props {
  5.   modelValue: boolean
  6.   downloadList: any
  7.   columnList: any
  8. }
  9. const props = withDefaults(defineProps<Props>(), {
  10.   modelValue: false,
  11.   downloadList: [],
  12.   columnList: []
  13. })
  14. const downloadList = computed(() => props.downloadList)
  15. const emit = defineEmits<{
  16.   (e: "update:modelValue", value: boolean): boolean
  17. }>()
  18. const columnList = computed(() => props.columnList)
  19. //#region 导出
  20. const tableRef = ref<any>(null)
  21. // 导出为 Excel
  22. const exportToExcel = () => {
  23.   // 获取 el-table 的引用
  24.   tableRef.value = document.querySelector("#download-table")
  25.   // 将 el-table 数据转换为二维数组
  26.   const dataArray = []
  27.   const headers: any = []
  28.   tableRef.value.querySelectorAll(".el-table__header-wrapper th").forEach((th: any) => {
  29.     headers.push(th.textContent.trim())
  30.   })
  31.   dataArray.push(headers)
  32.   const rowsToExport = tableRef.value.querySelectorAll(".el-table__body-wrapper tbody tr")
  33.   console.log(rowsToExport, "rowsToExport")
  34.   rowsToExport.forEach((row: any) => {
  35.     const rowData: any = []
  36.     row.querySelectorAll("td").forEach((cell: any) => {
  37.       rowData.push(cell.textContent.trim())
  38.     })
  39.     dataArray.push(rowData)
  40.   })
  41.   // 创建一个新的工作簿
  42.   const workbook = XLSX.utils.book_new()
  43.   // 创建一个新的工作表
  44.   const worksheet = XLSX.utils.aoa_to_sheet(dataArray)
  45.   console.log(dataArray, "dataArray")
  46.   // 设置列宽
  47.   const columnWidth = 20 // 列宽为20个字符
  48.   const numColumns = dataArray[0].length // 获取列数
  49.   worksheet["!cols"] = Array(numColumns).fill({ wch: columnWidth })
  50.   // // 设置列高
  51.   const rowHeight = 105 // 行高为110像素
  52.   const numRows = dataArray.length // 获取行数
  53.   worksheet["!rows"] = Array(numRows).fill({ hpx: rowHeight })
  54.   worksheet["!rows"][0] = { hpx: 15 } // 单独设置第一行的行高
  55.   // 设置单元格样式
  56.   const cellStyle = {
  57.     font: {
  58.       name: "微软黑体", // 字体名称
  59.       sz: 13, // 字体大小
  60.       color: { rgb: "000000" }, // 字体颜色
  61.       bold: false // 字体不加粗
  62.     },
  63.     border: {
  64.       top: { style: "thin", color: { rgb: "000000" } },
  65.       bottom: { style: "thin", color: { rgb: "000000" } },
  66.       left: { style: "thin", color: { rgb: "000000" } },
  67.       right: { style: "thin", color: { rgb: "000000" } }
  68.     },
  69.     alignment: {
  70.       horizontal: "center",
  71.       vertical: "center",
  72.       wrapText: true // 设置文字自动换行
  73.     }
  74.   }
  75.   // 遍历数据数组,为每个单元格应用样式
  76.   dataArray.forEach((row, rowIndex) => {
  77.     row.forEach((cell: any, columnIndex: any) => {
  78.       const cellAddress = XLSX.utils.encode_cell({ c: columnIndex, r: rowIndex })
  79.       worksheet[cellAddress].s = cellStyle
  80.     })
  81.   })
  82.   // 表头颜色加粗
  83.   if (dataArray[0]) {
  84.     dataArray[0].forEach((cell: any, columnIndex: any) => {
  85.       const cellAddress = XLSX.utils.encode_cell({ c: columnIndex, r: 0 })
  86.       worksheet[cellAddress].s = { ...cellStyle, font: { ...cellStyle.font, bold: true } } // 确保表头字体加粗
  87.     })
  88.   }
  89.   // 将工作表添加到工作簿
  90.   XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1")
  91.   // 将工作簿保存为 Excel 文件
  92.   const timestamp = new Date().getTime()
  93.   const fileName = `宝贝统计_${timestamp}.xlsx`
  94.   XLSX.writeFile(workbook, fileName)
  95.   emit("update:modelValue", false)
  96. }
  97. //#endregion
  98. watch(
  99.   () => props.modelValue,
  100.   (value: any) => {
  101.     if (value) {
  102.       console.log(downloadList.value)
  103.       nextTick(() => {
  104.         exportToExcel()
  105.       })
  106.     }
  107.   }
  108. )
  109. </script>
  110. <template>
  111.   <el-table style="display: none" :data="downloadList" id="download-table">
  112.     <el-table-column
  113.       v-for="(item, index) in columnList"
  114.       :key="index"
  115.       :prop="item.prop"
  116.       :label="item.label"
  117.       align="center"
  118.     />
  119.   </el-table>
  120. </template>
  121. <style lang="scss" scoped></style>
复制代码

3、使用

   使用是时候是相当于在页面上设置个不可间=见的表格举行下载 将需要下载的数据传入即可,可以举行改进,表单项也传入,这样就可以随意下载任何数据了
  1. import DownloadExcel from "@/components/DownloadExcel/index.vue"
  2. const columnList = [
  3.   {
  4.     prop: "index",
  5.     label: "序号"
  6.   },
  7.   {
  8.     prop: "username",
  9.     label: "用户名"
  10.   },
  11.   {
  12.     prop: "roles",
  13.     label: "角色"
  14.   },
  15.   {
  16.     prop: "phone",
  17.     label: "手机号"
  18.   },
  19.   {
  20.     prop: "email",
  21.     label: "邮箱"
  22.   },
  23.   {
  24.     prop: "status",
  25.     label: "状态"
  26.   },
  27.   {
  28.     prop: "createTime",
  29.     label: "创建时间"
  30.   }
  31. ]
  32. const downloadList = ref<any[]>([])
  33. const isDownload = ref<boolean>(false)
  34. const exportToExcel = () => {
  35.   if (multipleSelection.value.length == 0) {
  36.     ElMessage.error("请选择要下载的宝贝")
  37.     return
  38.   }
  39.   downloadList.value = multipleSelection.value.map((item: any, index: number) => {
  40.     return {
  41.       index: index, // 序号
  42.       username: item.username, // 用户名
  43.       roles: item.roles, // 角色
  44.       phone: item.phone, // 手机号
  45.       email: item.email, // 邮箱
  46.       status: item.status ? "启用" : "禁用", // 状态
  47.       createTime: item.createTime // 创建时间
  48.     }
  49.   })
  50.   isDownload.value = true
  51. }
复制代码
  1. <download-excel v-model="isDownload" :downloadList="downloadList" :columnList="columnList" />
  2. <div>
  3.   <el-tooltip content="下载">
  4.     <el-button type="primary" :icon="Download" circle @click="exportToExcel" />
  5.   </el-tooltip>
  6. </div>
复制代码

表格数据导入


1、安装 xlsx

  1. npm install xlsx --save
复制代码
2、引入

  1. import * as XLSX from "xlsx"
复制代码
3、使用

  1. <el-upload
  2.   class="upload-demo"
  3.   ref="upload"
  4.   action=""
  5.   :auto-upload="false"
  6.   accept=""
  7.   :on-change="analysisExcel"
  8.   multiple
  9.   :show-file-list="false"
  10. >
  11.   <el-button type="primary" :icon="Link">导入文件列表</el-button>
  12. </el-upload>
复制代码
  1. import * as XLSX from "xlsx"
  2. const loading = ref<boolean>(false)const tableData = ref<any[]>([])const analysisExcel = (file: any) => {  loading.value = true  console.log(file)  // 只能上传一个Excel,重复上传会覆盖之前的  file = file.raw  const reader = new FileReader()  reader.readAsArrayBuffer(file)  reader.onload = function () {    const buffer: any = reader.result    const bytes = new Uint8Array(buffer)    const length = bytes.byteLength    let binary = ""    for (let i = 0; i < length; i++) {      binary += String.fromCharCode(bytes[i])    }    const wb = XLSX.read(binary, {      type: "binary"    })    const outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])    console.log(outdata)    let da = [...outdata]    // 这里是把表格里面的名称改成表格里面的字段    da = da.map((item: any) => {      const newItem = {        index: Number(item["序号"]), // 序号        username: item["用户名"], // 用户名        roles: item["脚色"], // 脚色        phone: item["手机号"], // 手机号        email: item["邮箱"], // 邮箱        status: item["状态"], // 状态        createTime: item["创建时间"] // 创建时间      }      return newItem    })    console.log(da)    tableData.value = da    loading.value = false  }}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

反转基因福娃

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表