背景是用户需要把原本在Excel上填报的数据搬运到线上系统进行填报,在做了一个带输入框的表格之后用户提出希望能够实现将EXCEL上的数据复制黏贴到这个表格里的功能。
实现功能的整体思路是在input框上监听黏贴事件,获取到复制的数据。由于在Excel 中\t 表示换格,\n表示换行,所以我们可以根据此特性得到复制的数据一共是是几行几列,生成一个相对应的二维数组,在通过循环二维数组给相对应的单元格赋值。
1.监听黏贴事件。
<el-table-column v-for="(item, index) in tableTitle" :prop="item" :label="item" width="70"> <template slot-scope="scope2"> <div v-if="scope2.row.isSelected"> <el-input v-model="scope2.row[item]" class="tableInput" @paste.native="pasteExcel($event, scope2.$index, index, scope.row)"></el-input> </div> <div v-else>{{ scope2.row[item] }}</div> </template> </el-table-column>
2. 读取剪切板的数据并且根据\n,\t分割成数组
var data = null; var clipboardData = window.clipboardData || event.clipboardData; // IE || chrome data = clipboardData.getData('Text'); console.log(data); console.log(data.replace(/\t/g, '\\t').replace(/\n/g, '\\n')); //data转码 //解析数据 var arr = data.split('\n') .filter(function (item) { //兼容Excel行末\n,防止出现多余空行 return (item !== "") }).map(function (item) { return item.split("\t"); });
3.循环读取数组给相应的单元格赋值,这边需要注意的是要确定点击黏贴的单元格处于第几行第几列,这样才能正确的把后续的值赋值到对的地方,因为我这边表格是通过 v-for="(item, index) in tableTitle" 来动态生成的,所以通过传递 index就可以确定列,通过插槽中的scope.$index传递行数。
4.一切完成后我发现除了点击粘体的那个单元格,其他单元格都可以正常赋值,只有第一个单元格除了本该属于他的数据外还会将复制下来的数据全部黏贴上去。后续经过一番搜索发现是因为点击粘体后再执行完我们自己的方法后还是把剪贴板的所有数据复制到第一个单元格了,所以我们需要把页面的黏贴功能拦截。
document.addEventListener('paste', e => { e.preventDefault(); e.stopPropagation(); })
标签:数据,前端,单元格,EXCEL,表单,item,clipboardData,黏贴,data From: https://www.cnblogs.com/hegn/p/17573308.html