我使用pyppeteer(python puppet Package 器)从html生成pdf文件。这个效果很好。
但现在我想生成动态目录。关于这个主题,我读了很多小时,最后我意识到这不是一个简单的解决办法。因为没有内置的方法来获取特定页面的页码 <h1>
标记或其他目标元素。
完美的解决方案是 target-counter
功能来自分页媒体模块级别3,但浏览器不支持该功能。
我也尝试过像paged.js这样的polyfill解决方案,但这种解决方案还有其他问题和限制,与我的项目相冲突。
其他现有的从html生成PDF的解决方案,如wkhtmltopdf,都存在不支持现代css或javascript的问题。
经过所有的研究,我认为通过Pypetteer使用chrome生成PDF是满足我需求的最佳和健壮的解决方案。
但是在这一点上,我仍然有toc中页码的问题。我发现了这篇文章,它描述了使用chrome生成toc的一般思想。
我当前的示例html:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Page numbers</title>
<style>
#list-toc-generated {
list-style: none;
}
#list-toc-generated .toc-element {
break-inside: avoid;
}
#list-toc-generated .toc-element a {
text-decoration: none;
color: #000000;
}
#content {
break-before: page;
}
* {
font-family: 'Roboto', sans-serif !important;
}
</style>
</head>
<body>
<div id="toc">
</div>
<div id="content">
<h1>First</h1>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h1>Second Title</h1>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h1>Last Site</h1>
</div>
<script>
function createToc(config){
const content = config.content;
const tocElement = config.tocElement;
const titleElements = config.titleElements;
let tocElementDiv = content.querySelector(tocElement);
let tocUl = document.createElement("ul");
tocUl.id = "list-toc-generated";
tocElementDiv.appendChild(tocUl);
let tocElementNbr = 0;
for(var i= 0; i < titleElements.length; i++){
let titleHierarchy = i + 1;
let titleElement = content.querySelectorAll(titleElements[i]);
titleElement.forEach(function(element) {
element.classList.add("title-element");
element.setAttribute("data-title-level", titleHierarchy);
tocElementNbr++;
idElement = element.id;
if(idElement == ''){
element.id = 'title-element-' + tocElementNbr;
}
let newIdElement = element.id;
});
}
let tocElements = content.querySelectorAll(".title-element");
for(var i= 0; i < tocElements.length; i++){
let tocElement = tocElements[i];
let tocNewLi = document.createElement("li");
tocNewLi.classList.add("toc-element");
tocNewLi.classList.add("toc-element-level-" + tocElement.dataset.titleLevel);
let classTocElement = tocElement.classList;
for(var n= 0; n < classTocElement.length; n++){
if(classTocElement[n] != "title-element") {
tocNewLi.classList.add(classTocElement[n]);
}
}
tocNewLi.innerHTML = '<a href="#' + tocElement.id + '">' + tocElement.innerHTML + '</a>';
tocUl.appendChild(tocNewLi);
}
}
createToc({content: document.body, tocElement: '#toc', titleElements: ["h1"]});
</script>
</body>
</html>
此文件为所有文件生成动态目录 <h1>
标签,这是非常好的工作。如果我用chrome生成pdf,我可以点击toc中的标题,pdf阅读器跳转到 <h1>
元素。
但是在这一点上,我不知道如何用python解析pdf并获得toc中链接的特定目标元素的页码。
我尝试了各种python库,例如pypdf2、pdfminer或pdfrw,但没有一个可以完成。也许问题在于我不完全理解pdf文件是如何构造的。
有人能帮我提取目标链接元素的页码吗?
暂无答案!
目前还没有任何答案,快来回答吧!