行业标准信息PDF下载
// ==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);
}
})();