// ==UserScript== // @name 行业标准信息PDF下载 // @namespace http://tampermonkey.net/ // @version 2025.3.5 // @description 自动下载行业标准信息图片并合并为PDF(带进度显示) // @author Shuaima // @match https://hbba.sacinfo.org.cn/attachment/onlineRead/* // @require https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js // @grant GM_xmlhttpRequest // @grant GM_download // @grant GM_notification // @connect hbba.sacinfo.org.cn // ==/UserScript== (function() { 'use strict'; const pathParts = window.location.pathname.split('/'); const name = pathParts[3] || 'default_hash'; let pageNum = 0; let imgUrls = []; const doc = new jspdf.jsPDF(); let downloadBtn = null; // 验证页面 if (!name || pathParts[2] !== 'onlineRead') { GM_notification({text: '请在标准阅读页面使用本脚本!', timeout: 5000}); return; } function createButton() { downloadBtn = document.createElement('button'); downloadBtn.id = 'pdfDownloadBtn'; downloadBtn.style = ` position: fixed; top: 20px; right: 20px; padding: 7px 15px; background: #219677; color: white; border: none; border-radius: 4px; cursor: pointer; z-index: 9999; box-shadow: 0 2px 5px rgba(0,0,0,0.3); transition: all 0.3s; `; downloadBtn.textContent = '下载PDF'; downloadBtn.onclick = startDownload; document.body.appendChild(downloadBtn); } function startDownload() { // 重置状态 pageNum = 0; imgUrls = []; updateButton('准备下载...', true); fetchNextPage(); } function updateButton(text, disabled = false) { if (!downloadBtn) return; downloadBtn.textContent = text; downloadBtn.style.background = disabled ? '#808080' : '#219677'; downloadBtn.disabled = disabled; } function fetchNextPage() { const url = `https://hbba.sacinfo.org.cn/hbba_onlineRead_page/${name}/${pageNum}.png?t=1`; GM_xmlhttpRequest({ method: 'GET', url: url, responseType: 'blob', headers: { 'Referer': 'https://hbba.sacinfo.org.cn/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36' }, onload: function(response) { if (response.status === 200) { const blob = response.response; imgUrls.push(URL.createObjectURL(blob)); pageNum++; updateButton(`下载中...(已下载 ${pageNum} 页)`, true); setTimeout(fetchNextPage, 1000); } else { endDownload(); } }, onerror: function() { endDownload(); } }); } function endDownload() { if (pageNum === 0) { updateButton('下载失败,点击重试'); GM_notification({text: '下载失败,请重试!', timeout: 3000}); return; } updateButton('生成PDF中...', true); generatePDF(); } function generatePDF() { if (imgUrls.length === 0) return; const img = new Image(); img.src = imgUrls[0]; img.onload = function() { const imgWidth = doc.internal.pageSize.getWidth(); const imgHeight = (img.height * imgWidth) / img.width; doc.addImage(imgUrls[0], 'JPEG', 0, 0, imgWidth, imgHeight); for (let i = 1; i < imgUrls.length; i++) { doc.addPage(); doc.addImage(imgUrls[i], 'JPEG', 0, 0, imgWidth, imgHeight); } doc.save(`${name}.pdf`); // 清理资源 imgUrls.forEach(url => URL.revokeObjectURL(url)); updateButton('下载完成 ✔️'); setTimeout(() => updateButton('下载PDF'), 5000); }; } // 初始化 if (name !== 'default_hash') { setTimeout(createButton, 1000); } })();