【问题标题】:Links, Hyperlinks into a canvas using PDF.js使用 PDF.js 将链接、超链接放入画布
【发布时间】:2013-11-26 01:26:31
【问题描述】:

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

如果超链接可以在画布中使用,有什么想法吗?

谢谢

【问题讨论】:

标签: javascript html gwt pdf.js


【解决方案1】:

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

我使用查看器代码 (web/page_view.js,web/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);
}

【讨论】:

  • 共享资源和小提琴不起作用..你能更新一下内容吗
【解决方案2】:

在 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

【讨论】:

  • 这个答案对这个问题没有帮助,他想要超链接,而不是文本层。您应该改用 page.getAnnotations。
【解决方案3】:
 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

【讨论】:

  • 您能否扩展这个较新的示例以包含您正在引用的脚本,以使查看器和 pdflinkservice 引用正常工作?
  • 我无法使用 PDFLinkService,viewer.js 中没有此类,我已将 pdf.js github 中的 pdf_link_service 代码复制到我的项目中,但找不到并导入“pdfjs” -lib”,我不能让它工作,你能解释一下怎么做吗? :( 我无法实现注释,我真的需要它,如果你现在能解释一下如何做,我将非常感激,因为我认为 pdf.js 中的某些事情已经改变
  • @SMH 我没有用较新版本的 pdf.js 尝试过,是的,看起来有些东西已经改变了,尽管你可以在 web 文件夹中找到 pdf_link_service.js 文件,你可以尝试使用它。
  • @PranjalKosht​​i 是的,我是在 pdf.js github 中询问的,他们真的不希望我们直接使用这些文件 (pdf_link_service.js),所以他告诉我检查取出他们的示例组件并像他们一样通过 pdf_viewer.js 访问 pdfLinkService,这是示例组件的链接 github.com/mozilla/pdf.js/tree/master/examples/components 我正在关注他们的 pageViewer.js 示例,因此您只需通过 HTML 文件中的脚本标记添加 pdf_viewer.js然后在你的脚本中使用它,就像示例文件一样
猜你喜欢
  • 2015-04-26
  • 2019-03-24
  • 1970-01-01
  • 2018-09-20
  • 2011-09-22
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多