estrai testo da pdf in Javascript

Mi chiedo se è ansible ottenere il testo all’interno di un file PDF utilizzando solo Javascript? Se sì, qualcuno può mostrarmi come?

So che ci sono alcune librerie java, c #, server ecc., Ma preferirei non utilizzare un server. Grazie

Questa è una domanda antica, ma poiché pdf.js si è sviluppato nel corso degli anni, vorrei dare una nuova risposta. Cioè, può essere fatto localmente senza coinvolgere alcun server o servizio esterno. Il nuovo pdf.js ha una funzione: page.getTextContent (). Puoi ottenere il contenuto del testo da quello. L’ho fatto con successo con il seguente codice.

  1. Ciò che ottieni in ogni passaggio è una promise. È necessario codificare in questo modo: .then( function(){...}) per procedere al passaggio successivo.

    1) PDFJS.getDocument( data ).then( function(pdf) {

    2) pdf.getPage(i).then( function(page){

    3) page.getTextContent().then( function(textContent){

  2. Quello che ottieni infine è un array di stringhe textContent.bidiTexts[] . Li concateni per ottenere il testo di 1 pagina. Le coordinate dei blocchi di testo vengono utilizzate per giudicare se è necessario inserire newline o spazio. (Questo potrebbe non essere completamente robusto, ma dal mio test sembra ok.)

  3. I dati dei parametri di input devono essere un URL o dati di tipo ArrayBuffer. Ho usato la funzione ReadAsArrayBuffer (file) in FileReader API per ottenere i dati.

Spero che questo ti aiuti.

Nota: in base ad altri utenti, la libreria è stata aggiornata e ha causato la rottura del codice. In base al commento di async5 di seguito, è necessario sostituire textContent.bidiTexts con textContent.items .

  function Pdf2TextClass(){ var self = this; this.complete = 0; /** * * @param data ArrayBuffer of the pdf file content * @param callbackPageDone To inform the progress each time * when a page is finished. The callback function's input parameters are: * 1) number of pages done; * 2) total number of pages in file. * @param callbackAllDone The input parameter of callback function is * the result of extracted text from pdf file. * */ this.pdfToText = function(data, callbackPageDone, callbackAllDone){ console.assert( data instanceof ArrayBuffer || typeof data == 'string' ); PDFJS.getDocument( data ).then( function(pdf) { var div = document.getElementById('viewer'); var total = pdf.numPages; callbackPageDone( 0, total ); var layers = {}; for (i = 1; i <= total; i++){ pdf.getPage(i).then( function(page){ var n = page.pageNumber; page.getTextContent().then( function(textContent){ if( null != textContent.bidiTexts ){ var page_text = ""; var last_block = null; for( var k = 0; k < textContent.bidiTexts.length; k++ ){ var block = textContent.bidiTexts[k]; if( last_block != null && last_block.str[last_block.str.length-1] != ' '){ if( block.x < last_block.x ) page_text += "\r\n"; else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null )) page_text += ' '; } page_text += block.str; last_block = block; } textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text); layers[n] = page_text + "\n\n"; } ++ self.complete; callbackPageDone( self.complete, total ); if (self.complete == total){ window.setTimeout(function(){ var full_text = ""; var num_pages = Object.keys(layers).length; for( var j = 1; j <= num_pages; j++) full_text += layers[j] ; callbackAllDone(full_text); }, 1000); } }); // end of page.getTextContent().then }); // end of page.then } // of for }); }; // end of pdfToText() }; // end of class 

Non sono riuscito a far funzionare l’esempio di gm2008 (la struttura dati interna su pdf.js è cambiata apparentemente), quindi ho scritto la mia soluzione completamente basata su promesse che non usa alcun elemento DOM, queryselector o canvas, usando il pdf aggiornato .js dell’esempio di mozilla

Mangia un percorso file per il caricamento poiché lo sto usando con node-webkit. Devi assicurarti di avere i cmap scaricati e puntati da qualche parte e tu nee pdf.js e pdf.worker.js per farlo funzionare.

  /** * Extract text from PDFs with PDF.js * Uses the demo pdf.js from https://mozilla.github.io/pdf.js/getting_started/ */ this.pdfToText = function(data) { PDFJS.workerSrc = 'js/vendor/pdf.worker.js'; PDFJS.cMapUrl = 'js/vendor/pdfjs/cmaps/'; PDFJS.cMapPacked = true; return PDFJS.getDocument(data).then(function(pdf) { var pages = []; for (var i = 0; i < pdf.numPages; i++) { pages.push(i); } return Promise.all(pages.map(function(pageNumber) { return pdf.getPage(pageNumber + 1).then(function(page) { return page.getTextContent().then(function(textContent) { return textContent.items.map(function(item) { return item.str; }).join(' '); }); }); })).then(function(pages) { return pages.join("\r\n"); }); }); } 

utilizzo:

  self.pdfToText(files[0].path).then(function(result) { console.log("PDF done!", result); }) 

Ecco un codice JavaScript che fa ciò che vuoi usando Pdf.js da http://hublog.hubmed.org/archives/001948.html :

 var input = document.getElementById("input"); var processor = document.getElementById("processor"); var output = document.getElementById("output"); // listen for messages from the processor window.addEventListener("message", function(event){ if (event.source != processor.contentWindow) return; switch (event.data){ // "ready" = the processor is ready, so fetch the PDF file case "ready": var xhr = new XMLHttpRequest; xhr.open('GET', input.getAttribute("src"), true); xhr.responseType = "arraybuffer"; xhr.onload = function(event) { processor.contentWindow.postMessage(this.response, "*"); }; xhr.send(); break; // anything else = the processor has returned the text of the PDF default: output.textContent = event.data.replace(/\s+/g, " "); break; } }, true); 

… ed ecco un esempio:

http://git.macropus.org/2011/11/pdftotext/example/

Per tutte le persone che effettivamente vogliono usarlo su un server nodo:

 /** * Created by velten on 25.04.16. */ "use strict"; let pdfUrl = "http://example.com/example.pdf"; let request = require('request'); var pdfParser = require('pdf2json'); let pdfPipe = request({url: pdfUrl, encoding:null}).pipe(pdfParser); pdfPipe.on("pdfParser_dataError", err => console.error(err) ); pdfPipe.on("pdfParser_dataReady", pdf => { //optionally: //let pdf = pdfParser.getMergedTextBlocksIfNeeded(); let count1 = 0; //get text on a particular page for (let page of pdf.formImage.Pages) { count1 += page.Texts.length; } console.log(count1); pdfParser.destroy(); }); 

È ansible ma:

  • dovresti comunque utilizzare il server, non è ansible ottenere il contenuto di un file sul computer dell’utente senza trasferirlo al server e viceversa
  • Non penso che qualcuno abbia mai scritto una tale biblioteca

Quindi, se hai del tempo libero puoi imparare il formato pdf e scrivere da solo una tale libreria, oppure puoi semplicemente usare la libreria lato server, ovviamente.