Greasy Fork is available in English.
Tampermonkey 菜单提供多个复制功能:订单编号、页面标题、.stat-value 值、bootstrap-table 表格数据(排除首尾列,支持 tab 分隔和 JSON 格式)
// ==UserScript==
// @name 多功能复制工具 - 订单/标题/表格/JSON
// @namespace https://github.com/你的github用户名 或 http://tampermonkey.net/
// @version 1.0
// @description Tampermonkey 菜单提供多个复制功能:订单编号、页面标题、.stat-value 值、bootstrap-table 表格数据(排除首尾列,支持 tab 分隔和 JSON 格式)
// @author lanbinbin
// @match *://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=grok.com
// @grant GM_registerMenuCommand
// @grant GM_setClipboard
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 原有的功能:复制订单编号
GM_registerMenuCommand("复制订单编号", function() {
// 你原本的复制订单编号的代码
// 例如:
let orderNo = document.querySelector('#order-id')?.textContent || '';
if (orderNo) {
GM_setClipboard(orderNo.trim());
alert('已复制订单编号:' + orderNo);
} else {
alert('找不到订单编号');
}
},"o");
// 新增的功能:复制页面标题
GM_registerMenuCommand("复制标题", function() {
const title = document.title.trim();
console.log(title);
GM_setClipboard(title);
alert('已复制页面标题:\n' + title);
},"t");
GM_registerMenuCommand("复制所有 stat-value", () => {
const elements = document.querySelectorAll('.stat-value');
if (elements.length === 0) {
alert('没有找到任何 class="stat-value"');
return;
}
// 把所有内容用换行符拼接
const allValues = Array.from(elements)
.map(el => el.textContent.trim())
.filter(text => text.length > 0)
.join('\n');
GM_setClipboard(allValues);
alert(`已复制 ${elements.length} 条内容到剪贴板:\n\n${allValues}`);
},"y");
GM_registerMenuCommand('复制表格数据(排除操作列)', () => {
const tableId = 'bootstrap-table';
const maxWaitSeconds = 12; // 最多等待 12 秒
const checkInterval = 400; // 每 400ms 检查一次
let attempts = 0;
const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval);
function tryCopyTable() {
attempts++;
const table = document.getElementById(tableId);
if (!table) {
if (attempts >= maxAttempts) {
alert(`未找到 id="${tableId}" 的表格`);
return;
}
setTimeout(tryCopyTable, checkInterval);
return;
}
// 优先找 tbody 里的行
let rows = table.querySelectorAll('tbody tr');
// 如果 tbody 里没行,尝试找所有不含 th 的 tr
if (rows.length === 0) {
rows = table.querySelectorAll('tr:not(:has(th))');
}
// 还没有数据行,继续等待
if (rows.length === 0) {
if (attempts >= maxAttempts) {
alert('表格中没有找到任何数据行(已等待足够时间)');
return;
}
setTimeout(tryCopyTable, checkInterval);
return;
}
// 开始处理数据
const result = [];
rows.forEach(row => {
// 获取所有 td
const cells = row.querySelectorAll('td');
// 如果这一行没有 td,或者 td 数量太少,跳过
if (cells.length <= 1) return;
// 去掉最后一列(操作列)
const dataCells = Array.from(cells).slice(0, -1);
// 提取文本
const rowData = dataCells
.map(cell => {
// 优先使用 data-value 属性(bootstrap-table 常用)
let text = cell.getAttribute('data-value') || cell.textContent;
text = (text || '').trim().replace(/\s+/g, ' ');
return text;
})
.filter(text => text.length > 0)
.join('\t');
if (rowData.trim()) {
result.push(rowData);
}
});
if (result.length === 0) {
alert('没有提取到任何有效数据');
return;
}
const textToCopy = result.join('\n');
GM_setClipboard(textToCopy);
alert(`已复制 ${result.length} 行数据(已排除最后一列)\n可粘贴到 Excel 或文本编辑器`);
console.log('复制的内容:\n' + textToCopy);
}
// 开始执行
tryCopyTable();
},"i");
GM_registerMenuCommand('复制表格为 JSON', () => {
const tableId = 'bootstrap-table';
const maxWaitSeconds = 12;
const checkInterval = 400;
let attempts = 0;
const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval);
function tryExtractAndCopy() {
attempts++;
const table = document.getElementById(tableId);
if (!table) {
if (attempts >= maxAttempts) {
alert(`未找到 id="${tableId}" 的表格`);
return;
}
setTimeout(tryExtractAndCopy, checkInterval);
return;
}
// 尝试获取表头
const thead = table.querySelector('thead');
let headers = [];
if (thead) {
const headerCells = thead.querySelectorAll('th');
headers = Array.from(headerCells)
.slice(0, -1) // 排除最后一列(操作列)
.map(th => {
let text = th.textContent.trim();
// 清理不适合做 key 的字符
text = text.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_');
return text || `col${headers.length + 1}`;
});
}
// 如果没有表头或表头为空,使用默认列名
if (headers.length === 0) {
// 可以在这里设置默认列名,或者等看到第一行有多少列再决定
headers = Array(10).fill().map((_, i) => `col${i + 1}`);
}
// 获取数据行
let rows = table.querySelectorAll('tbody tr');
if (rows.length === 0) {
rows = table.querySelectorAll('tr:not(:has(th))');
}
if (rows.length === 0) {
if (attempts >= maxAttempts) {
alert('表格中没有找到任何数据行');
return;
}
setTimeout(tryExtractAndCopy, checkInterval);
return;
}
// 开始收集数据
const data = [];
rows.forEach(row => {
const cells = row.querySelectorAll('td');
if (cells.length <= 1) return;
// 排除最后一列
const dataCells = Array.from(cells).slice(0, -1);
const rowObj = {};
dataCells.forEach((cell, index) => {
let value = cell.getAttribute('data-value') || cell.textContent.trim();
value = value.replace(/\s+/g, ' ');
// 如果值看起来像数字,尝试转为 number
if (/^-?\d+(\.\d+)?$/.test(value)) {
value = parseFloat(value);
}
const key = headers[index] || `col${index + 1}`;
rowObj[key] = value;
});
data.push(rowObj);
});
if (data.length === 0) {
alert('没有提取到任何有效数据');
return;
}
// 转为美观的 JSON 字符串
const jsonString = JSON.stringify(data, null, 2);
// 复制到剪贴板
GM_setClipboard(jsonString);
alert(`已复制 ${data.length} 条记录的 JSON 数据到剪贴板\n(可粘贴到编辑器查看)`);
// 在控制台也输出,便于调试
console.log('已复制的 JSON 数据:');
console.log(jsonString);
}
// 开始执行
tryExtractAndCopy();
},"a");
GM_registerMenuCommand('复制表格为 JSON (col1/col2)', () => {
const tableId = 'bootstrap-table';
const maxWaitSeconds = 12;
const checkInterval = 400;
let attempts = 0;
const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval);
function tryExtractAndCopy() {
attempts++;
const table = document.getElementById(tableId);
if (!table) {
if (attempts >= maxAttempts) {
alert(`未找到 id="${tableId}" 的表格`);
return;
}
setTimeout(tryExtractAndCopy, checkInterval);
return;
}
// 获取数据行
let rows = table.querySelectorAll('tbody tr');
if (rows.length === 0) {
rows = table.querySelectorAll('tr:not(:has(th))');
}
if (rows.length === 0) {
if (attempts >= maxAttempts) {
alert('表格中没有找到任何数据行');
return;
}
setTimeout(tryExtractAndCopy, checkInterval);
return;
}
// 收集数据
const data = [];
rows.forEach(row => {
const cells = row.querySelectorAll('td');
// 至少要有 3 列才处理(去掉首尾后至少剩 1 列才有意义)
if (cells.length < 3) return;
// 去掉第一列和最后一列
const dataCells = Array.from(cells).slice(1, -1);
const rowObj = {};
dataCells.forEach((cell, index) => {
let value = cell.getAttribute('data-value') || cell.textContent.trim();
value = value.replace(/\s+/g, ' ');
// 尝试转为数字(可选,根据你的数据决定是否保留)
if (/^-?\d+(\.\d+)?$/.test(value)) {
value = parseFloat(value);
} else if (/^\d{4}-\d{2}-\d{2}/.test(value)) {
// 日期格式保持字符串
value = value;
}
// key 使用 col1, col2, col3 ...
const key = `col${index + 1}`;
rowObj[key] = value;
});
// 只有当有实际数据时才加入
if (Object.keys(rowObj).length > 0) {
data.push(rowObj);
}
});
if (data.length === 0) {
alert('没有提取到任何有效数据');
return;
}
// 转为格式化的 JSON
const jsonString = JSON.stringify(data, null, 2);
// 复制到剪贴板
GM_setClipboard(jsonString);
alert(`已复制 ${data.length} 条记录(JSON 格式,key 为 col1/col2...)`);
// 在控制台输出查看
console.log('已复制的 JSON 数据:');
console.log(jsonString);
}
// 开始执行
tryExtractAndCopy();
},"b");
})();