表格 筛选列、导出Csv文件 、导出Excel文件、 打印功能

54 阅读1分钟

安装:npm i file-saver
npm i xlsx
html:

 <div class="icons">
        <!-- 筛选列 -->
        <el-tooltip class="item" effect="dark" content="筛选列" placement="bottom">
          <el-popover placement="right" trigger="click">
            <el-checkbox-group v-model="checkedColumns">
              <el-checkbox style="display: block; margin-bottom: 10px" v-for="item in checkBoxGroup" :key="item"
                :label="item" :value="item"></el-checkbox>
            </el-checkbox-group>
            <i slot="reference" class="el-icon-edit-outline"></i>
          </el-popover>
        </el-tooltip>
        <!-- 打印 -->
        <el-tooltip class="item" effect="dark" content="打印" placement="bottom">
          <i class="el-icon-printer" v-print="'#print_demo'"></i>
        </el-tooltip>
        <!-- 导出文件 -->
        <el-dropdown @command="clickDropdownItem">
          <i class="el-icon-folder-opened" style="font-size: 26px"></i>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="csv">导出Csv文件</el-dropdown-item>
            <el-dropdown-item command="xlsx">导出Excel文件</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
  
      </div>
      <!-- 表格区域 -->
      <div id="print_demo">
        <el-table :data="tableData" id="out-table" :header-cell-style="{ background: '#f5f7fa' }" border>
          <el-table-column v-if="colData[0].istrue" prop="userName" label="姓名" align="center">
          </el-table-column>
          <el-table-column v-if="colData[1].istrue" prop="phone" label="账号" align="center">
          </el-table-column>
          <el-table-column v-if="colData[2].istrue" label="账号身份" align="center">
            <template slot-scope="{ row }">
              <el-select v-model="userSatus">
                <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </template>
          </el-table-column>
          <el-table-column v-if="colData[3].istrue" label="查看详情" align="center">
          </el-table-column>
          <el-table-column v-if="colData[4].istrue" label="删除账号" align="center">
          </el-table-column>
        </el-table>
      </div>

js:

<script>
  import FileSaver from 'file-saver'
  import XLSX from 'xlsx'
  export default {
    data() {
      return {
        queryData: {},
        tableData: [],
        //列表动态隐藏
        colData: [
          { title: '姓名', istrue: true },
          { title: '账号', istrue: true },
          { title: '账号身份', istrue: true },
          { title: '查看详情', istrue: true },
          { title: '删除账号', istrue: true },
        ],
        checkBoxGroup: [],
        checkedColumns: [],
        // 打印
        printObj: {
          id: 'print_demo',
          popTitle: '账户列表',
          extraCss: 'https://www.google.com,https://www.google.com',
          extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
        },
        itemList: [],
        //用户身份
        userSatus: 1,
      }
    },
  
    created() {
      // 列筛选
      this.colData.forEach((item, index) => {
        this.checkBoxGroup.push(item.title)
        this.checkedColumns.push(item.title)
      })
      this.checkedColumns = this.checkedColumns
      let UnData = localStorage.getItem(this.colTable)
      UnData = JSON.parse(UnData)
      if (UnData != null) {
        this.checkedColumns = this.checkedColumns.filter((item) => {
          return !UnData.includes(item)
        })
      }
    },
    // 监控列隐藏
    watch: {
      checkedColumns(val, value) {
        let arr = this.checkBoxGroup.filter((i) => !val.includes(i)) // 未选中
        localStorage.setItem(this.colTable, JSON.stringify(arr))
        this.colData.filter((i) => {
          if (arr.indexOf(i.title) != -1) {
            i.istrue = false
          } else {
            i.istrue = true
          }
        })
      },
    },

    methods: {
     
      //初始化数据
      async initData() {
        try {
          // 发送请求
          let { data } = await getQueryOrderListApi(this.queryData)
          this.tableData = data
          this.tableData.forEach((item) => {
            this.itemList.push({ userName: item.userName, phone: item.phone })
          })
        } catch (error) {
          return console.log(error)
        }
      },
      //导出Excel
      exportExcel() {
        var wb = XLSX.utils.table_to_book(document.querySelector('#out-table'))
        var wbout = XLSX.write(wb, {
          bookType: 'xlsx',
          bookSST: true,
          type: 'array',
        })
        try {
          FileSaver.saveAs(
            new Blob([wbout], { type: 'application/octet-stream' }),
            'table.xlsx'
          )
        } catch (e) {
          if (typeof console !== 'undefined') console.log(e, wbout)
        }
        return wbout
      },
      //导出CSV
      exportCsv() {
        const header = { userName: '姓名', phone: '账号' }
        export_csv(header, this.itemList)
        function export_csv(header, data) {
          let csv = ''
          for (let key in header) {
            csv += header[key] + ','
          }
          csv = csv.substr(0, csv.length - 1) + '\r\n'
          for (let i in data) {
            for (let key in header) {
              csv += data[i][key] + ','
            }
            csv = csv.substr(0, csv.length - 1) + '\r\n'
          }
          //定义文件内容,类型必须为Blob 否则createObjectURL会报错
          let content = new Blob(['\uFEFF' + csv])
          //生成url对象
          let urlObject = window.URL || window.webkitURL || window
          let url = urlObject.createObjectURL(content)
          //生成<a></a>DOM元素
          let el = document.createElement('a')
          //链接赋值
          el.href = url
          el.download = 'table.csv'
          //必须点击否则不会下载
          el.click()
          //移除链接释放资源
          urlObject.revokeObjectURL(url)
        }
      },
  
      clickDropdownItem(value) {
        if (value == 'csv') {
          this.exportCsv()
        } else if (value == 'xlsx') {
          this.exportExcel()
        }
      },
 
    },
  }
  </script>
  
  <style scoped>
  #print_demo {
    width: 1600px;
  }
  
  
  .title {
    font-size: 18px;
    color: #6f88e7;
    font-weight: bold;
    margin: 20px 0;
  }
  
  .el-pagination {
    display: flex;
    justify-content: right;
    margin-top: 10px;
  }
  
  .selectContent {
    display: flex;
    justify-content: space-between;
    margin: 20px 0;
  }
  
  .icons {
    height: 50px;
    width: 160px;
    font-size: 26px;
    color: #565682;
    display: flex;
    justify-content: space-around;
    margin-right: 40px;
    float: right;
  }
  </style>