Web前端怎样实现像excel那样的按列拖选的表格

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web前端怎样实现像excel那样的按列拖选的表格相关的知识,希望对你有一定的参考价值。

Web前端实现像excel那样的按列拖选表格的方法:

1.通过flash,flex实现FLEX 功能强大的datagrid

2.通过jquery插件,js实现

JS实现可编辑的表格,双击可编辑,可以删除行和列,增加行和列,重置,导出表格,也可以上下移动元素

Flexigrid – Web 2.0 Javscript Grid for jQuery - 可变列宽,自动适应表头宽度,可通过 Ajax 连接 XML 数据源,类似 Ext Grid,但基于 jQuery 因此更轻量小巧。


Chromatable JQuery Plugin - 固定表头,可滚动内容区,内容区滚动的时候表头位置保持不变。


Ingrid, the jQuery Datagrid - 在 html 表格上加入列宽调整,分页,排序,行列式样等功能(演示)。


JQTreeTable - 在表格中加入树形结构


Scrollable HTML table - 将普通 HTML 表格变为可滚动状态。将表头部分放入 THEAD 区,内容部分放入 TBODY 区,脚注部分放入 TFOOT 区域,引用 webtoolkit.scrollabletable.js 文件,然后在每个表格后面创建 ScrollableTable() 对象即可(演示)。


KeyTable - 象 Excel 那样,在单元格之间巡游,可以现场编辑。


graphTable - 借助 flot 将 HTML 表格中的内容变成图形(演示)。


DataTables - 非常强大的 jQuery 表格插件,可变宽页码浏览,现场过滤。多列排序,自动探测数据类型,智能列宽,可从几乎任何数据源获取数据。

参考技术A

直接在Web前端实现一个类Excel的表格不是更好吗?

类似这样的需求可以用一些纯前端的专业类Excel控件来实现,比如SpreadJS。

用这样的控件可以直接把一个类Excel的表格嵌入到Web前端的页面中。

这样无论从外形或者操作方式都与Excel一致,也就可以像Excel那样按列拖选表格。

Vue前端实现excel的导入导出打印功能

目录

一、相关依赖下载

导入导出依赖:
npm install xlsx@0.16.9
npm install xlsx-style@0.8.13 --save

  1. 安装xlsx-style,运行报错
    This relative module was not found: ./cptable in ./node_modules/xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js
  2. 解决报错
    在\\node_modules\\xlsx-style\\dist\\cpexcel.js 807行 的var cpt = require('./cpt' + 'able');改为:var cpt = cptable;

打印依赖:
npm install vue-print-nb@1.7.5 --save

二、excel导入功能

<template>
  <div>
    <el-upload
      action="#"
      :before-upload="beforeUpload"
      :show-file-list="false"
      accept=".xlsx, .xls"
    >
      <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
    </el-upload>
    <!-- 解析出来的数据 -->
    <el-table :data="tableData">
      <el-table-column prop="日期" label="日期" width="180"> </el-table-column>
      <el-table-column prop="姓名" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="地址" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
import XLSX from 'xlsx'
export default 
  name: 'importExcel',
  data () 
    return 
      tableData: [],
    
  ,
  methods: 
    beforeUpload (file) 
      console.log(file, '--文件');
      this.file2XLSX(file).then((res) => 
        console.log('可以继续对res数据进行二次处理')
        this.tableData = res[0].sheet
      )
      return false
    ,
    // excel导入方法
    file2XLSX (file) 
      return new Promise(function (resolve, reject) 
        // 通过FileReader对象读取文件
        const reader = new FileReader()
        // 读取为二进制字符串
        reader.readAsBinaryString(file)
        reader.onload = function (e) 
          console.log(e, '读取文件成功的e');
          // 获取读取文件成功的结果值
          const data = e.target.result
          // XLSX.read解析数据,按照type 的类型解析
          let wb = XLSX.read(data, 
            type: 'binary' // 二进制
          )
          console.log(wb, '---->解析后的数据')
          // 存储获取到的数据
          const result = []
          // 工作表名称的有序列表
          wb.SheetNames.forEach(sheetName => 
            result.push(
              // 工作表名称
              sheetName: sheetName,
              // 利用 sheet_to_json 方法将 excel 转成 json 数据
              sheet: XLSX.utils.sheet_to_json(wb.Sheets[sheetName]) 
            )
          )
          resolve(result)
        
      )
    
  ,

</script>

三、table导出excel表格

1.导出行数据

2.导出table数据(也会导出合并单元格)

3.导出二维数据的table数据

4.导出合并单元格table数据

