洛谷题目页面生成PDF,自动以PXXXX命名
// ==UserScript==
// @name 洛谷题目PDF下载(自动命名)
// @namespace http://tampermonkey.net/
// @version 0.3
// @description 洛谷题目页面生成PDF,自动以PXXXX命名
// @author 豆包编程助手
// @match https://www.luogu.com.cn/problem/*
// @icon https://www.luogu.com.cn/favicon.ico
// @grant GM_addStyle
// @require https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 创建下载按钮
const downloadBtn = document.createElement('button');
downloadBtn.innerText = '另存为 PDF';
downloadBtn.id = 'pdf-download-btn';
// 按钮样式
GM_addStyle(`
#pdf-download-btn {
position: fixed;
top: 70px;
right: 20px;
z-index: 9999;
padding: 10px 18px;
background-color: #2196F3;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
transition: all 0.3s ease;
}
#pdf-download-btn:hover {
background-color: #0b7dda;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
#pdf-download-btn:active {
transform: translateY(0);
}
#pdf-download-btn:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
`);
document.body.appendChild(downloadBtn);
// 从URL提取问题编号(PXXXX格式)
function getProblemId() {
// 匹配URL中的/problem/PXXXX部分
const match = window.location.href.match(/\/problem\/(P\d+)/);
return match ? match[1] : 'luogu-problem';
}
// 点击事件
downloadBtn.addEventListener('click', async () => {
downloadBtn.disabled = true;
downloadBtn.innerText = '正在生成...';
try {
// 获取问题编号作为文件名
const problemId = getProblemId();
const fileName = `${problemId}.pdf`;
// 克隆内容并清理不需要的元素
const mainContent = document.querySelector('.main-container') || document.body;
const contentClone = mainContent.cloneNode(true);
const elementsToRemove = contentClone.querySelectorAll(
'.lg-content-nav, .lg-right-bar, .ad, .banner, .comment, .discuss, .pagination, .copy-code, #pdf-download-btn'
);
elementsToRemove.forEach(el => el.remove());
// PDF配置(横向A4)
const opt = {
margin: 15,
filename: fileName,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'landscape' }
};
// 生成并下载PDF
await html2pdf().set(opt).from(contentClone).save();
} catch (error) {
console.error('PDF生成失败:', error);
alert('PDF生成失败,请重试');
} finally {
downloadBtn.disabled = false;
downloadBtn.innerText = '另存为 PDF';
}
});
})();