spreadJS初体验

SpreadJS是一款基于JavaScript的电子表格控件,通过以表格形式显示数据、高速的计算引擎以及数百种统计和财务函数及公式,提供类似于Excel的电子表格体验。 它易于实现,可扩展并且灵活。尤其可以帮助增强您的应用程序,并将内容从一组简单的数据转换为更加有用、易懂的类似于Excel的仪表板。 快速开始

App.vue

<template>
  <div>
    <input type="file" @change="importExcel($event)" />
    <button @click="exportExcel">导出EXCEL</button>
    <gc-spread-sheets
      :hostClass="hostClass"
      @workbookInitialized="initWorkbook"
    >
      <gc-worksheet />
      <gc-worksheet />
    </gc-spread-sheets>
  </div>
</template>

<script>
import '@grapecity/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css'
import '@grapecity/spread-sheets-resources-zh'
GC.Spread.Common.CultureManager.culture('zh-cn')
import * as GC from '@grapecity/spread-sheets'
import * as ExcelIO from '@grapecity/spread-excelio'
import '@grapecity/spread-sheets-vue'
import '@grapecity/spread-sheets-charts'
import FileSaver from 'file-saver'
const GCsheets = GC.Spread.Sheets
export default {
  data() {
    return {
      hostClass: 'spread-host',
      spread: null,
      table: null,
      // 源数据
      data: {
        rows: [
          {
            compName: '广东联塑科技实业有限公司',
            compNo: '1010',
            datFees: [
              {
                compName: '广东联塑科技实业有限公司',
                compNo: '1010',
                createTime: null,
                creator: '',
                electricityFees: '2.00',
                imonth: '04',
                iyear: '2022',
                pageCode: '',
                payTotal: '6.00',
                taxFees: '1.00',
                taxRefund: '4.00',
                updateTime: null,
                updator: '',
                waterFees: '3.00',
                xtype: '1',
              },
            ],
            plateTypeName: '塑料管道',
          },
          {
            compName: '福建联塑新材料科技有限公司',
            compNo: '1610',
            datFees: [
              {
                compName: '福建联塑新材料科技有限公司',
                compNo: '1610',
                createTime: null,
                creator: '',
                electricityFees: '2.00',
                imonth: '04',
                iyear: '2022',
                pageCode: '',
                payTotal: '6.00',
                taxFees: '1.00',
                taxRefund: '4.00',
                updateTime: null,
                updator: '',
                waterFees: '3.00',
                xtype: '1',
              },
            ],
            plateTypeName: '塑料管道',
          },
          {
            compName: '佛山市联塑万嘉新卫材有限公司',
            compNo: '1030',
            datFees: [
              {
                compName: '佛山市联塑万嘉新卫材有限公司',
                compNo: '1030',
                createTime: null,
                creator: '',
                electricityFees: '123.00',
                imonth: '04',
                iyear: '2022',
                pageCode: '',
                payTotal: '369.00',
                taxFees: '123.00',
                taxRefund: '0.00',
                updateTime: null,
                updator: '',
                waterFees: '123.00',
                xtype: '5',
              },
            ],
            plateTypeName: '管理及其他',
          },
        ],
      },
    }
  },
  mounted() {},
  methods: {
    // 计算总和
    calcCount(typeArr, type) {
      let obj = typeArr.reduce(
        (res, val) => {
          for (let k in res) {
            res[k] += parseFloat(val[k])
          }
          return res
        },
        {
          taxFees: 0,
          waterFees: 0,
          electricityFees: 0,
          payTotal: 0,
          taxRefund: 0,
        }
      )
      for (let k in obj) {
        obj[k] = obj[k].toFixed(2)
      }
      obj.compName = type ? `${type}合计` : `总计`
      return obj
    },
    // 更改对象key值
    changeKey(obj, keymapping) {
      let oldKeysArr = Object.keys(obj)
      let arr = Object.entries(obj)
      keymapping.forEach((item) => {
        if (oldKeysArr.indexOf(item.key) !== -1) {
          arr[oldKeysArr.indexOf(item.key)][0] = item.newKey
        }
      })
      return Object.fromEntries(arr)
    },
    // 格式化表格数据
    formatData(data) {
      let output = []
      let map = {}
      for (let rec of data) {
        map[rec.plateTypeName] = map[rec.plateTypeName] || []
        map[rec.plateTypeName].push(...rec.datFees)
      }
      let totalCount = []
      for (let k in map) {
        totalCount.push(this.calcCount(map[k], k))
        output.push(...map[k], this.calcCount(map[k], k))
      }
      output.push(this.calcCount(totalCount))
      return output
    },
    // 初始化工作簿
    initWorkbook(spread) {
      let newData = this.formatData(this.data.rows)
      let keyMapping = [
        { key: 'compName', newKey: '公司名称' },
        { key: 'compNo', newKey: '公司编码' },
        { key: 'electricityFees', newKey: '电费' },
        { key: 'imonth', newKey: '月份' },
        { key: 'iyear', newKey: '年份' },
        { key: 'payTotal', newKey: '总开销' },
        { key: 'taxFees', newKey: '税费' },
        { key: 'taxRefund', newKey: '退税' },
        { key: 'waterFees', newKey: '水费' },
      ]
      newData = newData.map(item=>{
        return this.changeKey(item,keyMapping)
      })
      this.spread = spread
      spread.suspendPaint() //暂停spread重绘
      let sheet = spread.getActiveSheet()
      let table = sheet.tables.addFromDataSource('Table1', 2, 1, newData)
      table.style(GCsheets.Tables.TableThemes['medium4'])
      table.highlightFirstColumn(true) // 第一列内容高亮
      sheet.setColumnWidth(0, 20) 
      sheet.setColumnWidth(1, 240) // 设置sheet第二列宽度
      spread.resumePaint() //恢复spread重绘
    },

    importExcel(e) {
      let file = e.target.files[0]
      let self = this
      let excelIO = new ExcelIO.IO()
      excelIO.open(file, (spreadJSON) => {
        self.spread?.fromJSON(spreadJSON)
      })
    },
    exportExcel() {
      if (this.spread) {
        let excelIO = new ExcelIO.IO()
        // spread.toJSON()设置 includeBindingSource 选项为 true,将表单或者表格中的数据源序列化到最终的 JSON 对象
        excelIO.save(this.spread.toJSON( { includeBindingSource: true }), (blob) => {
          FileSaver.saveAs(blob, 'export.xlsx')
        })
      }
    },
  },
}
</script>

<style>
.spread-host {
  width: 100%;
  height: 600px;
}
</style>

package.json

{
  "name": "sjs-vue-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@grapecity/spread-excelio": "^14.0.1",
    "@grapecity/spread-sheets": "^15.0.6",
    "@grapecity/spread-sheets-charts": "^15.0.6",
    "@grapecity/spread-sheets-resources-zh": "^15.0.6",
    "@grapecity/spread-sheets-vue": "^15.0.6",
    "@types/file-saver": "^2.0.1",
    "core-js": "^3.6.5",
    "file-saver": "^2.0.2",
    "vue": "^2.6.11"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.13",
    "@vue/cli-plugin-eslint": "~4.5.13",
    "@vue/cli-service": "~4.5.13",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {
      "generator-star-spacing": "off",
      "no-tabs": "off",
      "no-unused-vars": "off",
      "no-console": "off",
      "no-irregular-whitespace": "off",
      "no-debugger": "off"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

效果图

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值