<template>
  <div>
    <el-button type="primary" @click="exportSelectData"
      >导出行数据(json_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableData"
      >导出table数据(也会导出合并单元格)(table_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableDataFormAoa"
      >导出二维数据的table数据(aoa_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableDataCellMerging"
      >导出合并单元格table数据(aoa_to_sheet)</el-button
    >
    <el-table
      :data="tableData"
      @selection-change="handleSelectionChange"
      ref="tableDataRef"
      id="table1"
    >
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column prop="date" label="日期" width="180"> </el-table-column>
      <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
import XLSX from 'xlsx'
export default 
  name: 'importExcel',
  data () 
    return 
      selectionList: [],
      tableData: [
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      , 
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1517 弄'
      , 
        date: '2016-05-01',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1519 弄'
      , 
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      ]
    
  ,
  methods: 
    // 获取选择的行数据
    handleSelectionChange (val) 
      this.selectionList = val;
      console.log(this.selectionList, '--行数据');
    ,
    // 导出选择的行数据
    exportSelectData () 
      // 对选择的表格数据处理:添加标题
      let arr = this.selectionList.map(item => 
        return 
          日期: item.date,
          姓名: item.name,
          地址: item.address
        
      )
      // 将json数据变为sheet数据
      // json_to_sheet: 将一个由对象组成的数组转成sheet;
      let sheet = XLSX.utils.json_to_sheet(arr)
      // 新建表格
      let book = XLSX.utils.book_new()
      // 在表格中插入一个sheet
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      // 通过xlsx的writeFile方法将文件写入
      XLSX.writeFile(book, `user$new Date().getTime().xls`)
    ,
    // 导出table数据
    exportTableData () 
      // 获取dom元素(2种方式)
      // let table1 = document.querySelector("#table1");  // 原生dom
      let table = this.$refs.tableDataRef.$el
      // table_to_sheet: 将一个table dom直接转成sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并;
      let sheet = XLSX.utils.table_to_sheet(table)
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user$new Date().getTime().xls`)
    ,
    // 导出一个二维数组
    exportTableDataFormAoa () 
      let aoa = [
        ['姓名', '性别', '年龄', '注册时间'],
        ['张三', '男', 18, new Date()],
        ['李四', '女', 22, new Date()]
      ];
      // 将一个二维数组转成sheet
      // aoa_to_sheet: 这个工具类最强大也最实用了,将一个二维数组转成sheet,会自动处理number、string、boolean、date等类型数据;
      let sheet = XLSX.utils.aoa_to_sheet(aoa);
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user$new Date().getTime().xls`)
    ,
    // 导出合并单元格的table数据
    exportTableDataCellMerging () 
      let aoa = [
        ['主要信息', null, null, '其它信息'], // 特别注意合并的地方后面预留2个null
        ['姓名', '性别', '年龄', '注册时间'],
        ['张三', '男', 18, new Date()],
        ['李四', '女', 22, new Date()]
      ];
      let sheet = XLSX.utils.aoa_to_sheet(aoa);
      // 设置合并的单元格
      sheet['!merges'] = [
        // 设置A1-C1的单元格合并
         s:  r: 0, c: 0 , e:  r: 0, c: 2  
      ];
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user$new Date().getTime().xls`)
    
  

</script>

参考

  1. 对sheet二次处理的参考:
    https://blog.csdn.net/tian_i/article/details/84327329

四、table导出excel表格(带样式)

1.导出带样式的excel

<template>
  <div>
    <el-button @click="exportExcel()">导出带样式的excel</el-button>
  </div>
</template>

<script>
import XLSX from 'xlsx'
import XLSXStyle from 'xlsx-style';

export default 
  name: 'exportExcelStyle',
  methods: 
    exportExcel () 
      let data = [['时间', '电压'], ['2021-12-01 08:57:12', '3.14'], ['2021-12-01 08:58:20', '3.15']];
      let titles = ['时间', '电压']
      var sheet = XLSX.utils.json_to_sheet(data, 
        skipHeader: true,
      );
      /**设置标题头背景色 */
      for (const key in sheet) 
        // 第一行,表头
        if (key.replace(/[^0-9]/ig, '') === '1') 
          sheet[key].s = 
            fill:  //背景色
              fgColor:  rgb: 'C0C0C0' 
            ,
            font: //字体
              name: '宋体',
              sz: 12,
              bold: true
            ,
            border: //边框
              bottom: 
                style: 'thin',
                color: 'FF000000'
              
            ,
            alignment: 
              horizontal: 'center' //水平居中
            
          
        
        // 指定单元格样式
        if (key === 'A1') 
          sheet[key].s = 
            ...sheet[key].s,
            fill:  //背景色
              fgColor:  rgb: 'E4DFEC' 
            
          
        
        // 列宽
        let colsP = titles.map(item => 
          let obj = 
            'wch': 25 //列宽
          
          return obj;
        )
        sheet['!cols'] = colsP;//列宽

        // // 每列的列宽
        // sheet["!cols"] = [
        //   wpx: 70 //单元格列宽
        // , 
        //   wpx: 70
        // , 
        //   wpx: 70
        // , 
        //   wpx: 70
        // , 
        //   wpx: 150
        // , 
        //   wpx: 120
        // ];
      
      let fileName = 'Excel文件.xlsx'
      let sheetName = 'Excel文件'
      this.openDownload(this.sheet2blob(sheet, sheetName), fileName);
    ,
    sheet2blob (以上是关于Web前端怎样实现像excel那样的按列拖选的表格的主要内容,如果未能解决你的问题,请参考以下文章

从服务端生成Excel电子表格(Node.js+SpreadJS)

Vue前端实现excel的导入导出打印功能

图解Web前端实现类似Excel的电子表格

如何将多个csv按行合并?(不是首尾相接的按列合并)

EXCEL表格日期格式自定义如何设置

要生成像 iOS 8 Health 应用那样的图表,都有哪些比较好用的库