2013-05-27 6 views

Antwort

30

I have committed the example to Mozilla's pdf.js repository and it is available under the examples directory.

Das ursprüngliche Beispiel, das ich Pdf.js begangen existiert nicht mehr, aber ich glaube, es this Beispiel zeigt Text-Auswahl. Sie haben pdf.js aufgeräumt und reorganisiert, und so ist die Textauswahllogik in der Text-Ebene gekapselt, die mit einer Factory erstellt werden kann.

Insbesondere nimmt PDFJS.DefaultTextLayerFactory Pflege der Grundtext-Auswahl Sachen der Einrichtung.


Das folgende Beispiel ist veraltet; nur aus historischen Gründen.

Ich habe jetzt mit diesem Problem für 2-3 Tage zu kämpfen, aber ich dachte, es endlich heraus. Here ist eine Geige, die zeigt, wie man ein PDF mit aktivierter Textauswahl lädt.

Die Schwierigkeit beim Ausrechnen war, dass die Textauswahllogik mit dem Zuschauercode verflochten war (viewer.js, viewer.html, viewer.css). Ich musste einen entsprechenden Code und CSS befreien, um diese Arbeit zu kommen, um (die JavaScript-Datei in der Datei referenziert wird, man kann es auch here check out). Das Endergebnis ist eine minimale Demo, die sich als hilfreich erweisen sollte. Um die Auswahl richtig zu implementieren, ist das CSS, das in viewer.css ist, auch extrem wichtig, da es CSS-Stile für die div s erstellt, die schließlich erstellt und dann verwendet werden, um Textauswahl funktioniert zu erhalten.

Das schwere Heben erfolgt durch das TextLayerBuilder Objekt, das tatsächlich die Erstellung der Auswahl div s behandelt. Sie können Aufrufe an dieses Objekt innerhalb von viewer.js sehen.

Wie auch immer, hier ist der Code einschließlich der CSS. Beachten Sie, dass Sie weiterhin die Datei pdf.js benötigen. Meine Geige hat einen Link zu einer Version, die ich für pdf.js von Mozillas GitHub Repo gebaut. Ich wollte nicht direkt mit der Repo-Version verlinken, da sie ständig weiterentwickelt wird und möglicherweise kaputt ist.

So ohne weiteres:

HTML:

<html> 
    <head> 
     <title>Minimal pdf.js text-selection demo</title> 
    </head> 

    <body> 
     <div id="pdfContainer" class = "pdf-content"> 
     </div> 
    </body> 
</html> 

CSS:

.pdf-content { 
    border: 1px solid #000000; 
} 

/* CSS classes used by TextLayerBuilder to style the text layer divs */ 

/* This stuff is important! Otherwise when you select the text, the text in the divs will show up! */ 
::selection { background:rgba(0,0,255,0.3); } 
::-moz-selection { background:rgba(0,0,255,0.3); } 

.textLayer { 
    position: absolute; 
    left: 0; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    color: #000; 
    font-family: sans-serif; 
    overflow: hidden; 
} 

.textLayer > div { 
    color: transparent; 
    position: absolute; 
    line-height: 1; 
    white-space: pre; 
    cursor: text; 
} 

.textLayer .highlight { 
    margin: -1px; 
    padding: 1px; 

    background-color: rgba(180, 0, 170, 0.2); 
    border-radius: 4px; 
} 

.textLayer .highlight.begin { 
    border-radius: 4px 0px 0px 4px; 
} 

.textLayer .highlight.end { 
    border-radius: 0px 4px 4px 0px; 
} 

.textLayer .highlight.middle { 
    border-radius: 0px; 
} 

.textLayer .highlight.selected { 
    background-color: rgba(0, 100, 0, 0.2); 
} 

JavaScript:

//Minimal PDF rendering and text-selection example using pdf.js by Vivin Suresh Paliath (http://vivin.net) 
//This fiddle uses a built version of pdf.js that contains all modules that it requires. 
// 
//For demonstration purposes, the PDF data is not going to be obtained from an outside source. I will be 
//storing it in a variable. Mozilla's viewer does support PDF uploads but I haven't really gone through 
//that code. There are other ways to upload PDF data. For instance, I have a Spring app that accepts a 
//PDF for upload and then communicates the binary data back to the page as base64. I then convert this 
//into a Uint8Array manually. I will be demonstrating the same technique here. What matters most here is 
//how we render the PDF with text-selection enabled. The source of the PDF is not important; just assume 
//that we have the data as base64. 
// 
//The problem with understanding text selection was that the text selection code has heavily intertwined 
//with viewer.html and viewer.js. I have extracted the parts I need out of viewer.js into a separate file 
//which contains the bare minimum required to implement text selection. The key component is TextLayerBuilder, 
//which is the object that handles the creation of text-selection divs. I have added this code as an external 
//resource. 
// 
//This demo uses a PDF that only has one page. You can render other pages if you wish, but the focus here is 
//just to show you how you can render a PDF with text selection. Hence the code only loads up one page. 
// 
//The CSS used here is also very important since it sets up the CSS for the text layer divs overlays that 
//you actually end up selecting. 
// 
//For reference, the actual PDF document that is rendered is available at: 
//http://vivin.net/pub/pdfjs/TestDocument.pdf 

var pdfBase64 = "..."; //should contain base64 representing the PDF 

var scale = 1; //Set this to whatever you want. This is basically the "zoom" factor for the PDF. 

