Как встроить программу просмотра PDF. JS на страницу без iframe - PullRequest
1 голос
/ 09 июля 2020

Я удивлен, увидев относительно немного документации и руководств по PDF. JS, особенно после рефакторинга кода PDFJS -> pdfjsLib, учитывая, что эта библиотека довольно широко используется.

То, что я хочу сделать это относительно просто, я просто хочу встроить PDF прямо на веб-страницу, то есть без тегов <iframe>, <object> или <embed>. Я также хочу использовать текстовый слой, потому что хочу получить доступ к тексту в JavaScript и добавить всплывающие подсказки к некоторым предложениям.

Я подумал, что использование средства просмотра может быть решением, но я не хочу включать весь код в viewer.html, viewer.css и viewer.js на моей веб-странице, потому что я уверен, что он сломается. Если бы я мог просто отобразить PDF-файл и выбрать текст, этого было бы достаточно, мне не обязательно нужен сложный пользовательский интерфейс программы просмотра.

Вот мой код, но текстовый слой отображается неправильно:

document.addEventListener('DOMContentLoaded', () => {
  pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.4.456/pdf.worker.js';
});

function displayReport() {
  const file = document.getElementById('reportInput').files[0];
  const fileReader = new FileReader();
  fileReader.onload = async function() {
    const data = this.result;
    const pdf = await pdfjsLib.getDocument({data: data}).promise;
    const page = await pdf.getPage(1);
    const viewport = page.getViewport({scale: 0.5});

    const canvas = document.getElementById('reportCanvas');
    const context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    const renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    await page.render(renderContext).promise;
    const textContent = await page.getTextContent();

    const { top, left, width, height } = canvas.getBoundingClientRect();
    const textLayer = document.getElementById('reportTextLayer');
    textLayer.style.top = top;
    textLayer.style.left = left;
    textLayer.style.width = width;
    textLayer.style.height = height;

    await pdfjsLib.renderTextLayer({
      textContent: textContent,
      container: textLayer,
      viewport: viewport,
      textDivs: []
    });

    console.log("Page rendered!");
  };
  fileReader.readAsBinaryString(file);
}
#reportTextLayer {
  position: absolute;
  overflow: hidden;
  opacity: 0.2;
  line-height: 1.0;
}

#reportTextLayer > div {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.4.456/pdf.js"></script>

<p>Select a PDF file:</p>
<input id="reportInput" type="file" accept="application/pdf" onchange="displayReport()"/>

<div id="reportWrapper">
    <canvas id="reportCanvas"></canvas>
    <div id="reportTextLayer"></div>
</div>

Как я могу это исправить?

Спасибо за вашу помощь.

...