Saltar al contenido

¿Existe una muestra PDF.js minimalista que admita la selección de texto?

Ya no necesitas buscar más por todo internet ya que estás al lugar exacto, tenemos la respuesta que necesitas sin problema.

Solución:

He enviado el ejemplo al repositorio pdf.js de Mozilla y está disponible en la examples directorio.

El ejemplo original que comprometí con pdf.js ya no existe, pero creo que este ejemplo muestra la selección de texto. Han limpiado y reorganizado pdf.js, por lo que la lógica de selección de texto está encapsulada dentro de la capa de texto, que se puede crear utilizando una fábrica.

Específicamente, PDFJS.DefaultTextLayerFactory se encarga de configurar las cosas básicas de selección de texto.


El siguiente ejemplo está desactualizado; solo dejándolo aquí por razones históricas.

He estado luchando con este problema durante 2-3 días, pero finalmente lo descubrí. Aquí hay un violín que le muestra cómo cargar un PDF con la selección de texto habilitada.

La dificultad para resolver esto fue que la lógica de selección de texto estaba entrelazada con el código del visor (viewer.js, viewer.html, viewer.css). Tuve que extraer el código relevante y CSS para que esto funcionara (ese archivo JavaScript está referenciado en el archivo; también puede consultarlo aquí). El resultado final es una demostración mínima que debería resultar útil. Para implementar la selección correctamente, el CSS que está en viewer.css también es extremadamente importante, ya que configura estilos CSS para el divs que eventualmente se crean y luego se usan para que la selección de texto funcione.

El trabajo pesado lo hace el TextLayerBuilder objeto, que en realidad maneja la creación de la selección divs. Puede ver las llamadas a este objeto desde dentro viewer.js.

De todos modos, aquí está el código que incluye el CSS. Tenga en cuenta que todavía necesitará el pdf.js expediente. Mi violín tiene un enlace a una versión que construí a partir del repositorio de GitHub de Mozilla para pdf.js. No quería vincularme directamente a la versión del repositorio, ya que lo están desarrollando constantemente y puede estar roto.

Así que sin más preámbulos:

HTML:


    
        Minimal pdf.js text-selection demo
    

    
        

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("");

    //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("
") .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);

Debido a que esta es una pregunta antigua y una respuesta antigua aceptada, para que funcione con las versiones recientes de PDF.JS, puede usar esta solución

Converting pdf file to html canvas with text selection using PDF.js

Este es el código que usaron: Incluya los siguientes CSS y scripts del código PDF.js




use este código para cargar el PDF:

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();
        );
    );
);    

Comentarios y valoraciones de la guía

Recuerda que tienes autorización de añadir un diagnóstico justo si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 3 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *