11

我正在使用 PDF.js 库将 pdf 呈现到画布中。该pdf在那里有超链接,PDF.js库正在将pdf绘制到画布中,但超链接不起作用。

如果超链接有可能在画布中起作用,有什么想法吗?

谢谢

4

3 回答 3

16

是一个小提琴,向您展示如何在 PDF 文件中启用注释(包括超链接)。小提琴中使用的原始 PDF 文件在这里

我使用查看器代码(web/page_view.jsweb/viewer.css)作为参考来编写这个小提琴。

HTML:

<!doctype html>
<html lang="en">
  <head>
    <link href="style.css" rel="stylesheet" media="screen" />
    <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script src="http://seikichi.github.io/tmp/PDFJS.0.8.715/pdf.min.js" type="text/javascript"></script>
    <script src="http://seikichi.github.io/tmp/PDFJS.0.8.715/ui_utils.js"></script>
    <script src="./main.js" type="text/javascript"></script>
  </head>
  <body>
    <div id="pdfContainer" class="pdf-content">
      <canvas id="the-canvas"></canvas>
      <div class="annotationLayer"></div>
    </div>
  </body>
</html>

CSS:

body {
    font-family: arial, verdana, sans-serif;
}
.pdf-content {
    border: 1px solid #000000;
}
.annotationLayer > a {
    display: block;
    position: absolute;
}
.annotationLayer > a:hover {
    opacity: 0.2;
    background: #ff0;
    box-shadow: 0px 2px 10px #ff0;
}
.annotText > div {
    z-index: 200;
    position: absolute;
    padding: 0.6em;
    max-width: 20em;
    background-color: #FFFF99;
    box-shadow: 0px 2px 10px #333;
    border-radius: 7px;
}
.annotText > img {
    position: absolute;
    opacity: 0.6;
}
.annotText > img:hover {
    opacity: 1;
}
.annotText > div > h1 {
    font-size: 1.2em;
    border-bottom: 1px solid #000000;
    margin: 0px;
}

JavaScript

PDFJS.workerSrc = 'http://seikichi.github.io/tmp/PDFJS.0.8.715/pdf.min.worker.js';

$(function () {
  var pdfData = loadPDFData();

  PDFJS.getDocument(pdfData).then(function (pdf) {
    return pdf.getPage(1);
  }).then(function (page) {
    var scale = 1;
    var viewport = page.getViewport(scale);
    var $canvas = $('#the-canvas');
    var canvas = $canvas.get(0);
    var context = canvas.getContext("2d");
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    var $pdfContainer = $("#pdfContainer");
    $pdfContainer.css("height", canvas.height + "px")
      .css("width", canvas.width + "px");

    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    page.render(renderContext);
    setupAnnotations(page, viewport, canvas, $('.annotationLayer'));
  });

  function setupAnnotations(page, viewport, canvas, $annotationLayerDiv) {
    var canvasOffset = $(canvas).offset();
    var promise = page.getAnnotations().then(function (annotationsData) {
      viewport = viewport.clone({
        dontFlip: true
      });

      for (var i = 0; i < annotationsData.length; i++) {
        var data = annotationsData[i];
        var annotation = PDFJS.Annotation.fromData(data);
        if (!annotation || !annotation.hasHtml()) {
          continue;
        }

        var element = annotation.getHtmlElement(page.commonObjs);
        data = annotation.getData();
        var rect = data.rect;
        var view = page.view;
        rect = PDFJS.Util.normalizeRect([
          rect[0],
          view[3] - rect[1] + view[1],
          rect[2],
          view[3] - rect[3] + view[1]]);
        element.style.left = (canvasOffset.left + rect[0]) + 'px';
        element.style.top = (canvasOffset.top + rect[1]) + 'px';
        element.style.position = 'absolute';

        var transform = viewport.transform;
        var transformStr = 'matrix(' + transform.join(',') + ')';
        CustomStyle.setProp('transform', element, transformStr);
        var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
        CustomStyle.setProp('transformOrigin', element, transformOriginStr);

        if (data.subtype === 'Link' && !data.url) {
          // In this example,  I do not handle the `Link` annotations without url.
          // If you want to handle those annotations, see `web/page_view.js`.
          continue;
        }
        $annotationLayerDiv.append(element);
      }
    });
    return promise;
  }
});

