最近接到一份新的需求,要求可以在结果集表单中增加“复制”操作,支持单行文本复制并可粘贴到Excel表格上,参考如下图:
作为一个后端开发,接到这个需求我的内心简直是万马奔腾~~~~,偏偏在接到需求的前一天部门制定了严苛的绩效考核,为了保住孩子的奶粉钱,我也只能披甲持锐披荆斩棘一往无前.....其实没那么高尚哈,只是第一次接触这样的需求想尝试一下,下面就和大家叙述一下解题思路
1.获取<tr>标签下所有<td>的内容
这个过程只要有一定的前端基础还是不难的,如果在度娘上搜索相关关键词,多数结果是获取<table>下所有<tr>的<td>内容,虽然与目的不符,但还是能拓宽思路,激发灵感。下面就上面的需求贴码:
HTML
<table>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>操作</th>
</tr>
<tr>
<td>许某话</td>
<td>男</td>
<td>55</td>
<td>庙堂中人</td>
<td><a href="javascript:void(0)" class="tr_copy">复制</a></td>
</tr>
<tr>
<td>许某心</td>
<td>女</td>
<td>18</td>
<td>遣唐使</td>
<td>
<a href="javascript:void(0)" class="tr_copy">复制</a>
</td>
</tr>
</table>
当点击复制时,通过JS获取当前“复制”行的数据,具体实现如下:
JS
$(".tr_copy").click(function () {
//通过.parent()获取到当前所在的<tr>标签对象,通过.find()获得当前<tr>下所有的<td>对象。
var array = $(this).parent().parent().find("td");
//创建空数组用于接收遍历出<td>的内容。
var dataArr = new Array();
//获取<td>对象数组的数量,此项可根据业务需求取舍
var len = array.length;
array.each(function (i) {
//因为最后一个<td>是操作项,所以不取
if (i < len - 1) {
//取出内容后去空格
var trData = $.trim($(this).text())
//将内容push到设置好的数组中
dataArr.push(trData);
}
});
//获取<td>数据的任务已经完成
var copyData = dataArr.join(",");
})
如果需求仅仅是获取某个<tr>下所有<td>的内容,上面的JS方法已经实现。
2.将内容复制到粘贴板并可以粘贴在Excel中
接下来问题来了
- 如何将拿到的数据同步到系统粘贴板
- 适应Excel的数据是什么样的格式
如何将拿到的数据同步到系统粘贴板呢,目前常见的实现粘贴到剪贴板主要有以下两种方法:
- 原生JS, 主要是
document.execCommand
方法 - 第三方库 clipboardjs(推荐)、zeroclipboard(已过时,不推荐)
使用原生JS时,必须有一个输入框input或者textarea,点击按钮时只能粘里面的内容。同时,若将input框设置display:none,在使用select()方法时,没有选中的内容,没法正常copy到剪切板。相对受限,并且添加输入框不符合本需求,所以我选择了三方插件clipboardjs
说起clipboardjs,有几种复制方法没有在官方文档中说明,可以通过官网提供的zip包中的demo去领会,为什么这么说呢?因为我通过文档上的方法没有解决问题,所以就去爬demo,结果还真找到了。
解决了内容复制的问题,下面就来处理一下支持Excel粘贴的格式是什么样的,说实话,刚看到这个需求的时候就特别熟悉,好像在哪里经常复制数据到Excel,相信经常用SQLyog(Navicat Premium好久不用已经忘了)的同学已经想到了。
适配Excel的数据是什么样呢?把数据复制成功后直接粘贴到txt文档就知道了,另外,具体的规则在上面的截图中已经告知,如:“\t”代表字段终止…
这两个问题解决后这个需求也就实现了,参考最终的JS
$(".tr_copy").click(function () {
//通过.parent()获取到当前所在的<tr>标签对象,通过.find()获得当前<tr>下所有的<td>对象。
var array = $(this).parent().parent().find("td");
//创建空数组用于接收遍历出<td>的内容。
var dataArr = new Array();
//获取<td>对象数组的数量,此项可根据业务需求取舍
var len = array.length;
array.each(function (i) {
//因为最后一个<td>是操作项,所以不取
if (i < len - 1) {
//取出内容后去空格
var trData = $.trim($(this).text())
//将内容push到设置好的数组中,这里加“ " ”是因业务需要
dataArr.push("\"" + trData + "\"");
}
});
//获取<td>数据的任务已经完成,下面的操作是为复制内容到Excel做准备工作
var copyData = dataArr.join("\t");
//使用clipboard.js插件完成复制,首先创建clipboard对象
var clipboard = new ClipboardJS('.tr_copy', {
text: function () {
return copyData;
}
});
//复制成功
clipboard.on('success', function (e) {
alert("复制成功");
e.clearSelection();
});
//复制失败
clipboard.on('error', function (e) {
alert("复制失败,请刷新后重试");
});
})
记录自我成长得轨迹,也希望能够帮到别人。