使用js-xlsx读取sheet和导出sheet文件

实现需求:1.将后端返回的xlsx数据展示在页面上,但不是用elementuiui的table展示,是动态生成表格

2.将xlsx数据导出成sheet(下载导本地)

使用的插件:js-xlsx

实现步骤:安装:npm i xlsx -S

使用import XLSX from 'xlsx';
我先用后端返回的由对象组成的数组
代码如下:
生成的table显示在下面的div里
<div id="xlsxTable" :style="{height:this.tableHeight}">
     <div v-html="this.table"></div>
</div>
this.tableData.list 的数据如下
            [{
                date:'2020-01-08',
                salary:200,
                reward:30,
            },{
                date:'2020-01-09',
                salary:300,
                reward:20,
            },{
                date:'2020-02-08',
                salary:200,
                reward:30,
            },{
                date:'2020-01-10',
                salary:300,
                reward:40,
            }] 
        workbook:'',
            table:'',
            tableHeight:0,
            sheet1:'',
            blob:'',

 

<!-- 将json数组转为table展示 -->
<el-button @click="table">xlsx读取</el-button>
<!-- 将table数据转成sheet下载 -->
<el-button @click="sheet">xlsx导出sheet</el-button>
table(){ // 读取xlsx文件为table,在页面上显示,如果后端返回的是sheet数据,就不需要json_to_sheet这一步了
                console.log(this.tableData.list,'list')
                var sheet1 = XLSX.utils.json_to_sheet(this.tableData.list)  // 1.转成sheet(workbook)
                console.log(sheet1,'sheet1-980')
                this.sheet1 = sheet1
                
                this.table = this.csv2table(XLSX.utils.sheet_to_csv(sheet1)) // 2.将sheet转成csv,再利用csv2table方法转为拼接成表格,也可以直接用sheet_to_html直接转成table
                // this.table = XLSX.utils.sheet_to_html(sheet1)
                this.tableHeight ='400px'
                // document.getElementById('table').innerHTML = this.table
                // console.log(this.table,'table-980')
            },
            csv2table(csv){
                    var html = '<table width="100%" cellspacing="0" align="center">';
                    var rows = csv.split('\n');
                    rows.pop(); // 最后一行没用的
                    rows.forEach(function(row, idx) {
                        var columns = row.split(',');
                        columns.unshift(idx+1); // 添加行索引

                        html += '<tr>';
                        columns.forEach(function(column) {
                            html += '<td width="100px">'+column+'</td>';
                        });
                        html += '</tr>';
                    });
                    html += '</table>';
                    return html;
            },
            
            // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
            sheet2blob(sheet, sheetName) {
                sheetName = sheetName || 'sheet1';
                var workbook = {
                    SheetNames: [sheetName],
                    Sheets: {}
                };
                workbook.Sheets[sheetName] = sheet;
                // 生成excel的配置项
                var wopts = {
                    bookType: 'xlsx', // 要生成的文件类型
                    bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
                    type: 'binary'
                };
                var wbout = XLSX.write(workbook, wopts);
                this.blob = new Blob([s2ab(wbout)], {type:"application/octet-stream"});
                // 字符串转ArrayBuffer
                function s2ab(s) {
                    var buf = new ArrayBuffer(s.length);
                    var view = new Uint8Array(buf);
                    for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
                    return buf;
                }
                return this.blob;
            },
            openDownloadDialog(url, saveName){
                if(typeof url == 'object' && url instanceof Blob)
                {
                    url = URL.createObjectURL(url); // 创建blob地址
                }
                var aLink = document.createElement('a');
                aLink.href = url;
                aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
                var event;
                if(window.MouseEvent) event = new MouseEvent('click');
                else
                {
                    event = document.createEvent('MouseEvents');
                    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                }
                aLink.dispatchEvent(event);
            },
            sheet(){  // 将xlsx文件导出
                // var sheet = this.csv2sheet(csv);
                var blob = this.sheet2blob(this.sheet1);
                this.openDownloadDialog(blob, '导出.xlsx');
            },

