修改layui 源码 修复excel导出文件数据格式不正确问题

1,358 阅读3分钟

前几天使用 layui 框架的导出功能,导出的excel文件 数据格式不正确 数字会变成科学计数 我查了下原因是由于excel将数据当成是数字的格式 超过几位就会自动转成科学计数 涉及到layui 框架的底层源码部分
找到lay文件夹下面的modules文件下面的table.js 文件
通过美化js 将代码格式化 找到 exportFile 方法

table.exportFile = function(id, data, type){
    var that = this;
    data = data || table.clearCacheKey(table.cache[id]);
    type = type || 'csv';
    
    var config = thisTable.config[id] || {}
    ,textType = ({
      csv: 'text/csv'
      ,xls: 'application/vnd.ms-excel'
    })[type]
    ,alink = document.createElement("a");
    
    if(device.ie) return hint.error('IE_NOT_SUPPORT_EXPORTS');
    
    alink.href = 'data:'+ textType +';charset=utf-8,\ufeff'+ encodeURIComponent(function(){
      var dataTitle = [], dataMain = [], dataTotal = [];
      
      //表头和表体
      layui.each(data, function(i1, item1){
        var vals = [];
        if(typeof id === 'object'){ //如果 id 参数直接为表头数据
          layui.each(id, function(i, item){
            i1 == 0 && dataTitle.push(item || '');
          });
          layui.each(table.clearCacheKey(item1), function(i2, item2){
            vals.push('"'+ (item2 || '') +'"');
          });
        } else {
          table.eachCols(id, function(i3, item3){
            if(item3.field && item3.type == 'normal' && !item3.hide){
              var content =item1[item3.field]
              if(content === undefined || content === null) content = '';
              i1 == 0 && dataTitle.push(item3.title || '');
              vals.push('"'+ parseTempData(item3, content, item1, 'text') + '"');
            }
          });
        }
        dataMain.push(vals.join(','));
      });
      
      //表合计
      layui.each(that.dataTotal, function(key, value){
        dataTotal.push(value);
      });
      
      return dataTitle.join(',') + '\r\n' + dataMain.join('\r\n') + '\r\n' + dataTotal.join(',');
    }());
    
    alink.download = (config.title || 'table_'+ (config.index || '')) + '.' + type; 
    document.body.appendChild(alink);
    alink.click();
    document.body.removeChild(alink); 
  };

关键就在这个循环里面

table.eachCols(id, function(i3, item3){
    if(item3.field && item3.type == 'normal' && !item3.hide){
      var content =item1[item3.field]
      if(content === undefined || content === null) content = '';
      i1 == 0 && dataTitle.push(item3.title || '');
      vals.push('"'+ parseTempData(item3, content, item1, 'text') + '"');
    }
 });

这个content 就是输出的部分 还有一个问题就是 网页上面显示的 数据是处理过的 比如说 后端给的是1 我解析之后 是‘是’ 这样子导出到excel才是正确的 如果导出纯数据的话 毫无意义 所以这里应该 判断是否有那个templet函数 如果有就将我们处理数据的那个函数再调用一遍 没有的话就直接使用那个数据

var content = (typeof item3.templet == 'function' ? item3.templet(item1) : item1[item3.field])+'\t'+'';

网上说加上'\t'可以转化 我试过之后发现确实可以 修改成这样之后 得到的并不是我们要的 后面它还调用了parseTempData这个方法 找到这个方法

//解析自定义模板数据
  ,parseTempData = function(item3, content, tplData, text){ //表头数据、原始内容、表体数据、是否只返回文本
    var str = item3.templet ? function(){
      return typeof item3.templet === 'function' 
        ? item3.templet(tplData)
      : laytpl($(item3.templet).html() || String(content)).render(tplData) 
    }() : content;
    return text ? $('<div>'+ str +'</div>').text() : str;
  }

可以看到这里通过判断有没有templet函数 然后调用templet 那个函数 并没有转成文本的格式 导致数据显示异常 日期格式的会显示成### 所以这里其实可以不用调用这个方法 上面直接push content就行了 后面发现 如果我们在 templet 返回的数据带了标签 如果这个标签显示在excel文件也不太好 需要把它剔除掉 可以用正则的方式 把它剔除 content = content.replace(/<[^<>]+>/g,'') 到这里就可以将我们需要的数据导出到excel文件了 格式也没错数据也处理过了跟网页显示的一样

后面又因为数据删了之后 后端返回了null导致很多文本的处理报错 写方法的时候没有考虑到边界情况 导致templet方法报错 发现 layui 调用templet的方法也是在parseTempData里面调用的 可以在parseTempData方法里面将数据处理一遍 将为null的数据赋值空字符串 这样统一处理数据之后写代码就不会再出现报错的情况
每天进步一点点!