百度|原创力|人人|360文库|豆丁|豆丁建筑|道客|MBA智库|得力|七彩学科|金锄头|#问|蚂蚁|读根网|搜弘|微传网|淘豆网|GB|JJG|行业标准|轻竹办公|自然标准|交通标准|飞书|江苏计量|水利部|招投标|能源标准|认证认可标准|腾讯文档|绿色建站|电网等公开免费文档下载
// ==UserScript== // @name 【最强无套路脚本】你能看见多少我能下载多少&下载公开免费的PPT、PDF、DOC、TXT等文件 // @namespace http://tampermonkey.net/ // @homepage https://github.com/systemmin/kill-doc // @version 6.5 // @description 百度|原创力|人人|360文库|豆丁|豆丁建筑|道客|MBA智库|得力|七彩学科|金锄头|#问|蚂蚁|读根网|搜弘|微传网|淘豆网|GB|JJG|行业标准|轻竹办公|自然标准|交通标准|飞书|江苏计量|水利部|招投标|能源标准|认证认可标准|腾讯文档|绿色建站|电网等公开免费文档下载 // @author Mr.Fang // @match https://*.book118.com/* // @match https://*.renrendoc.com/* // @match https://*.docin.com/* // @match https://*.doc88.com/* // @match https://doc.mbalib.com/* // @match https://*.deliwenku.com/* // @match https://www.jinchutou.com/* // @match https://*.goldhoe.com/* // @match https://*.mayiwenku.com/* // @match https://*.dugen.com/* // @match https://*.7cxk.com/* // @match https://ishare.iask.com/* // @match https://swf.iask.com/* // @match https://*.down.sina.com.cn/* // @match https://wenku.baidu.com/* // @match https://wkbjcloudbos.bdimg.com/* // @match https://wkretype.bdimg.com/* // @match https://*.cho#####.com/* // @match https://*.weizhuannet.com/* // @match https://www.taodocs.com/* // @match https://wenku.so.com/* // @match https://*.360tres.com/* // @match https://www.wenkub.com/* // @match http://c.gb688.cn/* // @match https://jjg.spc.org.cn/resmea/view/stdonline // @match https://pro-img-brtm.baijiayun.com/* // @match https://hbba.sacinfo.org.cn/attachment/onlineRead/* // @match https://www.qzoffice.com/* // @match http://www.nrsis.org.cn/mnr_kfs/file/read/* // @match https://*.feishu.cn/space/* // @match http://www.jtysbz.cn:8009/pdf/viewer/* // @match https://www.nssi.org.cn/cssn/js/pdfjs/web/preview.jsp* // @match https://online.71nc.cn/* // @match http://114.251.111.103:18080/kfs/file/read/* // @match https://bulletin.cebpubservice.com/resource/ceb/js/pdfjs-dist/web/viewer.html* // @match http://121.36.94.83:9008/jsp/yishenqing/appladd/biaozhunfile/flash/previewImg.jsp* // @match http://rbtest.cnca.cn/cnca_kfs/file/read/* // @match https://weboffice.qq.com/pdf/* // @match https://gbservice.cn/* // @match https://ecp.sgcc.com.cn/* // @require https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jspdf/2.4.0/jspdf.umd.min.js // @require https://unpkg.com/@zip.js/[email protected]/dist/zip.min.js // @require https://unpkg.com/[email protected]/dist/html2canvas.js // @icon https://dtking.cn/favicon.ico // @run-at document-idle // @grant GM_getValue // @grant GM_deleteValue // @grant GM_setValue // @grant GM_download // @grant GM_notification // @grant GM_addStyle // @grant unsafeWindow // @license Apache-2.0 // ==/UserScript== (function() { 'use strict'; let MF = '#MF_fixed{position:fixed;top:50%;transform:translateY(-50%);right:20px;gap:20px;flex-direction:column;z-index:2147483647;display:flex}'; MF += '.MF_box{padding:10px;cursor:pointer;border-color:rgb(0,102,255);border-radius:5px;background-color:white;color:rgb(0,102,255);margin-right:10px;box-shadow:rgb(207,207,207) 1px 1px 9px 3px}.MF_active{color: green}#MF_speed{color: red;}'; MF += '@media print{html{height:auto !important}body{display:block !important}#app-left{display:none !important}#app-right{display:none !important}#MF_fixed{display:none !important}.menubar{display:none !important}.top-bar-right{display:none !important}.user-guide{display:none !important}#app-reader-editor-below{display:none !important}.no-full-screen{display:none !important}.comp-vip-pop{display:none !important}.center-wrapper{width:auto !important}.reader-thumb,.related-doc-list,.fold-page-content,.try-end-fold-page,.lazy-load,#MF_textarea,#nav-menu-wrap{display:none !important}}' const prefix = "MF_"; // canvas 禁止重写 drawImage const canvasRenderingContext2DPrototype = CanvasRenderingContext2D.prototype; const originalDrawImage = canvasRenderingContext2DPrototype.drawImage; Object.defineProperty(canvasRenderingContext2DPrototype, 'drawImage', { value: originalDrawImage, writable: false, configurable: false }); // 重写 setTimeout const originalSetTimeout = unsafeWindow.setTimeout; unsafeWindow.setTimeout = function(callback, delay, ...args) { let toStr = callback?.toString(); if (toStr && toStr.includes('revokeObjectURL')) return true; const wrappedCallback = function() { if (callback instanceof Function) { callback(...args); } }; return originalSetTimeout(wrappedCallback, delay); }; function generateRandomString() { let r###lt = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; const charactersLength = characters.length; for (let i = 0; i < 5; i++) { r###lt += characters.charAt(Math.floor(Math.random() * charactersLength)); } return r###lt; } const boxId = generateRandomString() const mainStyle = MF.replaceAll('MF_fixed', prefix + boxId); GM_addStyle(mainStyle) /** * @description 添加 URL 到本地缓存 * @author Mr.Fang * @time 2024年2月4日 * @param {Array} urls 数据 * @param key */ const MF_addURL = (urls, key = 'listData') => { const value = GM_getValue(key) || "[]"; let listData = JSON.parse(value); let index = 0; let length = listData.length; urls.forEach((url) => { if (!listData.some(item => item.src === url)) { // 添加新的URL对象 listData.push({ src: url, page: length + index }); index++; } }) localStorage.setItem(key, JSON.stringify(listData)); GM_setValue(key, JSON.stringify(listData)); console.log(GM_getValue("listData")); console.log('已添加URL:', urls.length); } /** * Url 地址拼接,无需预览直接从 HTML 中读取相应的参数即可 */ const loadingUrls = (params) => { const _pageCount = Viewer._pageCount; console.log(_pageCount); let dp; if (params) { dp = u.query('#dp').value.replace('www', 'ww'); // 读根网特殊情况 } else { dp = u.query('#dp').value; } const urls = []; for (var i = 1; i < _pageCount + 1; i++) { let u = dp + i + ".gif"; urls.push(u); } MF_addURL(urls); } /** * Url 地址拼接,无需预览直接从 HTML 中读取相应的参数即可 */ const joinDownloadURL = (baseUrl) => { const size = Page.size; const urls = []; for (var i = 0; i < size; i++) { urls.push(baseUrl + '/' + i + '.png'); } MF_addURL(urls); } class Box { id = ""; // id label = ""; // 按钮文本 fun = ""; // 执行方法 constructor(id, label, fun) { this.id = id; this.label = label; this.fun = fun; } } class Utility { debug = true; /** * 添加 css 样式 * @param e 节点 * @param data JSON 格式样式 */ style(e, data) { Object.keys(data).forEach(key => { e.style[key] = data[key] }) } attr(e, key, val) { if (!val) { return e.getAttribute(key); } else { e.setAttribute(key, val); } } /** * 追加样式 * @param css 格式样式 */ appendStyle(css) { let style = this.createEl('', 'style'); style.textContent = css; style.type = 'text/css'; let dom = document.head || document.documentElement; dom.appendChild(style); } /** * @description 创建 dom * @param id 必填 * @param elType * @param data */ createEl(id, elType, data) { const el = document.createElement(elType); el.id = id || ''; if (data) { this.style(el, data); } return el; } query(el) { return document.querySelector(el); } queryAll(el) { return document.querySelectorAll(el); } update(el, text) { const elNode = this.query(el); if (!elNode) { console.log('节点不存在'); } else { elNode.innerHTML = text; } } /** * 进度 * @param current 当前数量 -1预览结束 * @param total 总数量 * @param content 内容 */ preview(current, total, content) { return new Promise(async (resolve, reject) => { if (current === -1) { this.update('#' + prefix + 'text', content ? content : "已完成"); } else { let p = (current / total) * 100; let ps = p.toFixed(0) > 100 ? 100 : p.toFixed(0); console.log('当前进度', ps) this.update('#' + prefix + 'text', '进度' + ps + '%'); await this.sleep(500); resolve(); } }) } preText(content) { this.update('#' + prefix + 'text', content); } gui(boxs) { const box = this.createEl(prefix + boxId, 'div'); for (let x in boxs) { let item = boxs[x]; if (!item.id) continue; let el = this.createEl(prefix + item.id, 'button'); el.append(new Text(item.label)); if (x === '0') { el.classList = prefix + 'box ' + prefix + "active"; } else { el.className = prefix + "box"; } if (item.fun) { el.onclick = function() { eval(item.fun); } } if (item.id === 'speed') { this.attr(el, 'contenteditable', true) } box.append(el); } document.body.append(box); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } log(msg) { if (this.debug) { console.log(msg); } } logt(msg) { if (this.debug) { console.table(msg); } } } const u = new Utility(); const btns = [ new Box('text', '状态 0 %'), new Box('start', '自动预览', 'autoPreview()'), new Box('stop', '停止预览', 'stopPreview()'), new Box('down', '下载图片', 'executeDownload(2)'), new Box('pdf', '下载PDF', 'executeDownload(1)') ] const domain = { renrendoc: "renrendoc.com", book118: 'book118.com', docin: 'docin.com', wenku: 'wenku.baidu.com', so: 'wenku.so.com', doc88: 'doc88.com', mbalib: 'doc.mbalib.com', deliwenku: 'deliwenku.com', cxk: '7cxk.com', jinchutou: 'jinchutou.com', mayiwenku: 'mayiwenku.com', dugen: 'ww.dugen.com', iask: 'ishare.iask.com', cho#####: 'cho#####.com', weizhuan: 'weizhuannet.com', taodocs: 'taodocs.com', wenkub: 'wenkub.com', gb688: 'gb688.cn', jjg: 'jjg.spc.org.cn', shengtongedu: 'pro-img-brtm.baijiayun.com', sacinfo: 'hbba.sacinfo.org.cn', qzoffice: 'www.qzoffice.com', nrsis: 'www.nrsis.org.cn', nea: '114.251.111.103:18080', nssi: 'www.nssi.org.cn', feishu: 'feishu.cn', jtysbz: 'jtysbz.cn', jsjlw: 'online.71nc.cn', mwr: '121.36.94.83:9008', cebpubservice: 'bulletin.cebpubservice.com', rbtest: 'rbtest.cnca.cn', weboffice: 'weboffice.qq.com', gbservice: 'gbservice.cn', sgcc: 'ecp.sgcc.com.cn', }; const { host, href, origin } = window.location; const jsPDF = jspdf.jsPDF; let zipWriter; // 声明全局变量 zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true, useCompressionStream: false }); const doc = new jsPDF({ orientation: 'p', unit: 'px', compress: true }); let pdf_w = 446, pdf_h = 631, loading = 500, // 毫秒 pdf_ratio = 0.56, title = document.title, fileType = '', downType = 1, // 下载文件类型 select = null, selectBox = null, dom = null, beforeFun = null, interval = null, startPageNo = 0, BASE_URL = 'https://wkretype.bdimg.com/retype', readerInfoBai = null, // 百度文档参数 intervalBai = null; // 百度定时任务 if (host.includes(domain.taodocs)) { iscopy = 'TRUE'; // taodocs copy flag } const params = new URLSearchParams(document.location.search.substring(1)); if (params.size && params.get('custom')) { window.parent.postMessage({ type: "onload", value: 'success' }, "*") u.log('子页面加载完成!'); } // 百度拷贝文本 const baiduCopy = () => { const copyEvent = () => { let link = document.querySelector('.link'); let textContent = link ? link.textContent : ""; let r###lt = textContent ? textContent.substring(textContent.indexOf('“') + 1, textContent .lastIndexOf('”')) : window.getSelection().toString(); let textarea = u.query('#MF_textarea'); if (textarea) { textarea.innerText = r###lt; } else { textarea = u.createEl('MF_textarea', 'textarea'); let style = { width: "100%", height: "200px", outline: "none", padding: "10px", boxSizing: "border-box", fontSize: "16px", border: "1px solid rgb(204, 204, 204)" } u.style(textarea, style) document.querySelector('.mdInput-text').innerText = r###lt; let box = u.query('#catalog-main') || u.query('.catalog-main') || u.query( '.related-doc-list') box.before(textarea); } } const observerOptions = { characterData: true, subtree: true }; // dom 监听器 const observer = new MutationObserver(function(mutationList, observer) { copyEvent() }); const targetNodeWrap = document.querySelector('.search-r###lt-wrap'); // 触发监听 observer.observe(targetNodeWrap, observerOptions); document.addEventListener('mouseup', function() { var selection = window.getSelection(); if (selection.rangeCount > 0) { copyEvent() } }); } // 百度 xhr 数据监听 if (host.includes(domain.wenku)) { const _r_text = window.Response.prototype.text; window.Response.prototype.text = function() { return new Promise((resolve, reject) => { _r_text.call(this).then((text) => { resolve(text); }).catch(reject); }); } const _open = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function(...args) { this.addEventListener("load", () => { try { let content = this.responseText; const url = args[1]; if (url.includes('ndocview/readerinfo')) { const { data } = JSON.parse(content); const htmlUrls = data.htmlUrls; let list = htmlUrls.png; let images = []; if (list) { images = htmlUrls.png.map(item => { return item.pageLoadUrl }); } else { images = htmlUrls; } // 文本内容地址保存 if (htmlUrls.json) { let pageLoadUrl = htmlUrls.json.map(item => { return item.pageLoadUrl }) MF_addURL(pageLoadUrl, 'pageData'); } // 纯文本类型文件 if (fileType === "txt") { // 纯文本类型 let urls = []; const { docId, freePage, rsign, md5sum } = data; for (var i = readerInfoBai.showPage + 1; i < freePage + 1; i++) { let x = md5sum.substring(1); let n = ["pn=" + i, "rn=1", "type=txt", "spr=0", "rsign=" + rsign, "callback=wenku_" + i ].join("&"); let url = BASE_URL + "/text/" + docId + "?" + x + "&" + n; urls.push(url) } MF_addURL(urls, 'pageData'); } MF_addURL(images); } } catch {} }); return _open.apply(this, args); } } const childMessage = (message) => { window.parent.postMessage({ type: "child", value: message ? message : '' }, "*") } const parentMessage = (message, attr) => { const ifarme = document.getElementById(attr); let _window = ifarme.contentWindow; _window.postMessage({ type: 'parent', value: message ? message : '' }, "*") } // 监听页面消息事件 window.addEventListener("message", (e) => { // console.log(e) const { type, value } = e.data; if (type === 'parent') { // 父级-子页面消息 if (value.includes(origin)) { MF_ImageToBase64(value).then(data => { childMessage(data); }) } } else if (type === 'child') { // 子页面-到父页面消息 let index = Number(localStorage.getItem("current") || "0"); let length = Number(localStorage.getItem("length") || "0"); const { blob, uint8, width, height } = value; if (fileType.includes('ppt') || width > height) { doc.addPage([width * pdf_ratio, height * pdf_ratio], 'l'); doc.addImage(uint8, 'JPEG', 0, 0, width * pdf_ratio, height * pdf_ratio, index, 'FAST') } else { doc.addPage(); doc.addImage(uint8, 'JPEG', 0, 0, pdf_w, pdf_h, index, 'FAST') } if (index === 1) { doc.deletePage(1); } zipWriter.add(index + ".png", new zip.BlobReader(blob)); localStorage.setItem('current', index + 1 + ""); downimg(); } else if (type === 'onload') { const url = new URL(e.origin); const attrId = url.host.replaceAll(".", ""); const query = document.getElementById('#' + attrId); if (query) { downimg(); } } }) /** * @description 前置方法 * @author Mr.Fang * @time 2024年2月2日 */ const before = () => { if (beforeFun) { u.log('---------->beforeFun'); eval(beforeFun) } // 画布添加监听事件,当数据加载完成删除 id,防止数据被清空 if (host.includes(domain.wenku)) { const els = u.queryAll('canvas'); for (var i = 0; i < els.length; i++) { let eNode = els[i]; const intersectionObserver = new IntersectionObserver((entries) => { let isIntersecting = entries[0].isIntersecting if (isIntersecting && eNode.width && eNode.height) { eNode.id = ''; } }); // 开始监听 intersectionObserver.observe(eNode); } } } /** * @description 初始化方法 * @author Mr.Fang * @time 2024年2月2日 */ const init = () => { console.table({ host, href, origin }) dom = document.documentElement || document.body; if (host.includes(domain.renrendoc)) { if (!/.*renrendoc\.com\/.+$/.test(href)) { u.log('结束'); return; } const node = u.query('h1'); title = node.innerText.replaceAll(" ", ""); node.nextElementSibling.children const innerText = node.nextElementSibling.children[6].innerText; fileType = innerText.split(":")[1].toLowerCase(); dom = u.query('.main-content'); beforeFun = "let er = u.query('#load_preview_btn');if (er && er.style.display !== 'none') {er.click()}"; select = "#page img"; btns.push(new Box('PPT', '获取地址', 'downtxt()')) } else if (host.includes(domain.book118)) { if (!/.+book118\.com\/.+$/.test(href)) { u.log('结束'); return; } if (!href.includes('pptView.html') && !params.get("readpage")) { let node = u.query('h1') node = node ? node : u.query('h2'); title = node.innerText.replaceAll(" ", "").replaceAll("VIP", ""); const number = title.lastIndexOf("."); fileType = title.substring(number + 1).toLowerCase(); GM_setValue('title', title); if (fileType.includes('ppt')) { beforeFun = "let eb = u.query('#btn_ppt_front_pc');if (eb) {eb.click();}"; } else { beforeFun = "let eb = u.query('#btn_preview_remain');if (eb) {eb.click();}"; } } else { fileType = 'ppt'; title = GM_getValue('title'); } select = ".webpreview-item img"; btns.push(new Box('PPT', '获取地址', 'downtxt()')) } else if (host.includes(domain.docin)) { if (!/.+docin\.com\/.+$/.test(href)) { u.log('结束'); return; } select = "#contentcontainer canvas"; const toImg = params.get('toImg'); console.log('toImg', toImg); title = u.query('meta[property="og:title"]').content; fileType = u.attr(u.query('h1').children[0], 'title').toLowerCase(); if (toImg && toImg === '1') { select = "#contentcontainer img" } console.log('toImg', select); if (isUserLogin === '1') { // 登录 beforeFun = "let eb = u.query('.model-fold-show');if (eb) {eb.click();}"; } if (fileType.includes('ppt') || (toImg && toImg === '1')) { btns.push(new Box('PPT', '获取地址', 'downtxt()')) } } else if (host.includes(domain.wenku)) { if (!/.+wenku\.baidu\.com\/(tfview|view).+$/.test(href)) { u.log('结束'); return; } dom = u.query('.reader-wrap'); beforeFun = "let eb = u.query('.unfold')?u.query('.unfold'):u.query('.read-all');if (eb) {eb.click();}"; select = "#original-creader-root canvas"; btns.push(new Box('print-pdf', '打印PDF', 'window.print()')) if (fileType.includes('ppt') || fileType.includes('pdf')) { btns.push(new Box('PPT', '获取地址', 'downtxt()')) } else { btns.push(new Box('get-text', '获取文本', 'fullText()')) } } else if (host.includes(domain.so)) { if (!/.+wenku\.so\.com\/.+$/.test(href)) { u.log('结束'); return; } const { Title, DocType, Field03 } = asyncData.DocInfo; title = Title; fileType = DocType.toLowerCase();; btns.splice(1, 2); btns.push(new Box('PPT', '获取地址', 'downtxt()')); MF_addURL(Field03); } else if (host.includes(domain.doc88)) { if (!/.+doc88\.com\/.+$/.test(href)) { u.log('结束'); return; } title = u.query('meta[property="og:title"]').content; fileType = u.query("#box1 .attribute").innerText.split(" ")[0].split(":")[1].toLowerCase(); beforeFun = "let eb = u.query('#continueButton');if (eb) {eb.click();}"; select = "#pageContainer .inner_page"; btns.push(new Box('get-text', '获取文本', 'fullText()')) } else if (host.includes(domain.mbalib)) { if (!/doc\.mbalib\.com\/.+$/.test(href)) { u.log('结束'); return; } dom = u.query('#scroll-m-box'); title = u.query('h1 p').innerText; fileType = title.substring(title.indexOf('.') + 1).toLowerCase(); select = "#viewer .page" btns.splice(1, 0, new Box('speed', '500')); btns.push(new Box('get-text', '获取文本', 'fullText()')) } else if (host.includes(domain.deliwenku) || host.includes(domain.cxk) || host.includes(domain.jinchutou) || host.includes(domain.mayiwenku) || host.includes(domain.dugen) || host.includes(domain.cho#####) || host.includes(domain.weizhuan) ) { if ((!/.+deliwenku\.com\/.+$/.test(href)) && (!/.+7cxk\.com\/.+$/.test(href)) && (!/.+jinchutou\.com\/.+$/.test(href)) && (!/.+mayiwenku\.com\/.+$/.test(href)) && (!/ww\.dugen\.com\/.+$/.test(href)) && (!/.+cho#####\.com\/.+$/.test(href)) && (!/.+weizhuannet\.com\/.+$/.test(href)) ) { return; } GM_deleteValue('listData'); // 清空 // 蚂蚁需手动点击全文 if (host.includes(domain.mayiwenku) || host.includes(domain.dugen)) { preview(); loadingUrls(host.includes(domain.dugen)); } else { loadingUrls(); } if (host.includes(domain.cho#####)) { title = u.query('h1').innerText; fileType = title.substring(title.indexOf('.') + 1).toLowerCase(); } else { title = u.query('meta[property="og:title"]').content; fileType = u.query('meta[property="og:document:type"]').content.toLowerCase(); } btns.splice(1, 2); btns.push(new Box('PPT', '获取地址', 'downtxt()')) } else if (host.includes(domain.iask)) { if (!/ishare\.iask\.com\/.+$/.test(href)) return; title = pageConfig.access.title; fileType = pageConfig.access.format.toLowerCase();; btns.splice(1, 2); btns.push(new Box('PPT', '获取地址', 'downtxt()')) MF_addURL(pageConfig.imgUrl); } else if (host.includes(domain.taodocs)) { if (!/www\.taodocs\.com\/.+$/.test(href)) return; title = u.query('h1').innerText; fileType = title.substring(title.indexOf('.') + 1).toLowerCase(); beforeFun = "let eb = u.query('.fc2e');if (eb) {eb.click();}"; select = "#canvas canvas"; btns.push(new Box('get-text', '获取文本', 'fullText()')) } else if (host.includes(domain.wenkub)) { if (!/www\.wenkub\.com\/.+$/.test(href)) return; title = u.query('h1').innerText; fileType = title.substring(title.indexOf('.') + 1).toLowerCase(); beforeFun = "let eb = u.query('.fc2e');if (eb) {eb.click();}"; select = "#pageContainer img"; } else if (host.includes(domain.gb688)) { if (u.query('#verifyCode')) return; fileType = 'pdf'; select = "#viewer .page"; btns.splice(1, 0, new Box('speed', '500')); btns.push(new Box('get-text', '获取文本', 'fullText()')) } else if (host.includes(domain.jjg)) { fileType = ".pdf"; select = "#docViewer_ViewContainer .fwr-page-invisible"; // select = "#docViewer_ViewContainer .fwr-page-image img"; } else if (host.includes(domain.shengtongedu)) { fileType = "ppt"; } else if (host.includes(domain.sacinfo)) { GM_deleteValue('listData'); // 清空 fileType = "pdf"; const md5 = href.split('/').pop(); // 秘钥 joinDownloadURL('https://hbba.sacinfo.org.cn/hbba_onlineRead_page/' + md5) btns.splice(1, 2); btns.push(new Box('PPT', '获取地址', 'downtxt()')) } else if (host.includes(domain.qzoffice)) { fileType = "pdf"; title = params.get('content') || 'AI-PPT'; btns.splice(1, 2); btns.splice(2, 1); } else if (host.includes(domain.nrsis)) { fileType = "pdf"; select = ".page canvas"; } else if (host.includes(domain.nea)) { fileType = "pdf"; select = ".page canvas"; } else if (host.includes(domain.nssi)) { title = document.title, fileType = "pdf"; select = "#viewer .page"; dom = u.query('#viewerContainer') btns.splice(1, 0, new Box('speed', '500')); } else if (host.includes(domain.feishu)) { fileType = "pdf"; dom = u.query('#viewerContainer') fileType = 'pdf'; select = "#viewer .page"; if (title.includes('PDF')) { btns.splice(1, 0, new Box('speed', '500')); btns.push(new Box('get-text', '获取文本', 'fullText()')) } else { btns.splice(1, 5); btns.push(new Box('get-build', '打包下载', 'buildDown()')) } } else if (host.includes(domain.jtysbz) || host.includes(domain.cebpubservice)) { fileType = "pdf"; select = "#viewer .page"; btns.splice(1, 0, new Box('speed', '500')); btns.push(new Box('get-text', '获取文本', 'fullText()')) } else if (host.includes(domain.jsjlw)) { fileType = "pdf"; select = "#ctn img"; dom = u.query('#ctn'); } else if (host.includes(domain.mwr)) { fileType = "pdf"; select = "#imgdiv img"; title = u.query('.left_titile').innerText; } else if (host.includes(domain.rbtest)) { fileType = "pdf"; select = ".page canvas"; } else if (host.includes(domain.weboffice)) { fileType = "pdf"; select = "#viewer .page"; btns.splice(1, 0, new Box('speed', '500')); } else if (host.includes(domain.gbservice)) { // 首页-跳转详情页面 if (href.includes('basicbzDetail')) { let id = location.href.split("id=").pop(); window.open( `https://gbservice.cn/pdfjs/web/viewer.html?file=https://api.gbservice.cn/api/standard/fileurl?id=${id}` ) return; } else if (!href.includes('pdfjs')) { return false; } fileType = "pdf"; dom = u.query('#viewerContainer'); select = "#viewer .page"; btns.splice(1, 0, new Box('speed', '500')); } else if (host.includes(domain.sgcc)) { if (!href.includes('portal/#/doc/doci-win/')) { return false; } fileType = "pdf"; dom = u.query('#viewerContainer'); select = "#viewer .page"; btns.splice(1, 0, new Box('speed', '500')); btns.push(new Box('get-text', '获取文本', 'fullText()')) } const query = u.query("#btn_ppt_front_pc"); // 原创 if (!query) { u.gui(btns); } else { query.click(); } console.log('文件名称:', title); console.log('文件类型:', fileType); } // b d 接口数据处理 const handleRenderData = () => { const { readerInfo, viewBiz } = pageData; fileType = viewBiz.docInfo.fileType; title = viewBiz.docInfo.aiQueryTitle; readerInfoBai = readerInfo; const htmlUrls = readerInfo.htmlUrls; if (htmlUrls) { if (fileType.includes('ppt')) { MF_addURL(htmlUrls); } else if (fileType.includes('pdf')) { let images = []; if (htmlUrls.png) { images = htmlUrls.png.map(item => { return item.pageLoadUrl }) } else { images = htmlUrls; } MF_addURL(images); } // 文本内容地址保存 if (htmlUrls.json) { let pageLoadUrl = htmlUrls.json.map(item => { return item.pageLoadUrl }) MF_addURL(pageLoadUrl, 'pageData'); } } // 纯文本类型文件 if (fileType === "txt") { // 纯文本类型 let urls = []; const { docId, freePage, rsign, showPage, md5sum } = readerInfoBai; for (var i = 1; i < showPage + 1; i++) { let x = md5sum.substring(1); let n = ["pn=" + i, "rn=1", "type=txt", "spr=0", "rsign=" + rsign, "callback=wenku_" + i ].join("&"); let url = BASE_URL + "/text/" + docId + "?" + x + "&" + n; urls.push(url) } MF_addURL(urls, 'pageData'); } setTimeout(() => { baiduCopy() }, 500) } // 清理缓存 const clearCache = () => { // 移除多余 iframe document.querySelectorAll('iframe').forEach(item => { item.remove() }) // 清空系统缓存数据 localStorage.removeItem('listData'); localStorage.removeItem('length'); localStorage.removeItem('current'); localStorage.removeItem('pageData'); localStorage.removeItem('down'); localStorage.removeItem('SP_text'); if (host.includes(domain.wenku)) { // 加载主页面 if (href.includes('tfview') || href.includes('view')) { GM_deleteValue('listData'); // 删除缓存 handleRenderData() } } } // load 事件 (() => { clearCache() // 在这里执行渲染完成后的操作 console.log('HTML 渲染完成!'); // 监听子页面加载完成,发送消息 if (!params.size || !params.get('custom')) { init() } })(); /** * @description 开始方法,自动预览 * @author Mr.Fang * @time 2024年2月2日 */ const autoPreview = async () => { if (host.includes(domain.book118) && fileType.includes('ppt')) { localStorage.setItem('start', '1'); await autoParsingPPT(); return false; } if (host.includes(domain.shengtongedu) && fileType.includes('ppt')) { localStorage.setItem('start', '1'); await autoShengTongParsingPPT(); return false; } if (host.includes(domain.mbalib) || host.includes(domain.nssi) || host.includes(domain.feishu) || host.includes(domain.cebpubservice) || host.includes(domain.jtysbz) || (host.includes(domain.gb688) && !u.query('#viewer').style.transform) || host.includes(domain.weboffice) || host.includes(domain.sgcc) || host.includes(domain.gbservice) ) { // 特殊情况,获取预览 dom if (host.includes(domain.sgcc)) { dom = u.query('#viewerContainer'); if (!dom) { alert("请先点击附件预览!"); return false; } } localStorage.setItem('start', '1'); localStorage.removeItem('SP_index') dom.scrollTop = 0; await scrollPreview() return false; } if (interval) return false; if (host.includes(domain.docin)) { // 起始页码 startPageNo = document.querySelector("#page_cur").value - 1 || 0; } else { dom.scrollTop = 0; } interval = setInterval(() => { if (host.includes(domain.book118)) { scrollPageArea() } else if (host.includes(domain.renrendoc)) { scrollPageArea() } else if (host.includes(domain.docin)) { scrollWinArea() } else if (host.includes(domain.wenku)) { scrollWinArea() } else if (host.includes(domain.doc88)) { scrollPageAreaDoc88() } else if (host.includes(domain.taodocs)) { scrollWinAreaTao() } else if (host.includes(domain.gb688)) { scrollPageAreaDocGB() } else if (host.includes(domain.jjg)) { scrollPageAreaJJG() } else if (host.includes(domain.nrsis) || host.includes(domain.nea) || host.includes(domain.mwr) || host.includes(domain.jsjlw) || host.includes(domain.rbtest) ) { scrollWinArea() } }, 500); } /** * @description 结束方法,停止预览 * @author Mr.Fang * @time 2024年2月2日 */ const stopPreview = async () => { console.log('---------->stopPreview'); if (interval) { clearInterval(interval); interval = null; } localStorage.removeItem('start') } /** * @description 结束方法,停止预览,前置方法 * @author Mr.Fang * @time 2024年7月22日 */ const stopBeforePreview = async () => { if (host.includes(domain.mwr)) { const page_index = u.query('.page_index').innerText; const page_total = u.query('.page_total').innerText; if (page_index === page_total) { stopPreview(); u.preview(-1); } else { // 向上滚动一次 dom.scrollTo({ top: dom.scrollTop - 100, left: 0, behavior: "smooth", }); } } else { stopPreview(); u.preview(-1); } } /** * @description 执行文件下载 * @author Mr.Fang * @time 2024年2月20日 * @param type 文件类型 */ const executeDownload = async (type) => { downType = type; const down = localStorage.getItem('down'); console.log('down', down) console.log('host', host) console.log('downType', downType) if (!down) { // 结束后续执行的方法 if (host.includes(domain.book118) || host.includes(domain.shengtongedu)) { if (fileType.includes('ppt')) { conditionDownload(); } else { await parseImage() } } else if (host.includes(domain.renrendoc)) { await parseImage() } else if (host.includes(domain.wenku)) { const display = u.query('#app-top-right-tool')?.style.display; if (!display || display === 'none') { await downimg() } } else if (host.includes(domain.docin)) { if (params.get('toImg')) { await parseImage() } else { await imageToBase64() conditionDownload(); } } else if (host.includes(domain.mbalib) || host.includes(domain.feishu) || host.includes(domain.nssi) || host.includes(domain.cebpubservice) || host.includes(domain.weboffice) || host.includes(domain.sgcc) || host.includes(domain.gbservice) || host.includes(domain.jtysbz) ) { conditionDownload(); } else if ( host.includes(domain.doc88) || host.includes(domain.taodocs) || host.includes(domain.nrsis) || host.includes(domain.nea) || host.includes(domain.rbtest) ) { await imageToBase64() conditionDownload(); } else if (host.includes(domain.deliwenku) || host.includes(domain.cxk) || host.includes(domain.jinchutou) || host.includes(domain.mayiwenku) || host.includes(domain.dugen) || host.includes(domain.iask) || host.includes(domain.cho#####) || host.includes(domain.weizhuan) || host.includes(domain.so) || host.includes(domain.sacinfo) ) { await downimg() } else if (host.includes(domain.gb688)) { if (u.query('#viewer').style.transform) { // bg await downloadGBImage(); } else { conditionDownload(); } } else if (host.includes(domain.jsjlw)) { await parseImage() } else if (host.includes(domain.jjg)) { await downloadElement() conditionDownload(); } else if (host.includes(domain.qzoffice)) { await handleQzoffice(); conditionDownload(); } else if (host.includes(domain.mwr)) { await downloadImage(); conditionDownload(); } } else { conditionDownload(); } } // 飞书打包下载 const buildDown = async () => { const styles = [...u.queryAll('style')].map(div => div.outerHTML).join('\n'); if (title.includes('excel')) { const container = u.query('.container').innerHTML; const content = `<!DOCTYPE html><html><head><meta charset="utf-8">${styles}</head><body style="overflow: auto;">${container}</body></html>` const htmlBlob = new Blob([content], { type: "text/html;charset=utf-8" }); zipWriter.add('index.html', new zip.BlobReader(htmlBlob)) zipWriter.add('index.txt', new zip.TextReader(u.query('.container').innerText)) } else if (title.includes('txt')) { const container = u.query('#scroll-container').innerHTML; const content = `<!DOCTYPE html><html><head><meta charset="utf-8">${styles}</head><body>${container}</body></html>` const htmlBlob = new Blob([content], { type: "text/html;charset=utf-8" }); zipWriter.add('index.html', new zip.BlobReader(htmlBlob)) zipWriter.add('index.txt', new zip.TextReader(u.query('#scroll-container').innerText)) } await u.sleep(500) downzip(); u.preText('下载完成') } /** * 根据指定条件下载文件 */ const conditionDownload = () => { if (downType === 1) { downpdf() localStorage.setItem('down', '1') } else if (downType === 2) { downzip() if (!host.includes(domain.qzoffice)) // 排除 qz localStorage.setItem('down', '1') } u.preText('下载完成') } // 滚动指定 Window const scrollWinArea = () => { before(); const scrollTop = dom.scrollTop; const height = dom.scrollHeight - dom.clientHeight; if (height <= scrollTop) { stopBeforePreview(); } else { let top = scrollTop + 500; dom.scrollTo({ top: top, left: 0, behavior: "smooth", }); u.preview(top, height); } } /** * @description 判断 dom 是否在可视范围内 * @author Mr.Fang * @time 2024-6-25 * @param {HTMLElement} el */ const isElementInViewport = (el) => { const rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) ); } /** * @description 图片添加到 zip 或 pdf * @author Mr.Fang * @time 2024-6-25 * @see http://raw.githack.com/MrRio/jsPDF/master/docs/module-addImage.html#~addImage * @param {HTMLImageElement | HTMLCanvasElement | Uint8Array | RGBAData} imageData * @param {Blob} blob * @param {Number} i 下标 * @param {Number} width 宽 * @param {Number} height 高 * @param {Boolean} natural 原始高度宽度 true 原始尺寸 false A4 */ const saveImageAndPDF = (imageData, blob, i, width, height, natural = false) => { let dir = 'p'; let target_w = pdf_w; let target_h = pdf_h; if (width > height) { dir = 'l'; target_h = pdf_w; target_w = pdf_h; } if (natural) { target_h = height * pdf_ratio; target_w = width * pdf_ratio; } else { target_h = target_h; target_w = target_w; } zipWriter.add(`${i}.png`, new zip.BlobReader(blob)); doc.addPage([target_w, target_h], dir); doc.addImage(imageData, 'JPEG', 0, 0, target_w, target_h, i, 'FAST') if (doc.internal.pages[1].length === 2) { doc.deletePage(1); // 删除空白页 } } /** * @description 保存数据 * @author Mr.Fang * @time 2024-6-25 * @param {Number} i 下标 * @param {HTMLElement} imageData 图片对象 * @param {HTMLElement} textLayer 文本对象 */ const previewSave = async (i, imageData, textLayer) => { const { blob, width, height } = await MF_CanvasToBase64(imageData); saveImageAndPDF(imageData, blob, i, width, height, false) //获取文本内容 let texts = JSON.parse(localStorage.getItem('SP_text')) || []; texts.push(fileType.includes('doc') ? textLayer.innerText : textLayer.textContent); localStorage.setItem('SP_text', JSON.stringify(texts)) // 更新下标 localStorage.setItem('SP_index', i + 1); } /** * @description 预览&下载 * @author Mr.Fang * @time 2024-6-25 */ const scrollPreview = async () => { if (!localStorage.getItem("start")) { u.preview(-1, null, "已终止"); return; } before(); const i = Number(localStorage.getItem('SP_index')) || 0; const childrens = u.queryAll(select); const current = childrens[i]; const length = childrens.length; // 如果当前对象在可视范围内,进行保存添加 let dataLoaded; let imageData = current.querySelector('canvas'); if (!imageData) { imageData = current.querySelector('.canvasWrapper canvas'); dataLoaded = current.getAttribute('data-loaded') } const textLayer = current.querySelector('.textLayer'); if ((dataLoaded || isElementInViewport(current)) && imageData && textLayer) { await previewSave(i, imageData, textLayer) if (i !== length - 1) childrens[i + 1].scrollIntoView({ behavior: "smooth" }); } else { current.scrollIntoView({ behavior: "smooth" }); } u.preview(i, length); if (i !== length - 1) { let speed = 500, MF_speed = Number(u.query('#MF_speed').innerText); if (MF_speed > 0) { speed = MF_speed } else { u.query('#MF_speed').innerText = 500 } setTimeout(() => { console.log(speed, 'ms 后执行'); scrollPreview() }, speed) } else { console.log('执行结束'); u.preview(-1); localStorage.removeItem('SP_index') localStorage.removeItem('start') } } // 滚动指定 Window const scrollWinAreaTao = () => { const scrollTop = dom.scrollTop; const height = dom.scrollHeight - dom.clientHeight; const fc2e = u.query('.fc2e'); let end = 0; const images = u.queryAll(select); const length = images.length; for (let i = 0; i < length; i++) { let item = images[i]; const { top } = item.getBoundingClientRect(); if (item.width === 300 || item.height == 150) { end = 1; dom.scrollTo({ top: dom.scrollTop + top, left: 0, behavior: "smooth", }); u.preview(dom.scrollTop + top, height); break; } } if (end === 0) { if (!fc2e) { stopPreview(); u.preview(-1); } else { before() } } } // 滚动指定区域 const scrollPageArea = () => { before(); const clientHeight = dom.clientHeight; let end = 0; const images = u.queryAll(select); const length = images.length; for (let i = 0; i < length; i++) { let item = images[i]; const { top } = item.getBoundingClientRect(); if (item instanceof HTMLImageElement) { if (!item.src && !item.getAttribute('data-src')) { end = 1; dom.scrollTo({ top: dom.scrollTop + top, left: 0, behavior: "smooth", }); u.preview(i + 1, length); break; } } else if (item instanceof HTMLDivElement) { end = 1; dom.scrollTo({ top: dom.scrollTop + top, left: 0, behavior: "smooth", }); u.preview(i + 1, length); break; } } if (end === 0) { u.preview(-1); stopPreview(); } } // 道客滚动函数 const scrollPageAreaDoc88 = () => { before(); const clientHeight = dom.clientHeight; let end = 0; const images = u.queryAll(select); const length = images.length; const startNum = document.querySelector("#pageNumInput").value - 1 || 0; for (let i = startNum; i < length; i++) { let item = images[i]; const { top } = item.getBoundingClientRect(); let previousElementSibling = item.previousElementSibling.previousElementSibling; let fs = u.attr(item, 'fs'); let t = previousElementSibling.innerText; if (t.length !== 0) { end = 1; item.scrollIntoView({ behavior: "smooth" }); u.preview(i + 1, length); break; } } if (end === 0) { u.preview(-1); stopPreview(); } } const scrollPageAreaDocGB = () => { // 100% 预览 if (u.query('#scaleSelect').selectedIndex < 9) { u.query('#zoomIn').click(); return true; } const clientHeight = dom.clientHeight; let end = 0; const els = u.queryAll(select); const length = els.length; for (let i = 0; i < length; i++) { let item = els[i]; if (u.attr(item, 'bg')) { end = 1; item.scrollIntoView({ behavior: "smooth" }); u.preview(i + 1, length); break; } } if (end === 0) { u.preview(-1); stopPreview(); } } const scrollPageAreaJJG = () => { let end = 0; // 放大 if (u.query('.fwr-rb-zoom-box input').value === '100%') { u.query('.fwr-rb-bottom-zoomin').click(); return; } const pages = u.query(".fwr-rb-bottom-tabs input").value.split('/'); const els = u.queryAll(select); const length = els.length; for (let i = Number(pages[0].trim()) - 1; i < length; i++) { const item = els[i]; const page = item.querySelector('.fwr-page-tile') if (!page) { end = 1; u.query('.fwr-rb-bottom-page-next').click(); u.preview(i + 1, length); break; } } if (end === 0) { u.preview(-1); stopPreview(); } } /** * canvas 转 blob 对象 * 导出全部按 A4 格式导出,方便兼容大部分文档,支持横竖格式 */ const imageToBase64 = async () => { const images = u.queryAll(select); const length = images.length; for (let i = 0; i < length; i++) { const item = images[i]; if (host.includes(domain.doc88)) { let previousElementSibling = item.previousElementSibling.previousElementSibling; let t = previousElementSibling.innerText; if (t.length !== 0) { continue; } } let { blob, width, height } = await MF_CanvasToBase64(item); saveImageAndPDF(item, blob, i, width, height, host.includes(domain.doc88) || host.includes( domain.rbtest)) await u.preview(i + 1, length); } console.log('处理完成', length); } /** * @description 原创力 PPT 解析 * @author Mr.Fang * @time 2024年2月21日 */ const autoParsingPPT = async () => { if (!localStorage.getItem("start")) { u.preview(-1, null, "已终止"); return; } const page = Number(u.query('#PageIndex').innerText); const total = Number(u.query('#PageCount').innerText); const childNodes = u.query("#view").childNodes; const count = childNodes.length; const max_index = page - 1; const current = u.query("#view" + max_index); // 动作数量 const a_len = u.queryAll(`#view${max_index} #animt${max_index}>div`).length; if (a_len !== 0) { await u.sleep(1000); } const bgs = MF_RecursiveParsingImages(current); await new Promise((resolve) => { html2canvas(current, { useCORS: true, logging: false, }).then(function(canvas) { let fileName = max_index + "_" + a_len + ".png"; // 将canvas转换为图片并下载. canvas.toBlob(blob => { zipWriter.add(fileName, new zip.BlobReader(blob)); }, "image/png", 1); // 添加PDF // 794px*1123px ; doc.addPage([canvas.width * pdf_ratio, canvas.height * pdf_ratio], 'l'); doc.addImage(canvas, 'JPEG', 0, 0, canvas.width * pdf_ratio, canvas .height * pdf_ratio, max_index + "_" + a_len, 'FAST') if (max_index === 1) { doc.deletePage(1); } resolve(); }); }) if (a_len === 0) { try { const detail = bgs.map((item, i) => { return zipWriter.add(max_index + "/" + i + ".png", new zip.HttpReader( item)); }); await Promise.all(detail); zipWriter.add(max_index + "/" + "文本描述.txt", new zip.TextReader(current.innerText)); } catch (e) { console.error(e); } } u.preview(page, total); const pageNext = u.query('#pageNext'); const btmRight = u.query('.btmRight'); if (page !== total) { btmRight.click(); await autoParsingPPT(); } } /** * 键盘事件 ←左 右→ */ const triggerKeyEvent = (element, key = 'right', type) => { var event = new KeyboardEvent(type, { bubbles: true, cancelable: true, key: key, keyCode: key === 'letf' ? 37 : 39, // 37是左箭头,39是右箭头 which: key === 'letf' ? 37 : 39 }); element.dispatchEvent(event); } /** * @description 盛通教育 PPT 解析 * @author Mr.Fang * @time 2024年5月10日 */ const autoShengTongParsingPPT = async () => { if (!localStorage.getItem("start")) { u.preview(-1, null, "已终止"); return; } const current = u.query('#playerView > div:nth-child(2)'); current.style.transform = 'none' const { total, page } = await new Promise((resolve) => { const childNodes = document.querySelector( "#playerView > div:nth-child(2) > div:nth-child(1) > div").childNodes; const total = childNodes.length - 1; let page = 1; childNodes.forEach((item, index) => { if (item.childNodes.length > 0) { page = index; } }) resolve({ total, page }) }) const max_index = page - 1; // 动作数量 let a_len = 0; if (max_index === Number(localStorage.getItem('currentPage'))) { a_len = Number(localStorage.getItem('currentPageIndex')) + 1; } if (a_len !== 0) { await u.sleep(1000); } const bgs = MF_RecursiveParsingImages(current); await new Promise((resolve) => { html2canvas(current, { useCORS: true, logging: false, }).then(function(canvas) { // 将canvas转换为图片并下载. let data = canvas.toDataURL(); let fileName = `${max_index}_${a_len}.png`; zipWriter.add(fileName, new zip.Data64URIReader(data)); // 添加PDF // 794px*1123px ; doc.addPage([canvas.width * pdf_ratio, canvas.height * pdf_ratio], 'l'); doc.addImage(data, 'JPEG', 0, 0, canvas.width * pdf_ratio, canvas .height * pdf_ratio, max_index + "_" + a_len, 'FAST') if (max_index === 1) { doc.deletePage(1); } localStorage.setItem('currentPage', max_index); localStorage.setItem('currentPageIndex', a_len); resolve(); }); }) if (a_len === 0) { try { const detail = bgs.map((item, i) => { return zipWriter.add(max_index + "/" + i + ".png", new zip.HttpReader( item)); }); await Promise.all(detail); zipWriter.add(max_index + "/" + "文本描述.txt", new zip.TextReader(current.innerText)); } catch (e) { console.error(e); } } u.preview(page, total); if (page !== total) { triggerKeyEvent(document.body, 'right', 'keydown'); triggerKeyEvent(document.body, 'right', 'keyup'); await autoShengTongParsingPPT(); } } /** * @description 轻竹办公 * @author Mr.Fang * @time 2024年5月17日 */ const handleQzoffice = async () => { localStorage.removeItem('down') // 递归遍历 DOM 节点 function traverseDOM(node, callback) { if (node.nodeType === Node.ELEMENT_NODE) { callback(node); // 调用回调函数处理当前节点 node = node.firstChild; // 获取第一个子节点 while (node) { traverseDOM(node, callback); // 递归遍历子节点 node = node.nextSibling; // 获取下一个兄弟节点 } } } // 查找具有指定属性的 <image> 元素 function findImagesWithAttribute(node) { var images = []; traverseDOM(node, function(element) { if (element.tagName === 'image') { images.push(element); } }); return images; } const template = document.getElementById("templateCanvas").cloneNode(true); template.style.display = 'block'; template.style.height = '0px'; template.style.position = 'relative'; template.style.display = 'block'; // 在整个文档中查找具有指定属性的 <image> 元素 const images = findImagesWithAttribute(template); const imageArray = []; // 打印找到的元素 const blobs = []; try { images.forEach(async (image, i) => { const animVal = image.href.animVal; let is = imageArray.filter(item => item.href === animVal); if (animVal && is.length === 0) { image.setAttribute('xlink:href', `./images/${i}.png`) imageArray.push({ name: `./images/${i}.png`, href: animVal }) const { blob, width, height } = await MF_ImageToBase64(animVal); zipWriter.add(`images/${i}.png`, new zip.BlobReader(blob)); } else { image.setAttribute('xlink:href', is[0].name) } }); } catch (e) { console.log(e); } const avgArray = document.querySelectorAll(".child-element svg"); let content = []; const outerHTML = template.outerHTML; content.push(outerHTML); for (let i = 0; i < avgArray.length; i++) { const avgArrayElement = avgArray[i]; const cloneNode = avgArrayElement.cloneNode(true); cloneNode.style.position = "static"; cloneNode.style.width = "100%"; cloneNode.style.height = "100%"; cloneNode.style.transform = "none"; const html = cloneNode.outerHTML; content.push( "<div classname=\"page-view\" style=\"width: 1200px; height: 820px;\">" + html + "</div>"); } // 添加 html const htmlBlob = new Blob(['<!DOCTYPE html>' + content.join('\n\n')], { type: "text/html;charset=utf-8" }); zipWriter.add('index.html', new zip.BlobReader(htmlBlob)) zipWriter.add('index.txt', new zip.TextReader(document.querySelector('.texts').innerText)) } /** * @description 解析图片 [src] * @author Mr.Fang * @time 2024年2月2日 */ const parseImage = async () => { const images = u.queryAll(select); if (!images.length) { u.log('------>parseImage 暂无数据'); return; } const listData = []; images.forEach((item) => { let src = u.attr(item, 'data-src') || item.src; if (src.includes('http:') && location.protocol === 'https') { src = src.replace("http:", "https:") } else if (src.startsWith("//")) { src = "https:" + src; } if (src) { const page = u.attr(item, 'data-page') || u.attr(item.parentElement, 'data-id'); if (host.includes(domain.docin)) { const curr = Number(item.parentElement.id.split('_').pop()); if (curr >= startPageNo + 1) { listData.push({ page, src }) } } else { listData.push({ page, src }) } } }) const store = JSON.stringify(listData); u.logt(listData) u.log('size:' + images.length); GM_setValue('listData', store); localStorage.setItem('listData', store) u.log('--------->downimg'); localStorage.removeItem('current') downimg() } /** * @description 下载图片 * @author Mr.Fang * @time 2024年2月2日 */ const downimg = async () => { const images = JSON.parse(GM_getValue('listData')); const length = images.length; localStorage.setItem('length', length); let current = Number(localStorage.getItem("current")) || 0; u.log('downimg----------->current:' + current) for (let index = current; index < length; index++) { const image = images[index]; const src = image.src; if (src.includes(host)) { // 当前域 const { uint8, blob, width, height } = await MF_ImageToBase64(src); if (fileType.includes('ppt') || width > height) { doc.addPage([width * pdf_ratio, height * pdf_ratio], 'l'); doc.addImage(uint8, 'JPEG', 0, 0, width * pdf_ratio, height * pdf_ratio, index, 'FAST') } else { doc.addPage(); doc.addImage(uint8, 'JPEG', 0, 0, pdf_w, pdf_h, index, 'FAST') } if (index === 1) { doc.deletePage(1); } zipWriter.add(index + ".png", new zip.BlobReader(blob)); current = index; await u.preview(current, length); } else { const url = new URL(src); const attrId = url.host.replaceAll(".", "") const query = document.getElementById('#' + attrId); if (query) { // 框架是否存在 parentMessage(src, "#" + attrId); } else { const el = u.createEl("#" + attrId, 'iframe'); el.src = url.origin + '?custom=true'; el.style.visibility = "hidden"; document.body.append(el); } localStorage.setItem('current', index + ""); u.preview(current, length); break; } } // 非当前域下载文件下标会多加一个数值 if (localStorage.getItem("current")) { current -= 1; } console.log('current', current); if (current === length - 1) { conditionDownload(); } } /** * 图片下载 */ const downloadImage = async () => { const images = [...u.queryAll(select)]; const len = images.length; for (let i = 0; i < len; i++) { const image = images[i] const canvas = await MF_ImageToCanvas(image); const { blob, width, height } = await MF_CanvasToBase64(canvas); saveImageAndPDF(canvas, blob, i, width, height, false); u.preview(i, len); } } const downloadElement = async () => { const nodes = u.queryAll('#docViewer_ViewContainer .fwr-page-tile'); const len = nodes.length; for (let i = 0; i < len; i++) { const node = nodes[i] const { blob, canvas } = await MF_ImageStitchingToCanvas(node); saveImageAndPDF(canvas, blob, i, canvas.width, canvas.height, true); u.preview(i, len); } } const MF_ImageToCanvas = (image) => { return new Promise((resolve, reject) => { const canvas = u.createEl('', 'canvas'); const { naturalWidth: width, naturalHeight: height } = image; canvas.width = width; canvas.height = height; let ctx = canvas.getContext('2d'); ctx.fillStyle = '#FFFFFF'; ctx.fillRect(0, 0, width, height); ctx.drawImage(image, 0, 0, width, height); resolve(canvas); }) } /** * bg pdf 下载 */ const downloadGBImage = async () => { const els = u.queryAll(select); const length = els.length; for (let i = 0; i < length; i++) { let item = els[i]; const { blob, canvas } = await MF_ImagePositionToBase64(item); if (!blob) { continue; } saveImageAndPDF(canvas, blob, i, canvas.width, canvas.height, true) await u.preview(i + 1, length); } // 非当前域下载文件下标会多加一个数值 conditionDownload(); } /** * @param {String} url 请求地址 */ const requestGet = (url) => { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); // xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 206 || xhr.status === 200) { try { let responseText = xhr.responseText; let r###lt = responseText.substring(responseText.indexOf('\(') + 1, responseText.length - 1); u.log(r###lt) resolve(JSON.parse(r###lt)); } catch (e) { reject(e); } } else { reject(new Error(`HTTP status code ${xhr.status}`)); } } }; xhr.onerror = function() { reject(new Error("Network error")); }; xhr.send(); }); } /** * 复制到剪切板 * @param text */ const copyToClipboard = (text) => { var input = document.createElement("textarea"); input.value = text; document.body.appendChild(input); input.select(); document.execCommand("copy"); document.body.removeChild(input); } /** * @description 通过接口获取文本内容 * @author Mr.Fang * @time 2024年2月20日 */ const fullText = async () => { let text = ''; if (host.includes(domain.wenku)) { const pageData = JSON.parse(localStorage.getItem('pageData')); if (pageData) { for (var i = 0; i < pageData.length; i++) { let url = pageData[i].src; let r###ltData = await requestGet(url); if (r###ltData instanceof Array) { text += r###ltData[0].parags[0].c; } else { r###ltData.body.forEach(item => { if (typeof item.c === "string") { text += item.c; } }) } } } else { text = u.query('.ql-editor').innerText; } } else if (host.includes(domain.mbalib) || host.includes(domain.feishu) || host.includes(domain.cebpubservice) || host.includes(domain.sgcc) || host.includes(domain.jtysbz)) { const texts = JSON.parse(localStorage.getItem("SP_text")) || [] for (let i = 0; i < texts.length; i++) { let t = texts[i]; text += `\n\n====第${i+1}页====\n\n` + t; } localStorage.removeItem('SP_text') } else if (host.includes(domain.doc88)) { // const texts = Core.api._VM; const texts = Core.api._bf; if (!texts) { alert('没有文本内容') return } for (let i = 0; i < texts.length; i++) { text += `\n\n====第${i+1}页====\n\n` + texts[i]; } } else if (host.includes(domain.taodocs)) { const texts = u.queryAll('#canvas .textLayer'); for (let i = 0; i < texts.length; i++) { let t = texts[i]; text += `\n\n====第${i+1}页====\n\n`; text += t.innerText; } } MF_ExportTxt(text, `${title}.txt`); } /** * @description 下载压缩包,包含图片 * @author Mr.Fang * @time 2024年2月2日 */ const downzip = () => { // 修改无法触发浏览器下载问题 see https://github.com/systemmin/kill-doc/issues/8 zipWriter.close().then(blob => { var link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `${title}.zip`; // 触发下载 document.body.appendChild(link); link.click(); document.body.removeChild(link); }).catch(error => { console.error(error); }); } /** * @description 下载 PDF * @author Mr.Fang * @time 2024年2月2日 */ const downpdf = () => { // 下载 PDF 文件 doc.save(`${title}.pdf`, { returnPromise: true }); } /** * @description 下载 txt 文本 * @author Mr.Fang * @time 2024年2月2日 */ const downtxt = () => { const images = JSON.parse(GM_getValue('listData')); const text = images.map(item => { return item.src }).join("\n"); MF_ExportTxt(text, `${title}.txt`); } /** * @description 递归加载子节点,获取子节点背景,img 属性值 * @author Mr.Fang * @time 2024年1月20日18:05:49 * @param children * @returns {*[]} */ const MF_RecursiveParsingImages = (children) => { const list = []; if (children.childNodes.length) { children.childNodes.forEach(item => { if (item || item instanceof HTMLImageElement) { if (item instanceof HTMLImageElement) { // 图片 let src = item.src; list.push(src); } else if (item.style) { let bgi = item.style.backgroundImage; if (bgi && bgi !== 'initial' && bgi.includes('url')) { let src = bgi.substring(bgi.indexOf("\"") + 1, bgi.lastIndexOf( "\"")); src = src.indexOf("/") === 0 ? src : "/" + src; list.push(origin + src); } } if (item.childNodes.length) { const images = MF_RecursiveParsingImages(item); list.push(...images); } } }) } return list; } /** * @description 获取文件后缀名 * @author Mr.Fang * @time 2024年6月17日16:31:05 * @param {name} data 文件名 * @returns {String} suffix 后缀 ,默认 pdf */ const getFileNam###ffix = (name) => { const last = name.lastIndexOf("."); return last > 0 ? name.substring(last + 1).toLocaleLowerCase() : 'pdf'; }; /** * @description 导出 txt 文件 * @author Mr.Fang * @time 2024年1月20日18:05:49 * @param {Object} data 数据 * @param {Object} filename 文件名 */ const MF_ExportTxt = (data, filename) => { const csvContent = "data:text/txt;charset=utf-8," + data; const encodedUri = encodeURI(csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", filename); // 点击链接以下载文件 document.body.appendChild(link); link.click(); document.body.removeChild(link); } /** * @description 加载图片 * @author Mr.Fang * @time 2024年1月20日18:05:49 * @param src 图片地址 * @returns {Promise<unknown>} */ const MF_ImageToBase64 = (src) => { return new Promise((resolve, reject) => { // 1、创建 Image 对象 const image = new Image(); // 2、onload 加载成功触发 image.onload = function() { try { let canvas = u.createEl('', 'canvas'); const { naturalWidth: width, naturalHeight: height } = image; canvas.width = width; canvas.height = height; let ctx = canvas.getContext('2d'); ctx.fillStyle = '#FFFFFF'; ctx.fillRect(0, 0, width, height); ctx.drawImage(image, 0, 0, width, height); canvas.toBlob(async blob => { // canvas 转 blob 对象 // blob 转 uint8 、PDF 需要 uint8 对象 const uint8 = await MF_BlobToUint8Array(blob) resolve({ uint8, blob, width, height }); }, "image/png", 1, ); } catch (e) { reject(e); } } image.onerror = reject; image.src = src; }) } /** * @description 基于背景图片定位,转画布 * @author Mr.Fang * @time 2024年3月13日 * @param src 图片地址 * @returns {Promise<unknown>} */ const MF_ImagePositionToBase64 = (el) => { const base_gb = "http://c.gb688.cn/bzgk/gb/"; const style = el.style; const cw = Number(style.width.replace('px', '')); const ch = Number(style.height.replace('px', '')); // 所有子节点 const childrens = el.children; // 背景图片地址处理 if (childrens.length < 2) { return new Promise((resolve, reject) => { resolve({ blob: null }) }) } const imageUrl = childrens[0].style.backgroundImage; const fullUrl = imageUrl.substring(5, imageUrl.length - 2); if (!imageUrl) { return new Promise((resolve, reject) => { resolve({ blob: null }) }) } return new Promise((resolve, reject) => { // 1、创建 Image 对象 const image = new Image(); // 2、onload 加载成功触发 image.onload = function() { try { let canvas = u.createEl('', 'canvas'); canvas.width = cw; canvas.height = ch; // 获取上下文对象 const ctx = canvas.getContext('2d'); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < childrens.length; i++) { const child = childrens[i]; const pos = child.style.backgroundPosition.split(' '); const coord = child.className.split('-'); const dx = Number(coord[1]); const dy = Number(coord[2]); const sx = Math.abs(pos[0].replace('px', '')); const sy = Math.abs(pos[1].replace('px', '')); const rect = child.getBoundingClientRect(); const { width: sw, height: sh } = rect; ctx.drawImage(image, sx, sy, sw, sh, dx * sw, dy * sh, sw, sh); if (i === childrens.length - 1) { // 转 base64 输出 canvas.toBlob( (blob) => { resolve({ blob, canvas }); }, "image/png", 1, ); } } } catch (e) { reject(e); } } image.onerror = reject; image.src = fullUrl; }) } const MF_ImageStitchingToCanvas = (node) => { return new Promise((resolve, reject) => { try { // 获取最后一个分辨率 / tiles-layer-125 分辨率/ div/ 行 div [img] const children = node.lastElementChild.children; const firstNode = children[0]; // 计算画布宽度 const cwidth = [...firstNode.querySelectorAll('img')].reduce((start, item) => start + item.width, 0); const cheight = children.length * firstNode.querySelector('img').height; const canvas = u.createEl('', 'canvas'); canvas.width = cwidth; canvas.height = cheight; // 获取上下文对象 const ctx = canvas.getContext('2d'); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); // 拼接 for (let i = 0; i < children.length; i++) { const chils = [...children[i].querySelectorAll('img')]; let iw = 0; for (let j = 0; j < chils.length; j++) { const { width, height } = chils[j]; ctx.drawImage(chils[j], iw, i * height, width, height); iw += width } } canvas.toBlob( (blob) => { resolve({ blob, canvas, }); }, "image/png", 1, ); } catch (e) { //TODO handle the exception reject(e) } }) } /** * @description 图片拼接转 blob * @author Mr.Fang * @time 2024年6月5日 * @param el 节点对象 * @returns {Promise<blob>} */ const MF_ImageJoinToBlob = (el) => { return new Promise((resolve, reject) => { const children = el.children; const { naturalWidth, naturalHeight } = children[0]; // 1、创建画布 let canvas = u.createEl('', 'canvas'); canvas.width = naturalWidth * 6; canvas.height = naturalHeight; const ctx = canvas.getContext('2d'); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); // 2、获取所有图片节点 const listData = [] for (var i = 0; i < children.length; i++) { const img = children[i]; const left = img.style.left.replace('px', '') listData.push({ index: i, left: Number(left) }) } listData.sort((a, b) => a.left - b.left); // 3、遍历绘制画布 for (var i = 0; i < listData.length; i++) { const img = children[listData[i].index]; ctx.drawImage(img, i * naturalWidth, 0, naturalWidth, naturalHeight); } // 4、导出 canvas.toBlob( (blob) => { resolve({ blob, canvas, }); }, "image/png", 1, ); }) } /** * @description 将 blob 对象转 uint8Array * @author Mr.Fang * @time 2024年5月27日 * @param {Object} blob 图片对象 * @returns {Promise<Uint8Array>} */ const MF_BlobToUint8Array = (blob) => { return new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.onload = function() { resolve(new Uint8Array(this.r###lt)); }; fileReader.onerror = function(error) { reject(error); }; fileReader.readAsArrayBuffer(blob); }); } /** * @description 画布输出 blob 对象 * @author Mr.Fang * @time 2024年1月20日18:05:49 * @param src 图片地址 * @returns {Promise<Object>} */ const MF_CanvasToBase64 = (canvas) => { return new Promise((resolve, reject) => { const { width, height } = canvas; canvas.toBlob( (blob) => { resolve({ blob, width, height }); }, "image/png", 1, ); }) } })();