// ==UserScript== // @name Excel处理工具库 // @namespace https://scriptcat.org/ // @version 0.0.3 // @description 一个松耦合的Excel工具库 // @match *://*/* // @require https://cdn.bootcdn.net/ajax/libs/xlsx/0.17.0/xlsx.full.min.js // ==/UserScript== class ExcelHelper { constructor() { this.workbook = XLSX.utils.book_new(); // 创建新的工作簿 } /** * 添加工作表 * @param {string} sheetName - 工作表名称 * @param {Array} data - 需要添加到工作表的数据,支持字符串和超链接对象 */ addSheet(sheetName, data) { const worksheetData = data.map(row => row.map(cell => { // 检查单元格内容,如果是对象则创建超链接 if (typeof cell === 'object' && cell !== null && 'text' in cell && 'link' in cell) { return { l: { Target: cell.link, Tooltip: cell.text }, v: cell.text }; } return cell; // 普通字符串 })); const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); XLSX.utils.book_append_sheet(this.workbook, worksheet, sheetName); } /** * 导出 Excel 文件为 Blob * @returns {Blob} - 导出的 Excel Blob 对象 */ exportExcel() { const excelFile = XLSX.write(this.workbook, { bookType: 'xlsx', type: 'binary' }); return new Blob([this.s2ab(excelFile)], { type: "application/octet-stream" }); } /** * 设置单元格样式 * @param {string} cellAddress - 单元格地址,如 'A1' * @param {Object} style - 样式对象 */ setCellStyle(cellAddress, style) { const cell = this.workbook.Sheets[this.workbook.SheetNames[0]][cellAddress]; if (cell) { cell.s = style; } } /** * 辅助函数:将字符串转换为 ArrayBuffer * @param {string} s - 输入字符串 * @returns {ArrayBuffer} - 转换后的 ArrayBuffer */ s2ab(s) { const buf = new ArrayBuffer(s.length); const view = new Uint8Array(buf); for (let i = 0; i < s.length; i++) { view[i] = s.charCodeAt(i) & 0xFF; } return buf; } }