/** 
* Converts a base64 string into a Uint8Array 
*/ 
function base64ToUint8Array(base64) { 
    var raw = atob(base64); //This is a native function that decodes a base64-encoded string. 
    var uint8Array = new Uint8Array(new ArrayBuffer(raw.length)); 
    for(var i = 0; i < raw.length; i++) { 
     uint8Array[i] = raw.charCodeAt(i); 
    } 

    return uint8Array; 
} 

function loadPdf(pdfData) { 
    PDFJS.disableWorker = true; //Not using web workers. Not disabling results in an error. This line is 
           //missing in the example code for rendering a pdf. 

    var pdf = PDFJS.getDocument(pdfData); 
    pdf.then(renderPdf);        
} 

function renderPdf(pdf) { 
    pdf.getPage(1).then(renderPage); 
} 

function renderPage(page) { 
    var viewport = page.getViewport(scale); 
    var $canvas = jQuery("<canvas></canvas>"); 

    //Set the canvas height and width to the height and width of the viewport 
    var canvas = $canvas.get(0); 
    var context = canvas.getContext("2d"); 
    canvas.height = viewport.height; 
    canvas.width = viewport.width; 

    //Append the canvas to the pdf container div 
    jQuery("#pdfContainer").append($canvas); 

    //The following few lines of code set up scaling on the context if we are on a HiDPI display 
    var outputScale = getOutputScale(); 
    if (outputScale.scaled) { 
     var cssScale = 'scale(' + (1/outputScale.sx) + ', ' + 
      (1/outputScale.sy) + ')'; 
     CustomStyle.setProp('transform', canvas, cssScale); 
     CustomStyle.setProp('transformOrigin', canvas, '0% 0%'); 

     if ($textLayerDiv.get(0)) { 
      CustomStyle.setProp('transform', $textLayerDiv.get(0), cssScale); 
      CustomStyle.setProp('transformOrigin', $textLayerDiv.get(0), '0% 0%'); 
     } 
    } 

    context._scaleX = outputScale.sx; 
    context._scaleY = outputScale.sy; 
    if (outputScale.scaled) { 
     context.scale(outputScale.sx, outputScale.sy); 
    }  

    var canvasOffset = $canvas.offset(); 
    var $textLayerDiv = jQuery("<div />") 
     .addClass("textLayer") 
     .css("height", viewport.height + "px") 
     .css("width", viewport.width + "px") 
     .offset({ 
      top: canvasOffset.top, 
      left: canvasOffset.left 
     }); 

    jQuery("#pdfContainer").append($textLayerDiv); 

    page.getTextContent().then(function(textContent) { 
     var textLayer = new TextLayerBuilder($textLayerDiv.get(0), 0); //The second zero is an index identifying 
                     //the page. It is set to page.number - 1. 
     textLayer.setTextContent(textContent); 

     var renderContext = { 
      canvasContext: context, 
      viewport: viewport, 
      textLayer: textLayer 
     }; 

     page.render(renderContext); 
    }); 
} 

var pdfData = base64ToUint8Array(pdfBase64); 
loadPdf(pdfData);  
+1

Wow .. du hast einen tollen Job gemacht! Es wird sicher vielen anderen helfen. Die Schwierigkeiten, die ich hatte, waren genau die, die du beschrieben hast. Danke für das Zusammenstellen dieser Demo. –

+0

Ihre Geige funktioniert gut, aber wenn ich es in die HTML-Datei zu kopieren, es hat nicht funktioniert :(Was sonst Dateien soll ich ein? –

+0

@DamjanPavlica einen Blick auf die Konsole um zu sehen, was es zu beschweren. Sie müssen pdf haben ... Js verfügbar –

2

Weil Dies ist eine alte Frage und alte akzeptierte Antwort, um es mit der neuesten PDF zu arbeiten.JS Versionen, die Sie mit dieser Lösung können

http://www.ryzhak.com/converting-pdf-file-to-html-canvas-with-text-selection-using-pdf-js

Hier ist der Code, den sie verwendet: Fügen Sie die folgende CSS und Scripts aus dem Pdf.js Code

<link rel="stylesheet" href="pdf.js/web/text_layer_builder.css" /> 
<script src="pdf.js/web/ui_utils.js"></script> 
<script src="pdf.js/web/text_layer_builder.js"></script> 

Verwendung dieser Code die PDF laden :

PDFJS.getDocument("oasis.pdf").then(function(pdf){ 
    var page_num = 1; 
    pdf.getPage(page_num).then(function(page){ 
     var scale = 1.5; 
     var viewport = page.getViewport(scale); 
     var canvas = $('#the-canvas')[0]; 
     var context = canvas.getContext('2d'); 
     canvas.height = viewport.height; 
     canvas.width = viewport.width; 

     var canvasOffset = $(canvas).offset(); 
     var $textLayerDiv = $('#text-layer').css({ 
      height : viewport.height+'px', 
      width : viewport.width+'px', 
      top : canvasOffset.top, 
      left : canvasOffset.left 
     }); 

     page.render({ 
      canvasContext : context, 
      viewport : viewport 
     }); 

     page.getTextContent().then(function(textContent){ 
      console.log(textContent); 
      var textLayer = new TextLayerBuilder({ 
       textLayerDiv : $textLayerDiv.get(0), 
       pageIndex : page_num - 1, 
       viewport : viewport 
      }); 

      textLayer.setTextContent(textContent); 
      textLayer.render(); 
     }); 
    }); 
});  
+0

Siehe auch Beispiele https://github.com/mozilla/pdf.js/tree/master/examples/components – async5