function loadPDFData() {
  /*jshint multistr: true */
  var base64pdfData = '...'; //should contain base64 representing the PDF

  function base64ToUint8Array(base64) {
    var raw = atob(base64);
    var uint8Array = new Uint8Array(new ArrayBuffer(raw.length));
    for (var i = 0, len = raw.length; i < len; ++i) {
      uint8Array[i] = raw.charCodeAt(i);
    }
    return uint8Array;
  }
  return base64ToUint8Array(base64pdfData);
}
于 2013-11-22T09:24:31.910 回答
1

在 PDF.JS 中启用文本选择


第 1 步:添加一个元素来保存文本层

<div id="text-layer"></div>

此 div 将添加到呈现 PDF 的元素之外,因此 HTML 将如下所示:

<canvas id="pdf-canvas"></canvas>
<div id="text-layer"></div>

第 2 步:为文本层添加 CSS

将以下内容添加到您的 CSS 文件中:

#text-layer { 
   position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    overflow: hidden;
    opacity: 0.2;
    line-height: 1.0;
}

#text-layer > div {
    color: transparent;
    position: absolute;
    white-space: pre;
    cursor: text;
    transform-origin: 0% 0%;
}

第 3 步:获取 PDF 文本

在画布中呈现 PDF 后,您需要获取 PDF 的文本内容,并将该文本放置在文本层中。

// page is the page context of the PDF page
// viewport is the viewport required in renderContext
// For more see https://usefulangle.com/post/20/pdfjs-tutorial-1-preview-pdf-during-upload-wih-next-prev-buttons    

page.render(renderContext).then(function() {
    // Returns a promise, on resolving it will return text contents of the page
    return page.getTextContent();
}).then(function(textContent) {
     // PDF canvas
    var pdf_canvas = $("#pdf-canvas"); 

    // Canvas offset
    var canvas_offset = pdf_canvas.offset();

    // Canvas height
    var canvas_height = pdf_canvas.get(0).height;

    // Canvas width
    var canvas_width = pdf_canvas.get(0).width;

    // Assign CSS to the text-layer element
    $("#text-layer").css({ left: canvas_offset.left + 'px', top: canvas_offset.top + 'px', height: canvas_height + 'px', width: canvas_width + 'px' });

    // Pass the data to the method for rendering of text over the pdf canvas.
    PDFJS.renderTextLayer({
        textContent: textContent,
        container: $("#text-layer").get(0),
        viewport: viewport,
        textDivs: []
    });
});

来源:https ://usefulangle.com/post/90/javascript-pdfjs-enable-text-layer

于 2021-01-15T11:14:37.837 回答
0
 setupAnnotations = (page, viewport, canvas, annotationLayerDiv) => {
        let pdfjsLib = window['pdfjs-dist/build/pdf'];
        let pdfjsViewer = window['pdfjs-dist/web/pdf_viewer'];

        //BELOW--------- Create Link Service using pdf viewer
        let pdfLinkService = new pdfjsViewer.PDFLinkService();

        page.getAnnotations().then(function (annotationsData) {
            viewport = viewport.clone({
                dontFlip: true
            });

            let pdf_canvas = canvas;
          
            // Render the annotation layer
            annotationLayerDiv.style.left = pdf_canvas.offsetLeft + 'px';
            annotationLayerDiv.style.top = pdf_canvas.offsetTop + 'px';
            annotationLayerDiv.style.height = viewport.height + 'px';
            annotationLayerDiv.style.width = viewport.width + 'px';

            pdfjsLib.AnnotationLayer.render({
                viewport: viewport,
                div: annotationLayerDiv,
                annotations: annotationsData,
                page: page,
                linkService: pdfLinkService,
                enableScripting: true,
                renderInteractiveForms: true
            });
    }

IMP ---- 不要忘记添加这个 CSS

.annotation-layer{
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  opacity: 1;
}

.annotation-layer section{
  position: absolute;
  cursor: pointer;
}

.annotation-layer section a{
  display: block;
  width: 100%;
  height: 10px;
}

在上面的例子中,链接服务实例是使用 pdf 查看器中的类创建的,它作为参数传递给注释层渲染方法。请参阅PDF.js的源代码,请参阅 /web/pdf_viewer.js - 类 PDFLinkService 了解更多信息。

PDF.js 版本 - v2.9.359

于 2021-08-27T10:34:10.233 回答