背景

最近公司我的项目有需要, 某导入性能, 想让客户选完excel文件, 间接将加载到web的excel编辑器中, 批改、确认, 之后上传导入。

以此来记录我的开发过程。

成果查看

抉择

  • Luckysheet(https://dream-num.github.io/LuckysheetDocs/zh/guide/#demo) ,一款纯前端相似excel的在线表格,功能强大、配置简略、齐全开源。
  • x-sheet

就看到了这两个, 最初抉择了Luckysheet, 看他的star比拟多, 哈哈。

需要实现剖析

剖析一下整个流程。

其实大体就两步, 搞进去,抽离进去。

一、加载本地excel到web编辑器中

1、拿到本地excel文件流

2、转换为 Luckysheet 要的格局

3、new 一个 Luckysheet 实例, 挂在到对应标签上

实现以上就把excel加载进去了, 显示进去了。

在线编辑的事就是这个库帮咱们搞定了.

二、 从web编辑器导出文件流 上传

等客户在线编辑实现, 就须要点击一个按钮, 导出文件流, 确认并调接口上传

1、获取 Luckysheet里工作表的数据

luckysheet.getAllSheets()

2、将数据加工并应用xlsx或者exceljs导出文件流

导出为为arrayBuffer, 再将arrayBuffer转为Blob

3、调后端接口上传

开发实际

一、引入 lucky-sheet

有两种形式

1、官网文档里的cdn

这种加载有点慢

<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' /><script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js"></script><script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js"></script>

2、本人打包, 传到oss, 引入(举荐)

第一种第三方的cdn不稳固, 有时候很慢,还是倡议,拉他的仓库,而后打个包,传到本人动态资源库, 来应用

clone 这个仓库 https://gitee.com/mengshukeji/Luckysheet

npm run builddist 传上去应用。

二、指定容器

这个是挂载 luckysheet 的容器, 它确保了被展现在何处。

id="luckysheet" 能够自定义, 和上面提到的
container: 'luckysheet' 保持一致即可

<div id="luckysheet"></div>

三、导入本地文件

1、 用elment的上传文件组件 抉择文件

然而这里不上传,仅仅是用它抉择文件拿到文件对象File

<div class="import-okr">    <!-- ,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet -->    <el-upload        v-model:file-list="fileList"        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"        class="upload-demo"        :before-upload="beforeUpload"        action=""        :show-file-list="false"    >        <button @click="uploadFile">上传数据</button>    </el-upload></div>

2、beforeUpload 办法拿到文件

const beforeUpload = (file) => {    console.log(file)}

3、将文件流转换为lucky要的格局

这个是官网文档里举荐的转换包

https://github.com/dream-num/Luckyexcel#es-import

装置转换工具
npm install luckyexcel
应用

file是文件对象, 回调函数里的 exportJson 是转换玩的luckySheet对象

// After getting the xlsx fileLuckyExcel.transformExcelToLucky(file,     function(exportJson, luckysheetfile){        // exportJson就是转换后的数据    },    function(error){        // handle error if any thrown    }

4、将转换后的数据创建表格

// 将拿到的数据创建表格luckysheet.create({    container: 'luckysheet', // 挂载的dom的id名    data:exportJson.sheets,    title:exportJson.info.name,    userInfo:exportJson.info.creator,    lang: 'zh', // 设定表格语言    myFolderUrl: window.location.href,    showtoolbarConfig: {        pivotTable: false,  //'数据透视表'        // protection: false, // '工作表爱护'        print:false, // '打印'        image: false, // 插入图片    },    showinfobar: false,    options: {        // 其余配置        userImage:'http://qzz-static.forwe.store/public-assets/pgy_kj_pic_logo.png?x-oss-process=image/resize,m_fill,w_72,h_72', // 头像url        userName:'Lucky', // 用户名    }});

残缺代码

const beforeUpload = (file) => {    console.log(file)    // 转换工具, 将文件流转换为lucky要的格局    LuckyExcel2.transformExcelToLucky(        file,        function(exportJson, luckysheetfile){            isShowExcel.value = true            console.log(exportJson)            nextTick(() => {                window.luckysheet.destroy();                // 将拿到的数据创建表格                luckysheet.create({                    container: 'luckysheet', // luckysheet is the container id                    data:exportJson.sheets,                    title:exportJson.info.name,                    userInfo:exportJson.info.creator,                    lang: 'zh', // 设定表格语言                    myFolderUrl: window.location.href,                    showtoolbarConfig: {                        pivotTable: false,  //'数据透视表'                        // protection: false, // '工作表爱护'                        print:false, // '打印'                        image: false, // 插入图片                    },                    showinfobar: false,                    options: {                        // 其余配置                        userImage:'http://qzz-static.forwe.store/public-assets/pgy_kj_pic_logo.png?x-oss-process=image/resize,m_fill,w_72,h_72', // 头像url                        userName:'Lucky', // 用户名                    }                });            })        },        function(err){            logger.error('Import failed. Is your fail a valid xlsx?');        });}

四、导出

1、利用 luckysheet.getAllSheets() 获取表数据

console.log(luckysheet.getAllSheets())

2、exceljs将上述对象转换为excel文件流

import Excel  from 'exceljs'// 导出excelconst exportExcel  = async function (luckysheet) { // 参数为luckysheet.getluckysheetfile()获取的对象    // 1.创立工作簿,能够为工作簿增加属性    const workbook = new Excel.Workbook()    // 2.创建表格,第二个参数能够配置创立什么样的工作表    luckysheet.every(function (table) {        if (table.data.length === 0) return true        const worksheet = workbook.addWorksheet(table.name)        // 3.设置单元格合并,设置单元格边框,设置单元格款式,设置值        setStyleAndValue(table.data, worksheet)        setMerge(table.config.merge, worksheet)        setBorder(table.config.borderInfo, worksheet)        return true    })    // 4.写入 buffer    const buffer = await workbook.xlsx.writeBuffer()    return buffer}

3、 写个办法,执行上述两步

// 保留文件const onClickSaveFile = async ( ) => {    console.log(luckysheet.getAllSheets())    const buf = await exportExcel(luckysheet.getAllSheets())    const blob = new Blob([buf]);    // $emit('file', blob)    handleUpload(blob)}

4、上传办法

从上一步拿到文件, 利用formData, 将生成的文件二进制流发给后端

const handleUpload = async(file) => {    // isShowExcel.value = false    const loading = ElLoading.service({        fullscreen: true,        text: '上传中,请稍等',        background: 'rgba(0,0,0,0.1)'    });    try {        const formData = new FormData()        formData.append('file', file)        // 伪代码        const {code, data, message } = await IMPORT_OKR(formData)        if(code === 1) {            //...        }        loading.close()    } catch (error) {        console.log(error)        loading.close()    }}

遇到问题

1、iconfont抵触

lucky-sheet这个我的项目里的iconfont类名和我我的项目里一样,导致有些被笼罩了.

解决: 将他我的项目里 iconfont 换成 lucky-sheet, 相干类名也全副替换, 而后从新打包,再引入,即可解决

2、lucky-sheet层级不够高,无奈编辑

elmentui和antd的一些组件层级比拟高,所以, 让kucky的层级更高即可

解决: 减少下述css即可

.luckysheet-input-box { z-index: 2000; } .luckysheet-cols-menu { z-index: 2001; }

用过lucky-sheet的敌人们还遇到了什么坑? 评论区通知我

最初

妥妥的都是站在伟人的肩膀上,感激开发luckySheet的大佬们。

那么你们说产品下次是不筹备搞协同编辑?

欢送各位评论区交换

求赞