代码拉取完成,页面将自动刷新
同步操作将从 Jeexu/Easyui框架-右键拷贝+datagrid导出为xlsx文件 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/**
* ********************************
* 此文件需导入在body标签内
* ********************************
*
/************ easyui datagrid组件 右键菜单(copy) ***************************/
/**@desc 生成随机右键菜单的id值 */
const menuID = "menu" + Math.ceil(Math.random() * 10000).toString();
!(function () {
//创建菜单
const menu = document.body.appendChild(document.createElement("div"));
menu.id = menuID;
menu.classList.add("easyui-menu");
menu.style.display = "none";
menu.innerHTML = `
<div id="btn_CopyCell" data-options="iconCls:'icon-copycell'">拷贝此格</div>
<div id="btn_CopyLine" data-options="iconCls:'icon-line'">拷贝此行</div>
<div id="btn_CopySelect" data-options="iconCls:'icon-copyselect'">拷贝选中</div>
<div id="btn_CopyAllLines" data-options="iconCls:'icon-copyall'">拷贝所有行</div>
`;
})();
/**
* function --> 数据表添加右键copy
*
* @example 用法: onRowContextMenu: function (e, index, row) {
* onRowContextMenu_Copy.call(this, e, index, row)
* }
* @param {Event} e
* @param {int} index
* @param {object} row
*/
function onRowContextMenu_Copy(e, index, row) {
let that = this; // this为当前元素
// 阻止默认右键
e.preventDefault();
// 判断是否点击到行内,index ->当前所点击的行号
if (index != -1) {
$("#" + menuID).menu("show", {
//显示右键菜单
left: e.pageX, //在鼠标点击处显示菜单
top: e.pageY,
hideOnUnhover: false, // 当设置为false时,在鼠标离开菜单的时候将不会自动隐藏菜单。
onClick: function (item) {
switch (item.id) {
case "btn_CopyCell":
copyToClipboard(e.target.innerText);
break;
case "btn_CopyLine":
let rowValue = switchGriddataToText({
datagridName: that.id, rowType: 1, rowArray: [row], title: false,
});
copyToClipboard(rowValue);
break;
case "btn_CopySelect":
if ($("#" + that.id).datagrid("getSelections").length === 0) {
$.messager.show({
title: "消息",
msg: "<b style='font-size:150%;color:red;'>没有选中行</b>",
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 120,
});
} else {
let rowsValue = switchGriddataToText({
datagridName: that.id, rowType: 2, title: false
});
copyToClipboard(rowsValue);
}
break;
case "btn_CopyAllLines":
let rowsAllValue = switchGriddataToText({
datagridName: that.id, rowType: 3, title: true
});
copyToClipboard(rowsAllValue);
break;
default:
break;
}
},
});
}
}
/**
* 将datagrid的数据转换成 string
*
* @param {int} datagridName -> 表格id值
* @param {int} rowType -> 1,2,3 1:获取一行 2: 获取选中 3: 获取全部
* @param {Array} rowArray -> 当rowType:1时,传入数组,例如,[{id:1,name:"www"}]
* @param {boolen} title -> boolen 是否含表头
*/
function switchGriddataToText({ datagridName, rowType, rowArray, title = false }) {
/**@desc 存储返回的string */
let rowsValue = "";
/**@desc 储存表头信息的 filed */
let prop = [];
const state = $("#" + datagridName).datagrid("options");
// datagrid数据
const rows =
rowType == 3
? $("#" + datagridName).datagrid("getRows")
: rowType == 2
? $("#" + datagridName).datagrid("getSelections")
: rowArray;
// 判断是否是空数据
if (state.columns == "") return "";
//判断是否存在冻结列
if (state.frozenColumns != "") {
propFn(state.frozenColumns);
}
propFn(state.columns);
// 处理options里面的数据
function propFn(params) {
let flag = 0;
// 默认columns[0]中的title
for (let item of params[0]) {
// 判断title 、 field 以及隐藏列,符合判断语句则跳出此次循环
if (
!item.title ||
(!item.title && !item.field) ||
(item.hidden && item.hidden == true) ||
item.title == "√"
)
continue;
// 判断是否存在多表头
if (params.length > 1) {
function add(item, flag) {
if (
item.title &&
item.field &&
(!item.hidden || item.hidden != true) &&
(!item.colspan || item.colspan <= 1)
) {
prop.push(item);
} else if (item.colspan > 1) {
flag += 1;
for (let item2 of params[flag]) {
add(item2, flag);
}
}
}
add(item, flag);
} else {
prop.push(item);
}
}
}
let arr = [],
prop2 = [],
prop3 = [];
//去重
for (const item of prop) {
if (!arr.includes(item.field)) {
arr.push(item.field);
prop2.push(item);
}
}
// 取正确的
for (let $row of [rows[0]]) {
for (let index in prop2) {
let val = $row[prop2[index].field];
if (val === undefined && prop2[index].formatter != undefined) {
val = " ";
} else if (val === undefined && prop2[index].formatter === undefined) {
val = undefined;
}
if (val === undefined) continue;
prop3.push(prop2[index]);
}
}
prop = prop3;
// 如果需要表头
if (title) {
// 判断是否是多表头
if (state.columns.length > 1) {
let arr = []; //表头数组 为了判断 不插入重复值
let flag1 = 0; // colspan之前有多少项
let flag2 = 0; // colspan之前有多少项
// 根据columns.length得出多表头有几列,循环几次,把数据加入数组中
let length = Math.max(state.columns.length, state.frozenColumns.length);
for (let i = 0; i < length; i++) {
const column = state.columns[i] ? state.columns[i] : [];
const frozenColumn = state.frozenColumns[i] ? state.frozenColumns[i] : [];
for (let j = 0; j < flag2; j++) {
arr.push("\t");
}
addTitle(frozenColumn, i);
for (let j = 0; j < flag1; j++) {
arr.push("\t");
}
addTitle(column, i);
function addTitle(params, curr) {
for (const val of params) {
// 判断是否有title属性
if (
!val.title ||
(!val.title && !val.field) ||
(val.hidden && val.hidden == true) ||
val.title == "√"
)
continue;
if (params == []) {
flag1 = flag2 = 0;
} else if (params == state.frozenColumns[curr] && state.frozenColumns.length == 1) {
for (const iterator of params) {
flag2++;
}
} else if (params == state.frozenColumns[curr]) {
if ((!val.colspan || val.colspan <= 1) && val.rowspan && val.rowspan > 1) flag2++;
} else if (params == state.columns[curr]) {
if ((!val.colspan || val.colspan <= 1) && val.rowspan && val.rowspan > 1) flag1++;
}
}
// 多少个符合条件的
let count = 0,
i = 0;
for (const val of params) {
// 判断是否有title属性
if (
!val.title ||
(!val.title && !val.field) ||
(val.hidden && val.hidden == true) ||
val.title == "√"
)
continue;
count++;
}
for (const item of params) {
// 判断是否有title属性
if (
!item.title ||
(!item.title && !item.field) ||
(item.hidden && item.hidden == true) ||
item.title == "√"
)
continue;
i++;
// 最后一项
if (i == count && (params == state.columns[curr] || params == state.frozenColumns[curr])) {
if (item.colspan && item.colspan > 1) {
arr.push(item.title);
for (let k = 0; k < item.colspan - 1; k++) {
arr.push("\t");
}
} else {
arr.push(item.title);
}
if (params == state.columns[curr]) arr.push("\n");
if (params == state.frozenColumns[curr]) arr.push("\t");
} else if (params == state.columns[curr]) {
if (item.colspan && item.colspan > 1) {
arr.push(item.title);
for (let k = 0; k < item.colspan; k++) {
arr.push("\t");
}
} else {
arr.push(item.title + "\t ");
}
} else if (params == state.frozenColumns[curr]) {
if (item.colspan && item.colspan > 1) {
arr.push(item.title);
for (let k = 0; k < item.colspan; k++) {
arr.push("\t");
}
} else {
arr.push(item.title + "\t ");
}
}
}
}
}
rowsValue = arr.join("");
} else {
for (let index in prop) {
if (index == prop.length - 1) {
rowsValue += prop[index].title + "\n";
} else {
rowsValue += prop[index].title + "\t ";
}
}
}
}
// 根据表头的 field 属性 , 遍历内容
for (let i in rows) {
for (let index in prop) {
let val = rows[i][prop[index].field];
if (val === undefined && prop[index].formatter != undefined) {
val = prop[index].formatter(val, rows[i], i);
}
if (val === undefined) continue;
// 当数据是一行的最后一个
if (index == prop.length - 1) {
if (val === null || val.toString() === "") {
rowsValue += "\n";
} else {
// 如果存在格式化函数(formatter方法:原始数据 --->页面显示的数据)
if (prop[index].formatter != undefined && val != undefined) {
let format_val = prop[index].formatter(val, rows[i], i);
if (typeof format_val == 'string') {
format_val = format_val.replace(/<[^>]+>/g, "")
}
rowsValue += format_val + "\n";
} else {
// 如果数据中存在换行符
if (val.toString().trim().includes("\n")) {
rowsValue += '"' + val.toString().trim() + '"' + "\n";
} else if (val.toString().includes("\t")) {
rowsValue += val.toString().trim() + "\n";
} else {
rowsValue += val + "\n";
}
}
}
} else {
if (val === null || val.toString() === "") {
rowsValue += "\t ";
} else {
// 如果存在格式化函数(formatter方法:原始数据 --->页面显示的数据)
if (prop[index].formatter != undefined && val != undefined) {
let format_val = prop[index].formatter(val, rows[i], i);
if (typeof format_val == 'string') {
format_val = format_val.replace(/<[^>]+>/g, "")
}
rowsValue += format_val + "\t";
} else {
// 如果数据中存在换行符
if (val.toString().trim().includes("\n")) {
rowsValue += '"' + val.toString().trim() + '"' + "\t";
} else if (val.toString().includes("\t")) {
rowsValue += val.toString().trim() + "\t";
} else {
rowsValue += val + "\t";
}
}
}
}
}
}
return rowsValue.slice(0, -1);
}
/**
* 复制 str 到 剪切板
* 兼容 ie
*/
function copyToClipboard(str) {
if (!navigator.clipboard) {
textArea = document.createElement("textArea");
textArea.innerHTML = str;
textArea.value = str;
document.body.appendChild(textArea);
textArea.select();
try {
if (document.execCommand("Copy")) {
$.messager.show({
title: "消息",
msg: "<b style='font-size:150%'>复制成功</b>",
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 100,
});
} else {
$.messager.show({
title: "消息",
msg: "<span style='color:red;font-size:150%'>复制失败</span>",
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 100,
});
}
} catch (err) {
$.messager.show({
title: "消息",
msg: "<span style='color:red;font-size:150%'>复制失败</span>:" + err,
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 120,
});
}
document.body.removeChild(textArea);
} else {
navigator.clipboard.writeText(str).then(
function () {
let msg =
str == ""
? "<span style='color:red;font-size:150%'>复制内容为空</span>"
: "<b style='font-size:150%'>复制成功</b>";
$.messager.show({
title: "消息",
msg: msg,
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 120,
});
},
function () {
$.messager.show({
title: "消息",
msg: "<span style='color:red;font-size:150%'>复制失败</span>",
timeout: 700,
showType: "fade",
style: {
top: window.innerHeight / 5,
},
width: 200,
height: 120,
});
}
);
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。