Esta es una antigua cuestión, pero debido a que pdf.js se ha desarrollado a lo largo de los años, me gustaría dar una nueva respuesta. Es decir, se puede hacer localmente sin involucrar ningún servidor o servicio externo. El nuevo pdf.js tiene una función: page.getTextContent(). Puedes obtener el contenido de texto de eso. Lo he hecho con éxito con el siguiente código.
Lo que obtienes en cada paso es una promesa. Debe codificar de esta manera: .then(function(){...})
para pasar al siguiente paso.
1) PDFJS.getDocument(data).then(function(pdf) {
2) pdf.getPage(i).then(function(page){
3) page.getTextContent().then(function(textContent){
Lo que finalmente se obtiene es una matriz de cadenas textContent.bidiTexts[]
. Los concatenas para obtener el texto de 1 página. Las coordenadas de los bloques de texto se utilizan para juzgar si se debe insertar nueva línea o espacio. (Esto puede no ser totalmente robusto, pero de mi prueba parece estar bien.)
El parámetro de entrada data
debe ser un tipo de datos de URL o ArrayBuffer. Usé la función ReadAsArrayBuffer (archivo) en FileReader
API para obtener los datos.
Espero que esto ayude.
Nota: De acuerdo con algún otro usuario, la biblioteca se ha actualizado y provocó la ruptura del código. De acuerdo con el comentario por async5 a continuación, debe reemplazar 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
'Pregunta antigua' pero excelente respuesta. ¿Tienes alguna idea de cómo hacer que textLayer no represente caracteres en divs individuales sino que los represente como palabras completas? Obtuve un gran golpe de rendimiento al tratar de usar la superposición de la capa de texto con los divs en posición absoluta, ya que hay muchos de ellos. Si prefieres esto como una pregunta de StackOverflow real separada, haré una. – AJP
@ gm2008 He intentado extraer texto de un PDF usando su función. Sin embargo, no puedo extraer el texto. El texto completo devuelve una cadena vacía al final. ¿Puedes ayudarme? – suzee
No pude hacer que esto funcione tampoco (API ha cambiado). Agregué mi propio ejemplo a continuación. – SchizoDuckie