1小时解决在浏览器中所有与excel相关的需求

我心飞翔 分类:javascript

从小我们都有一个共识,假如在电脑中打开一个特定类型的文件,最起码得下载一个相关的软件才能打开。比如excel就是其中之一。但浏览器逐渐发展起来,慢慢变成更多的文件格式都在直接在浏览器中预览编辑。假如我们接到了一个需要在前端处理excel表格数据上传、下载或者预览编辑的需求,有需要做哪些工作呢?

以下是比较常见的四种需求的实现思路:

1.实现在浏览器端的在线excel:

此类需求大致需要实现原生excel的所有常用功能,能导入导出,增删改查,界面样式和部分扩展功能最好也能够实现。
这种情况最好是使用现成的完整的库。目前没有找到开源且功能齐全的,建议使用付费的库进行制作,也比较方便后续的维护。在这简单地列举一下比较常见的几种:

  • spreadsheet :较为清新,该有的都有,可自行研究。

  • Handsontable:JS实现的spreadsheets评分最高的库。石墨文档的excel部分有使用到此库。基础版本免费,部分高级功能比如导出到excel要用到收费的商业版本。

  • SpreadJS:样式和微软的以前的一个版本的很像,功能齐全,国内有代理公司。

2.只需读取excel内容进行预览:

这种情况的话主要是一些需要导入excel文件,并进行实时预览。类似包括预览word、pdf等格式文件都可使用此类方法进行解决。

  • 微软在线预览:直接通过调用微软的在线预览功能,并插入iframe实现。预览前提是你的资源必须是公共可访问的。缺点是预览速度很慢且大文件无法进行预览。
//将iframe的src设置为http://view.officeapps.live.com/op/view.aspx?src=你的在线下载excel的地址
//需要对excel地址进行encodeURI处理,示例如下

<iframe 
  src='http://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Flearn.bankofamerica.com%2Fcontent%2Fexcel%2FWedding_Budget_Planner_Spreadsheet.xlsx' 
  width='100%' 
  height='100%' 
  frameborder='1'>
</iframe>
 
  • 百度文档服务:类似的也有其他网站的文档服务,可供office、wps等格式文档的存储、转码、分发能力,同时满足PC、WAP、APP多端的文档在线浏览需求,可自行搜索了解。

  • 私有化部署相关(wopi) apps:

整体使用类似于上面的微软在线预览,但是需要自己将office web部署至自己的服务器,并进行相关的配置。转换文档需要两台服务器,一台为转换server,另外一台为域控server。并且服务器系统要求为Windows。有需要的可自行了解。

3.需定制化读取、显示和操作数据:

此需求为需要导入excel文件,然后读取excel的相关数据和样式,再进行我们想要的格式显示的出来。
比如读取某些固定位置的数据进行计算,以及读取相关位置的数据样式显示至自己需要的表格等地方。

正常来说应该是由后端读取解析所有需要用来展示的excel数据,前端再调用返回的数据生成样式。那这样子就还得经过后端处理才能对excel进行解析,多了一层步骤。

但其实纯前端也有实现方式。对比了当前开源库的解决方案之后,目前比较倾向于使用ExcelJS进行实现。这个库几乎可以将所有日常excel需要的数据及样式都读取出来在前端使用。以下是我用ExcelJS实现的纯前端的excel导入。仓库地址点这里

假如在wps打开excel的时候,内容如下图所示

image.png

然后在我的项目中上传excel文件,即可实现在浏览器对excel文件进行预览。

1.gif

点击不同的单元格即可显示单元格的内容,还支持页面放大缩小功能

2.gif

4.gif
同时还支持对解析后的数据,导出成excel进行下载或导出成图片进行下载,相关实现和操作都可以把源码下载之后自己运行尝试一下噢

3.gif

但是由于官方文档对导入数据处理的欠缺,在解析excel数据也产生了很多的问题

官方文档中导入的操作有三种,实测从浏览器端上传文件,可用buffer类型的读取解析出数据。具体操作就是你先写好上传文件的控件,再根据返回的数据进行转换。

<input type="file" name="file" @change="getUploadData"/>
//省略部分代码,记得安装好ExcelJS在你的项目中

import Excel from "exceljs";
getUploadData(e){
    let fileData = e.target.files[0]
    
    let reader = new FileReader()
    reader.readAsArrayBuffer(fileData)
    reader.onloadend = e => {
        let data = new Uint8Array(e.target.result)
        this.workbook = new Excel.Workbook()
        this.workbook.xlsx.load(data).then(() => {
            //this.workbook为excel文件的整体数据
            if(this.workbook._themes.theme1){
                this.workbook.eachSheet(worksheet => {
                    //这里的worksheet就是我们所需要读取的每个表的数据
                })
            }
            else{
                /* 默认能读到主题的excel才算解析成功,否则为错误格式
                   主题的含义下面再解释。*/
                this.$Messgae.error('文件格式有误,无法解析')
            }
        })
    }    
}
 

在主要这里要获取到excel文件的整体数据、以及文件里每个sheet的数据。
导入之后看到我们查看每个表的数据。excel主要的数据都在model这个属性里面。

image.png

model属性里面的cols就是我们的列宽数据,rows就是我们每一行的数据。所有单元格的具体数据样式也在rows里面

image.png

rows就是我们每一行的数据,包括每个格子的数据也在里面。我们如果需要生成一个类似于表格形式的展示页面,需要用到一下数据

  • 每一行的宽度和高度
  • 每个格子的内容、样式。包括每条边的颜色、宽度、是虚线还是直线等。

这些统统在官方文档都没找到解释。如果需要更多的数据只好自己一步步筛查属性在哪里了。我在仓库代码里面已经对excel的高宽、样式、合并单元格、默认样式表的xml格式转换、不同数据格式的内容,进行了处理,具体详情可以查看源码。

上面的演示只是一个demo,excel的数据格式较为丰富且多变,很多情况都没有进行处理的,如果需要进行扩展的话最好还是修补一下代码哦。

4.直接用JS将需要的数据导出excel的格式:

这个需求一般都是用于对相关表格或统计的数据进行直接导出。比如将一个自己制作的前端表格组件库,导出成excel文件在浏览器进行下载,即可使用上面介绍的ExcelJS。直接在代码中导入创建一个数据对象,操作一番即可导出。具体可以参考官方文档,有直接导出该如何处理的详细解释。

//这里只是一个最简单的DEMO,具体样式都可以在官方文档一个个找到的,这里就不赘述了。
//file-saver是一个用来下载文件的库

import { saveAs } from "file-saver";
import Excel from "exceljs";

    var workbook = new Excel.Workbook();
    var worksheet = workbook.addWorksheet('My Sheet');

    worksheet.columns = [
    { header: 'Id', key: 'id', width: 10 },
    { header: 'Name', key: 'name', width: 32 },
    { header: 'D.O.B.', key: 'DOB', width: 10, outlineLevel: 1 }
    ];

    worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)});
    worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)});

    workbook.xlsx.writeBuffer().then(buffer => {
        // done
        saveAs(new Blob([buffer]), `${Date.now()}_feedback.xlsx`);
    });
 

上面代码执行完就会执行浏览器的下载文件功能,打开下载后的excel,就能看到以下内容了:

image.png

文章要是有什么错误的地方也希望大家补充指正。感谢感谢。觉得有不清楚的地方可以问我噢,喜欢的话就点个赞哈。

回复

我来回复
  • 暂无回复内容