前几天使用 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的数据赋值空字符串 这样统一处理数据之后写代码就不会再出现报错的情况
每天进步一点点!