• vue开发在线表格


    一、方式一
    1、安装依赖

    npm i x-data-spreadsheet xlsx
    
    • 1

    2、逻辑部分

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160

    2、方式二
    1、安装依赖(功能更全)

    cnpm i -S exceljs  luckyexcel
    
    • 1

    2、在index.html通过cdn引入

    
        
        
        
        
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注:如果要本地引入,则下载源码,执行cnpm i后执行npm run build,然后将dist文件夹下的内容拷贝出来,放在index.html统计目录下,例如:

    
        
        
        
        
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、新建export.js文件

    // import { createCellPos } from './translateNumToLetter'
    const Excel = require('exceljs')
    
    import FileSaver from 'file-saver'
    export var testaaa = function (){
      console.log("...");
    }
    export var exportExcel = function(luckysheet, value) {
      // 参数为luckysheet.getluckysheetfile()获取的对象
      // 1.创建工作簿,可以为工作簿添加属性
      const workbook = new Excel.Workbook()
      // 2.创建表格,第二个参数可以配置创建什么样的工作表
      if (Object.prototype.toString.call(luckysheet) === '[object Object]') {
        luckysheet = [luckysheet]
      }
      luckysheet.forEach(function(table) {
        if (table.data.length === 0) return  true
        // ws.getCell('B2').fill = fills.
        const worksheet = workbook.addWorksheet(table.name)
        const merge = (table.config && table.config.merge) || {}
        const borderInfo = (table.config && table.config.borderInfo) || {}
        // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值
        setStyleAndValue(table.data, worksheet)
        setMerge(merge, worksheet)
        setBorder(borderInfo, worksheet)
        return true
      })
    
      // return
      // 4.写入 buffer
      const buffer = workbook.xlsx.writeBuffer().then(data => {
        // console.log('data', data)
        const blob = new Blob([data], {
          type: 'application/vnd.ms-excel;charset=utf-8'
        })
        console.log("导出成功!")
        FileSaver.saveAs(blob, `${value}.xlsx`)
      })
      return buffer
    }
    
    var setMerge = function(luckyMerge = {}, worksheet) {
      const mergearr = Object.values(luckyMerge)
      mergearr.forEach(function(elem) {
        // elem格式:{r: 0, c: 0, rs: 1, cs: 2}
        // 按开始行,开始列,结束行,结束列合并(相当于 K10:M12)
        worksheet.mergeCells(
          elem.r + 1,
          elem.c + 1,
          elem.r + elem.rs,
          elem.c + elem.cs
        )
      })
    }
    
    var setBorder = function(luckyBorderInfo, worksheet) {
      if (!Array.isArray(luckyBorderInfo)) return
      // console.log('luckyBorderInfo', luckyBorderInfo)
      luckyBorderInfo.forEach(function(elem) {
        // 现在只兼容到borderType 为range的情况
        // console.log('ele', elem)
        if (elem.rangeType === 'range') {
          let border = borderConvert(elem.borderType, elem.style, elem.color)
          let rang = elem.range[0]
          // console.log('range', rang)
          let row = rang.row
          let column = rang.column
          for (let i = row[0] + 1; i < row[1] + 2; i++) {
            for (let y = column[0] + 1; y < column[1] + 2; y++) {
              worksheet.getCell(i, y).border = border
            }
          }
        }
        if (elem.rangeType === 'cell') {
          // col_index: 2
          // row_index: 1
          // b: {
          //   color: '#d0d4e3'
          //   style: 1
          // }
          const { col_index, row_index } = elem.value
          const borderData = Object.assign({}, elem.value)
          delete borderData.col_index
          delete borderData.row_index
          let border = addborderToCell(borderData, row_index, col_index)
          // console.log('bordre', border, borderData)
          worksheet.getCell(row_index + 1, col_index + 1).border = border
        }
        // console.log(rang.column_focus + 1, rang.row_focus + 1)
        // worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border = border
      })
    }
    var setStyleAndValue = function(cellArr, worksheet) {
      if (!Array.isArray(cellArr)) return
      cellArr.forEach(function(row, rowid) {
        row.every(function(cell, columnid) {
          if (!cell) return true
          let fill = fillConvert(cell.bg)
    
          let font = fontConvert(
            cell.ff,
            cell.fc,
            cell.bl,
            cell.it,
            cell.fs,
            cell.cl,
            cell.ul
          )
          let alignment = alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)
          let value = ''
    
          if (cell.f) {
            value = { formula: cell.f, result: cell.v }
          } else if (!cell.v && cell.ct && cell.ct.s) {
            // xls转为xlsx之后,内部存在不同的格式,都会进到富文本里,即值不存在与cell.v,而是存在于cell.ct.s之后
            // value = cell.ct.s[0].v
            cell.ct.s.forEach(arr => {
              value += arr.v
            })
          } else {
            value = cell.v
          }
          //  style 填入到_value中可以实现填充色
          let letter = createCellPos(columnid)
          let target = worksheet.getCell(letter + (rowid + 1))
          // console.log('1233', letter + (rowid + 1))
          for (const key in fill) {
            target.fill = fill
            break
          }
          target.font = font
          target.alignment = alignment
          target.value = value
    
          return true
        })
      })
    }
    
    var fillConvert = function(bg) {
      if (!bg) {
        return {}
      }
      // const bgc = bg.replace('#', '')
      let fill = {
        type: 'pattern',
        pattern: 'solid',
        fgColor: { argb: bg.replace('#', '') }
      }
      return fill
    }
    
    var fontConvert = function(
      ff = 0,
      fc = '#000000',
      bl = 0,
      it = 0,
      fs = 10,
      cl = 0,
      ul = 0
    ) {
      // luckysheet:ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
      const luckyToExcel = {
        0: '微软雅黑',
        1: '宋体(Song)',
        2: '黑体(ST Heiti)',
        3: '楷体(ST Kaiti)',
        4: '仿宋(ST FangSong)',
        5: '新宋体(ST Song)',
        6: '华文新魏',
        7: '华文行楷',
        8: '华文隶书',
        9: 'Arial',
        10: 'Times New Roman ',
        11: 'Tahoma ',
        12: 'Verdana',
        num2bl: function(num) {
          return num === 0 ? false : true
        }
      }
      // 出现Bug,导入的时候ff为luckyToExcel的val
    
      let font = {
        name: typeof ff === 'number' ? luckyToExcel[ff] : ff,
        family: 1,
        size: fs,
        color: { argb: fc.replace('#', '') },
        bold: luckyToExcel.num2bl(bl),
        italic: luckyToExcel.num2bl(it),
        underline: luckyToExcel.num2bl(ul),
        strike: luckyToExcel.num2bl(cl)
      }
    
      return font
    }
    
    var alignmentConvert = function(
      vt = 'default',
      ht = 'default',
      tb = 'default',
      tr = 'default'
    ) {
      // luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
      const luckyToExcel = {
        vertical: {
          0: 'middle',
          1: 'top',
          2: 'bottom',
          default: 'top'
        },
        horizontal: {
          0: 'center',
          1: 'left',
          2: 'right',
          default: 'left'
        },
        wrapText: {
          0: false,
          1: false,
          2: true,
          default: false
        },
        textRotation: {
          0: 0,
          1: 45,
          2: -45,
          3: 'vertical',
          4: 90,
          5: -90,
          default: 0
        }
      }
    
      let alignment = {
        vertical: luckyToExcel.vertical[vt],
        horizontal: luckyToExcel.horizontal[ht],
        wrapText: luckyToExcel.wrapText[tb],
        textRotation: luckyToExcel.textRotation[tr]
      }
      return alignment
    }
    
    var borderConvert = function(borderType, style = 1, color = '#000') {
      // 对应luckysheet的config中borderinfo的的参数
      if (!borderType) {
        return {}
      }
      const luckyToExcel = {
        type: {
          'border-all': 'all',
          'border-top': 'top',
          'border-right': 'right',
          'border-bottom': 'bottom',
          'border-left': 'left'
        },
        style: {
          0: 'none',
          1: 'thin',
          2: 'hair',
          3: 'dotted',
          4: 'dashDot', // 'Dashed',
          5: 'dashDot',
          6: 'dashDotDot',
          7: 'double',
          8: 'medium',
          9: 'mediumDashed',
          10: 'mediumDashDot',
          11: 'mediumDashDotDot',
          12: 'slantDashDot',
          13: 'thick'
        }
      }
      let template = {
        style: luckyToExcel.style[style],
        color: { argb: color.replace('#', '') }
      }
      let border = {}
      if (luckyToExcel.type[borderType] === 'all') {
        border['top'] = template
        border['right'] = template
        border['bottom'] = template
        border['left'] = template
      } else {
        border[luckyToExcel.type[borderType]] = template
      }
      // console.log('border', border)
      return border
    }
    
    function addborderToCell(borders, row_index, col_index) {
      let border = {}
      const luckyExcel = {
        type: {
          l: 'left',
          r: 'right',
          b: 'bottom',
          t: 'top'
        },
        style: {
          0: 'none',
          1: 'thin',
          2: 'hair',
          3: 'dotted',
          4: 'dashDot', // 'Dashed',
          5: 'dashDot',
          6: 'dashDotDot',
          7: 'double',
          8: 'medium',
          9: 'mediumDashed',
          10: 'mediumDashDot',
          11: 'mediumDashDotDot',
          12: 'slantDashDot',
          13: 'thick'
        }
      }
      // console.log('borders', borders)
      for (const bor in borders) {
        // console.log(bor)
        if (borders[bor].color.indexOf('rgb') === -1) {
          border[luckyExcel.type[bor]] = {
            style: luckyExcel.style[borders[bor].style],
            color: { argb: borders[bor].color.replace('#', '') }
          }
        } else {
          border[luckyExcel.type[bor]] = {
            style: luckyExcel.style[borders[bor].style],
            color: { argb: borders[bor].color }
          }
        }
      }
    
      return border
    }
    
    function createCellPos(n) {
      let ordA = 'A'.charCodeAt(0)
    
      let ordZ = 'Z'.charCodeAt(0)
      let len = ordZ - ordA + 1
      let s = ''
      while (n >= 0) {
        s = String.fromCharCode((n % len) + ordA) + s
    
        n = Math.floor(n / len) - 1
      }
      return s
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349

    4、测试代码

    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190

    5、官方文档

  • 相关阅读:
    xavier安装torch-gpu
    uniapp引入小程序原生插件
    C语言程序设计 复习总结[持续更新ing]
    关于jvm client 与 jvm server 有什么区别, 如何启动jvm client
    外卖项目(SpringBoot)--- 移动端登录模块、菜品展示、购物车
    Ubuntu部署运行ORB-SLAM2
    HTML实现猜数字游戏
    springcloud学习笔记:使用hystrix实现服务熔断与服务降级
    外包干了一个月,技术明显进步。。。。。
    Python零基础入门-8 错误和异常
  • 原文地址:https://blog.csdn.net/weixin_41463944/article/details/127770261