从pdf文件中的锚链接目标获取页码

pes8fvy9  于 2021-08-20  发布在  Java
关注(0)|答案(0)|浏览(310)

我使用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:

  1. <!DOCTYPE html>
  2. <html lang="de">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Page numbers</title>
  6. <style>
  7. #list-toc-generated {
  8. list-style: none;
  9. }
  10. #list-toc-generated .toc-element {
  11. break-inside: avoid;
  12. }
  13. #list-toc-generated .toc-element a {
  14. text-decoration: none;
  15. color: #000000;
  16. }
  17. #content {
  18. break-before: page;
  19. }
  20. * {
  21. font-family: 'Roboto', sans-serif !important;
  22. }
  23. </style>
  24. </head>
  25. <body>
  26. <div id="toc">
  27. </div>
  28. <div id="content">
  29. <h1>First</h1>
  30. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  31. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  32. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  33. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  34. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  35. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  36. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  37. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  38. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  39. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  40. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  41. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  42. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  43. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  44. <h1>Second Title</h1>
  45. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  46. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  47. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  48. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  49. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  50. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  51. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  52. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  53. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  54. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  55. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  56. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  57. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  58. <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  59. <h1>Last Site</h1>
  60. </div>
  61. <script>
  62. function createToc(config){
  63. const content = config.content;
  64. const tocElement = config.tocElement;
  65. const titleElements = config.titleElements;
  66. let tocElementDiv = content.querySelector(tocElement);
  67. let tocUl = document.createElement("ul");
  68. tocUl.id = "list-toc-generated";
  69. tocElementDiv.appendChild(tocUl);
  70. let tocElementNbr = 0;
  71. for(var i= 0; i < titleElements.length; i++){
  72. let titleHierarchy = i + 1;
  73. let titleElement = content.querySelectorAll(titleElements[i]);
  74. titleElement.forEach(function(element) {
  75. element.classList.add("title-element");
  76. element.setAttribute("data-title-level", titleHierarchy);
  77. tocElementNbr++;
  78. idElement = element.id;
  79. if(idElement == ''){
  80. element.id = 'title-element-' + tocElementNbr;
  81. }
  82. let newIdElement = element.id;
  83. });
  84. }
  85. let tocElements = content.querySelectorAll(".title-element");
  86. for(var i= 0; i < tocElements.length; i++){
  87. let tocElement = tocElements[i];
  88. let tocNewLi = document.createElement("li");
  89. tocNewLi.classList.add("toc-element");
  90. tocNewLi.classList.add("toc-element-level-" + tocElement.dataset.titleLevel);
  91. let classTocElement = tocElement.classList;
  92. for(var n= 0; n < classTocElement.length; n++){
  93. if(classTocElement[n] != "title-element") {
  94. tocNewLi.classList.add(classTocElement[n]);
  95. }
  96. }
  97. tocNewLi.innerHTML = '<a href="#' + tocElement.id + '">' + tocElement.innerHTML + '</a>';
  98. tocUl.appendChild(tocNewLi);
  99. }
  100. }
  101. createToc({content: document.body, tocElement: '#toc', titleElements: ["h1"]});
  102. </script>
  103. </body>
  104. </html>

此文件为所有文件生成动态目录 <h1> 标签,这是非常好的工作。如果我用chrome生成pdf,我可以点击toc中的标题,pdf阅读器跳转到 <h1> 元素。
但是在这一点上,我不知道如何用python解析pdf并获得toc中链接的特定目标元素的页码。
我尝试了各种python库,例如pypdf2、pdfminer或pdfrw,但没有一个可以完成。也许问题在于我不完全理解pdf文件是如何构造的。
有人能帮我提取目标链接元素的页码吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题