Browse Source

表格导出

zhongxiaoyu 2 years ago
parent
commit
41ba4de420

+ 3 - 1
package.json

@@ -26,6 +26,7 @@
     "echarts": "5.3.2",
     "el-table-infinite-scroll": "^3.0.1",
     "element-plus": "^2.2.9",
+    "file-saver": "^2.0.5",
     "js-error-collection": "^1.0.7",
     "mitt": "^3.0.0",
     "moment-mini": "2.22.1",
@@ -35,7 +36,8 @@
     "pinia": "^2.0.16",
     "tinymce": "4.9.11",
     "vue": "^3.2.37",
-    "vue-router": "4.0.14"
+    "vue-router": "4.0.14",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@babel/eslint-parser": "7.16.3",

+ 4 - 1
src/components/tableTemp/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-table v-el-table-infinite-scroll="load" :row-key="
+  <el-table ref="table" v-el-table-infinite-scroll="load" :row-key="
       props.tableProperty.rowKey
         ? props.tableProperty.rowKey
         : tablePropertyDefault.rowKey
@@ -223,8 +223,11 @@ const load = () => {
   emit("load", true);
 };
 
+const table = ref(null)
+
 defineExpose({
   cellClass,
+  table
 });
 </script>
 

+ 1 - 1
src/views/baggageManagement/components/CountBox/index.vue

@@ -29,7 +29,7 @@ const props = defineProps({
     default: '总数',
   },
 })
-const numberBoxes = ref<HTMLInputElement[] | undefined[]>([])
+const numberBoxes = ref<HTMLElement[] | undefined[]>([])
 const numberItems = computed(() => {
   let numberString = props.countNumber.toString()
   if (numberString.length > props.length) {

+ 7 - 1
src/views/baggageManagement/departure/flight/index.vue

@@ -66,6 +66,7 @@ import Search from "@/components/search/index.vue";
 import tableColumnSet from "@/components/tableColumnSet/index.vue";
 import {CaretRight} from "@element-plus/icons-vue"
 import { ref } from 'vue';
+import useTableExport from "../../hooks/useTableExport";
 
 const state = reactive({
   tableHeader: [
@@ -205,9 +206,14 @@ const refresh=(data) =>{
   console.log(data)
 }
 
+const domeTable = ref(null)
+const { exportToExcel } = useTableExport()
 //点击下载按钮
 const downLoad=(data) =>{
-  console.log(data)
+  const tableRef = ref(domeTable.value.table)
+  exportToExcel({
+    tableRef
+  })
 }
 
 //点击列设置按钮

+ 62 - 0
src/views/baggageManagement/hooks/useTableExport.ts

@@ -0,0 +1,62 @@
+import { Ref } from 'vue'
+import { ElMessage, ElTable } from 'element-plus'
+import * as XLSX from 'xlsx'
+import FileSaver from 'file-saver'
+
+interface ExportOptions {
+  tableRef: Ref<InstanceType<typeof ElTable>>
+  sheetName?: string
+  fileName?: string
+  headerRowNumber?: number
+}
+
+type ExportHandler = (option: ExportOptions) => void
+
+export default function useTableExport() {
+  const exportToExcel: ExportHandler = ({
+    tableRef,
+    sheetName = 'sheet1',
+    fileName = '导出表格.xlsx',
+    headerRowNumber = 1,
+  }) => {
+    try {
+      const tableNode = (tableRef.value.$el as HTMLElement).cloneNode(
+        true
+      ) as HTMLElement
+      // 设置了列的fixed属性后会有两个table元素,导出数据会重复,需要去掉一个table
+      const fixedTable = tableNode.querySelector('.el-table__fixed')
+      fixedTable && tableNode.removeChild(fixedTable)
+      // 自定义的表头里包含筛选,直接导出会把筛选的下拉数据也写到表头单元格里,需要先去掉筛选弹出框
+      const tableHeaderCellPopovers = tableNode.querySelectorAll(
+        '.table-header-cell-popover'
+      )
+      tableHeaderCellPopovers.forEach(node => {
+        const childNode = node.querySelector('.el-popover')
+        if (childNode) {
+          node.removeChild(childNode)
+        }
+      })
+      // 生成要导出的xlsx数据对象,raw: true表示不使用excel的格式解析,输出为纯文本,sheet设置xlsx这一页的标题
+      const tableBook = XLSX.utils.table_to_book(tableNode, {
+        raw: true,
+        sheet: sheetName,
+      })
+      const tableBuffer = XLSX.write(tableBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true,
+      })
+      FileSaver.saveAs(
+        new Blob([tableBuffer], { type: 'application/octet-stream' }),
+        fileName
+      )
+    } catch (error: any) {
+      ElMessage.error(error.message)
+    }
+  }
+
+  return {
+    exportToExcel,
+  }
+}