vue3导出

1. pnpm i xlsx
2.工具

/* eslint-disable no-prototype-builtins */
import * as XLSX from 'xlsx';
/*
    * @description:
    * @param {Object} json 服务端发过来的数据
    * @param {String} name 导出Excel文件名字
		* @param titleObj 一个存放标题的字段(请根据展示顺序编写写) 格式如下  
			titleObj={
				云飒ID:'ysId',
				中文名称:字段名
			}
    * @param {String} sheetName 导出sheetName名字
*/
export function exportExcel(
  json: any,
  name: string,
  titleObj: object,
  sheetName: string
) {
  // 获取 所需要的中英文字段名
  const filterTitle: any = getObjVal(titleObj, 'value'); // 英文字段
  const titleArr: any = getObjVal(titleObj, 'key'); // 中文字段

  let data = []; // 最终存放的数据
  const tempData: any[] = []; // 筛选出的乱序数据
  const sortData = [] as any; // 排序后的数据
  // 筛选出符合条件的服务端数据
  for (const key1 in json) {
    if (json.hasOwnProperty(key1)) {
      const element = json[key1];
      const rowArr = [];
      for (const key2 in element) {
        if (element.hasOwnProperty(key2) && filterTitle.includes(key2)) {
          rowArr.push({
            label: key2,
            value: element[key2]
          });
        }
      }
      tempData.push(rowArr);
    }
  }
  // 对符合条件数据 按照titleObj 进行排序
  tempData.map((item: any) => {
    const arr = [] as any;
    filterTitle.map((item1: any) => {
      item.map((item2: any) => {
        if (item1 === item2.label) {
          arr.push(item2.value);
        }
      });
    });
    sortData.push(arr);
  });

  // //  隐藏英文字段 数据组装
  // data = [filterTitle, titleArr, ...sortData];
  // console.log("data", data);
  // const ws = XLSX.utils.aoa_to_sheet(data);
  // const wb = XLSX.utils.book_new();
  // 此处隐藏英文字段表头
  // let wsrows = [{ hidden: true }];
  // ws["!rows"] = wsrows; // ws - worksheet
  // XLSX.utils.book_append_sheet(wb, ws, sheetName);
  /* generate file and send to client */
  // XLSX.writeFile(wb, name + ".xlsx");

  // 不要英文字段
  // 数据组装
  data = [titleArr, ...sortData];
  console.log('data', data, sortData);
  const ws = XLSX.utils.aoa_to_sheet(data);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, sheetName);
  XLSX.writeFile(wb, name + '.xlsx');
}

/*
    * @description: 分别获取对象的键 或 值
    * @param {titleObj}  原始对象
		* @flag 标记  key 取键  value 取值 

*/
export function getObjVal(titleObj: any, flag: string) {
  const arr = [];
  // key 取key值
  if (flag == 'key') {
    for (const key in titleObj) {
      if (titleObj.hasOwnProperty(key)) {
        arr.push(key);
      }
    }
    return arr;
  }
  // value 取value 值
  if (flag == 'value') {
    for (const key in titleObj) {
      if (titleObj.hasOwnProperty(key)) {
        arr.push(titleObj[key]);
      }
    }
    return arr;
  }
}

3.使用

<template>
  <div>
    <Search :search="moreSearch" :reset="moreReset">
      <template v-slot:body>
        <el-form-item label="书名">
          <el-input v-model="query.book_name" name="book_name" clearable />
        </el-form-item>
        <el-form-item label="bid">
          <el-input v-model="query.bid" name="bid" clearable />
        </el-form-item>
        <el-form-item label="版权方">
          <el-select v-model="query.cp_name" filterable remote clearable :remote-method="remoteMethod"
            placeholder="选择版权方">
            <el-option v-for="item in cpoptions" :key="item.cp_id" :label="item.cp_name" :value="item.cp_name" />
          </el-select>
        </el-form-item>
        <el-form-item label="日期">
          <el-date-picker unlink-panels clearable @change="timeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
            v-model="query.time" type="daterange" :default-value="defaultTime2" :shortcuts="shortcuts"
            range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" />
        </el-form-item>
      </template>
      <template v-slot:extra_button>
        <el-button type="primary" @click="dataExport" size="default">
          <!-- <Icon name="document-arrow-up" className="w-4 h-4 mr-1 -ml-1" /> -->
          导出
        </el-button>
      </template>
    </Search>
    <div style="margin:8px 0;">
      <el-card shadow="hover" :body-style="{ padding: '20px' }">
        <div class="stat-wrapper">
          <div>订阅结算统计书币: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_total_coins || '暂无数据' }}</span></div>
          <div>订阅的总金额: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_available_amount || '暂无数据' }}</span>
          </div>
          <div>应结算金额: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_final_amount || '暂无数据' }}</span></div>
        </div>
      </el-card>
    </div>
    <div class="table-default">
      <!-- <Operate :show="open" /> -->
      <!-- <div class="set-warpper">
        <el-button type="primary" @click="testExport" size="default">导出</el-button>
      </div> -->
      <el-table :data="tableData" class="mt-3" v-loading="loading">
        <el-table-column prop="book_name" label="书名" />
        <el-table-column prop="bid" label="bid" />
        <el-table-column prop="cp_name" label="版权方" />
        <el-table-column prop="yesterday_total_coins" label="订单结算书币" />
        <el-table-column prop="yesterday_available_amount" label="订阅金额" />
        <el-table-column prop="yesterday_final_amount" label="应结算金额" />
        <el-table-column prop="book_settlement_type_str" label="书籍合作模式" />
        <el-table-column prop="date" label="创建时间" />
      </el-table>
      <Paginate />
    </div>

    <Dialog v-model="visible" :title="title" destroy-on-close>
      <Create @close="close(reset)" :primary="id" :api="api" />
    </Dialog>
  </div>
</template>

<script lang="ts" setup>
import {
  computed,
  onMounted,
  ref
} from 'vue';
import {
  useGetList
} from '@/hook/curd/useGetList';
import {
  useDestroy
} from '@/hook/curd/useDestroy';
import {
  useOpen
} from '@/hook/curd/useOpen';
import {
  MenuType
} from '@/enum/app';
// import table2excel from 'js-table2excel'
import moment from 'moment';
import { exportExcel } from '@/utils/exportExcel'
import { shortcuts } from '@/utils/shortcuts'
import http from '@/support/http';
import { cpOptions, subscribeStatisticDataList, subscribeStatisticDataListStatistic } from '@/api/cp/index';

const defaultTime2 = [
  moment().startOf('month'), moment().endOf('month')
]

const api = 'contentManage/cp/subscribeStatisticData/list';

const start_date = moment().startOf('month').format('YYYY-MM-DD')
const end_date = moment().endOf('month').format('YYYY-MM-DD')

const dataExport = () => {
  let exportTableData = ref([])
  subscribeStatisticDataList({ is_export: 1, ...query.value }).then(res => {
    console.log(res);
    exportTableData.value = res.data
    console.log(res, 'exportTableData', exportTableData.value);
    console.log(start_date, end_date);
    const titleObj = {
      "书名": "book_name",
      "bid": "bid",
      "版权方": "cp_name",
      "订单结算书币": "yesterday_total_coins",
      "订阅金额": "yesterday_available_amount",
      "应结算金额": "yesterday_final_amount",
      "书籍合作模式": "book_settlement_type_str",
      "创建时间": "date",
    };
    console.log(tableData.value, 'tableData.value', exportTableData.value);
    exportExcel(exportTableData.value, `数据中心${moment().format('YYYY-MM-DD HH:mm:ss')}`, titleObj, "数据中心");
  })
}

const timeChange = (e) => {
  if (query.value.time) {
    const timeArr = toRaw(e);
    query.value.start_date = timeArr[0]
    query.value.end_date = timeArr[1]
  } else {
    delete query.value.start_date
    delete query.value.end_date
  }
}


let { data, query, search, reset, loading } = useGetList(api, true);
const { destroy, deleted } = useDestroy();
const { open, close, title, visible, cp_id } = useOpen();
let cpoptions = ref([]);

let tableData = computed(() => data.value?.data);
let statisticalData = ref({})

const moreSearch = () => {
  search();
  subscribeStatisticDataListStatistic({ ...query.value }).then(res => {
    statisticalData.value = res.data
  })
}
const moreReset = () => {
  reset()
  subscribeStatisticDataListStatistic({ ...query.value }).then(res => {
    statisticalData.value = res.data
  })
}


const remoteMethod = (query: string) => {
  if (query) {
    console.log(66666);
    initCpOtion({ cp_name: query })
  } else {
    initCpOtion({})
  }
}
const initCpOtion = (params: object) => {
  cpOptions(params).then(res => {
    cpoptions.value = res.data
  })
}

onMounted(() => {
  query.value.time = [start_date, end_date];
  query.value.start_date = start_date;
  query.value.end_date = end_date;
  subscribeStatisticDataListStatistic({ ...query.value }).then(res => {
    statisticalData.value = res.data
  })
  initCpOtion({})
  search();
  deleted(reset);
});

</script>

<style lang="scss" scoped>
.stat-wrapper {
  display: flex;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;

  .stat {
    box-sizing: border-box;
    font-size: 18px;
    font-weight: 550;
    padding: 0 12px;
  }
}

.set-warpper {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值