最后效果:

 下面结合实际项目中使用的情况记录下

1.实现上传本地execl后在页面上显示为table

<el-upload action="/active/uploadExcel" 
                            :show-file-list="false" :on-success="CleanSheetSuccess" :before-upload="beforeAvatarUpload">
                            <el-button size="small" style="display:inline">上传execl</el-button>
                        </el-upload>
// 上传成功后
CleanSheetSuccess(res){
            if (res.code == "ACK") {                
                this.sheetUrl = res.data.url
                this.$message.success('上传成功')
                
            } else {
                this.$message({
                    duration: 0,
                    showClose: true,
                    message: res.error,
                    type: "error"
                });
            }
        },
// 将csv拼接成table csv2table(csv){
var html = '<table width="100%" cellspacing="0" align="center">'; var rows = csv.split('\n'); rows.pop(); // 最后一行没用的 rows.forEach(function(row, idx) { var columns = row.split(','); columns.unshift(idx+1); // 添加行索引 html += '<tr>'; columns.forEach(function(column) { html += '<td width="100px">'+column+'</td>'; }); html += '</tr>'; }); html += '</table>'; return html; },
    //上传文件之前判断类型 beforeAvatarUpload(file) {
    // 这里我上传了file文件,我想直接把file文件利用XLSX转为table
        var reader = new FileReader();
            reader.onload = function(e) {
                var data = e.target.result;
                console.log(e,'dat')
                var workbook = XLSX.read(data, {type: 'binary'});
                // if(callback) callback(workbook);
                console.log(workbook,'workbook988')                
                 this.table = this.csv2table(XLSX.utils.sheet_to_csv(workb          ook.Sheets[workbook.SheetNames[0]]))
                console.log(this.table ,'table988')
            };

            console.log(file,'file')
            const isEXEL =
                file.type ===
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            if (!isEXEL) {
                this.$message.error("请导入excel 文件!");
            }
            return isEXEL;
        },
  
// 在页面中显示 ,contenteditable :table可以编辑
<div id="xlsxTable" contenteditable :style="{height:this.tableHeight}">
     <div v-html="this.table"></div>
 </div>  
 

2.上传execl文件后,实现将后端返回的.xlsx的execl链接转为table显示在页面上(每次点击查看可以预览生成的table)

// this.urlPath 是后端返回的execl链接,利用readWorkbookFromRemoteFile 方法返回workbook,
再利用XLSX的api:sheet_to_csv,最后转为table显示在页面上
this.readWorkbookFromRemoteFile(this.urlPath, (workbook) => {
                    console.log(workbook,'workbook')
                    this.table = this.csv2table(XLSX.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]]))
// 这里是只显示一个table,如果后端给你返回的execl链接里有多个sheet表,就需要循环展示出表名和表格
            
       
                    var workData =[]
                    for(const i in workbook.SheetNames){                                           
                        workData.push(workbook.Sheets[workbook.SheetNames[i]])                   
                            this.table.push({
                            table:this.csv2table(XLSX.utils.sheet_to_csv(workData[i])),
                            title:workbook.SheetNames[i]})
                    }
            
                }) 

readWorkbookFromRemoteFile(url, callback) {
                var xhr = new XMLHttpRequest();
                xhr.open('get', url, true);
                xhr.responseType = 'arraybuffer';
                xhr.onload = function(e) {
                    if(xhr.status == 200) {
                        var data = new Uint8Array(xhr.response)
                        var workbook = XLSX.read(data, {type: 'array'});
                        if(callback) callback(workbook);
                    }
                };
                xhr.send();
            },

 

 

 

 

 

posted @ 2021-06-24 17:03  程序员瑶琴  阅读(1488)  评论(0编辑  收藏  举报