之前有一个功能是做导入商品,但是不是使用excel或者文档之类的直接导入,然后后台解析数据。此次采用的是用户直接复制excel中的数据到文本域中,前端再解析数据,解析为一个二维数组的方式,再传给后台查询完整信息。(项目比较老,使用jsp+jq完成的)。每行数据列数不确定(但对于前端不重要,有多少传多少,反正每一行的列数是相同的),但是列信息不一定全必录。
为适应项目,首先想到了采用如下的方式去显示和处理数据
页面显示部分如下:
<textarea type="text" id="inputInfo" value="">xxx</textarea>
关于数据处理:
// 把复制过来的数据转换为二维数组
formaterValToJSON() {
var _fmt = /\t/;
var val = this.$_inputInfo.val() || _fmt;
if (val == this.$_inputInfo[0].defaultValue) {
return false;
}
var rowArr = val.split('\n');
var _rowArr = [];
for (var i = 0, lenR = rowArr.length; i < lenR; i++) {
if (rowArr[i] == '' || rowArr[i].replace(/\t/g, '') == '') {
continue;
}
var colArr = rowArr[i].split(_fmt);
var _colArr = [];
for (var j = 0, lenC = colArr.length; j < lenC; j++) {
_colArr.push(colArr[j]);
}
_rowArr.push(_colArr);
}
if (_rowArr.length == 0) {
return false;
}
return _rowArr;
}
这种方式能够很快的达到预期效果,只是关于导入完成后的数据处理在项目中比较麻烦,但这一步操作开发是很快的。
但同时也具有局限性,只考虑了用户从excel复制过来的数据,当时也没有测试从word过来的表格是不是一个效果,没有注意,需求也没有讲到这里,就跳过了。用户复制到文本域的内容也是不规则的,毕竟只是一个textarea,没有样式相关显示操作处理,只是简单实现一下就结束了。
可见,简单的完成,导致的结果是局限性太大,而且交互体验也不是很好,用户没办法在文本域中检查数据,因为列不是必录,也可能长短不一,所以每一列没有对齐,根本没有办法检查数据,只能点击导入之后再看看是不是正确的了........
于是,为了好看,我选择了曾经使用过的UEditor富文本编辑器,开开心心地去一步一步实现...
先引入必要的文件:
<script type="text/javascript" charset="utf-8" src="../ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="../ueditor/ueditor.all.min.js"> </script>
<script type="text/javascript" charset="utf-8" src="../ueditor/lang/zh-cn/zh-cn.js"></script>
然后还是加一个文本域(重要的是id,标签的话,应该是块标签就可以吧,以前我用的div):
<textarea id="inputInfo" type="text/plain"></textarea>
然后就去初始化我们的富文本编辑器了:
ueditor = UE.getEditor('inputInfo', {
toolbars: [
['fullscreen', 'undo', 'redo', 'selectall', 'searchreplace', 'cleardoc', 'preview']
],
autoHeightEnabled: false,
autoFloatEnabled: true,
initialFrameWidth: 850,
elementPathEnabled: false,
wordCount: false,
enableContextMenu: true,
autotypeset: {
removeEmptyline: true,
clearFontSize: true,
clearFontFamily: true
},
retainOnlyLabelPasted: true,
initialContent: 'xxx',
autoClearinitialContent: true
});
ueditor.ready(function() {
var height = $(window).height() - $("#inputInfo").offset().top - 50;
ueditor.setHeight(height);
$(".edui-editor-messageholder.edui-default").css({ "visibility": "hidden" });
UE.dom.domUtils.on(ueditor.body, 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (e.ctrlKey && keyCode == 86) {
ctrlV = true;
}
});
});
UE.getEditor('inputInfoShow').addListener('contentChange', function() {
// 如果内容改变就去触发事件,不太友好,所以只在粘贴内容的时候再去触发比较合适
if (ctrlV) {
THISPAGE.formaterValToHTML();
ctrlV = !ctrlV;
}
});
我只保留了很少的工具栏工具,因为我这里用不上,所以选了几个可以用得上的,初始化配置也是配置了需要用的东西。关于配置可以看文档编辑器初始化配置、工具栏配置。
完了之后一切ok。
对了中间有监听键盘事件,因为我只想在用户复制的时候去处理一下数据,因为在这里显示必须是表格,所以我想也不会有人无聊到去弄这个玩,而是为了功能使用达到目的即可。所以即使想添加数据,那也可以插入行,后面我提取table里面的数据就好了。不是复制的时候去改变数据,那就不用再继续去触发事件了,没必要。
一切ok,复制过来显示都ok,但是提交数据的时候才觉得难受,以前使用把样式保存一下就好,没必要做数据处理,毕竟我们显示的时候直接拿然后显示html就好,不用处理什么的。
现在却需要去处理table数据,内置的getContentTxt()不能达到要求,因为它只能取到文本,而我需要的是数组....
所以,我又开启了处理数据的代码编写......
var val = ueditor.getContent();
// 从word复制过来的表格里面会自动带出一系列样式及其他标签,先给过滤掉,只保留table类标签,便于提取数据
val = val.replace(/<(\/)?(p|br|span|strong|div)(\/)?>/g, '');
console.log(val)
var inputData = [];
val.replace(/<tr.*<\/tr>/g, function() {
var trArr = arguments[0].split('</tr>');
for (var i = 0, lenTR = trArr.length; i < lenTR; i++) {
var flag = false;
_trDataArr = [];
var item = trArr[i];
if (item == '') {
continue;
}
item.replace(/<td.*<\/td>/g, function() {
var tdArr = arguments[0].split('</td>');
for (var j =0, lenTD = tdArr.length; j < lenTD; j++) {
var ele = tdArr[j];
if (ele == '') {
continue;
}
var str = ele.replace(/<td.*>/ig, '');
if (!flag && str != '') {
flag = true;
}
_trDataArr.push(str);
}
});
// 空行跳过
if (flag) {
inputData.push(_trDataArr);
}
}
});
return inputData;
就采用这样的方式去提取table里面的数据并且格式化为二维数组......
但是同样有局限性,只适用于从各处复制来的表格,如果不是表格,还是需要在之前的监听函数那里先格式化为二维数组,再拼接出一个html显示回去才行.......同时,复制的格式需要限定,否则根本没必要做除了表格之外的复制数据处理.....
就这样了,只做了表格的,别的还在思考中,想想其实也没必要做~~~用excel就能处理好,而且还很方便,我想也没人选择用一大块不规则的 文本 来存自己的多行多列信息吧~~~
关于有看到有大佬说用 form 提交之类的,我想了想,可能不太适合这种场景,也就没去试了。。。
希望各位大佬指教,这样就可以优化了,O(∩_∩)O哈哈~~~