Jest to starożytny pytanie, ale ponieważ pdf.js rozwija się przez lata, chciałbym dać nową odpowiedź. Oznacza to, że można to zrobić lokalnie, nie angażując żadnego serwera ani usługi zewnętrznej. Nowy plik pdf.js ma funkcję: page.getTextContent(). Możesz pobrać z tego treść tekstową. Zrobiłem to z powodzeniem z następującego kodu.
To, co dostajesz na każdym etapie, to obietnica. Musisz kodować w następujący sposób: .then(function(){...})
, aby przejść do następnego kroku.
1) PDFJS.getDocument(data).then(function(pdf) {
2) pdf.getPage(i).then(function(page){
3) page.getTextContent().then(function(textContent){
Co wreszcie jest tablicą ciąg textContent.bidiTexts[]
. Łączysz je, aby uzyskać tekst 1 strony. Współrzędne bloków tekstowych służą do oceny, czy nowa linia lub spacja muszą być wstawione. (To może nie być całkowicie solidne, ale z mojego testu wydaje się, że jest w porządku.)
Parametr wejściowy data
musi być adresem typu URL lub ArrayBuffer. Użyłem funkcji ReadAsArrayBuffer (file) w FileReader
API, aby uzyskać dane.
Mam nadzieję, że to pomoże.
Uwaga: Według niektórych innych użytkowników biblioteka zaktualizowała się i spowodowała pęknięcie kodu. Zgodnie z komentarzem: async5 poniżej, musisz zamienić textContent.bidiTexts
na 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
"Pytanie starożytne", ale doskonałe odpowiedzi. Masz pojęcie, jak sprawić, by textLayer nie renderował znaków w poszczególnych elementach div, ale renderował je jako całe słowa? Dostaję całkiem duży hit wydajnościowy od próby użycia nakładania się warstwy tekstowej z divami ustawionymi bezwzględnie, ponieważ jest ich tak wiele. Jeśli wolisz to jako osobne rzeczywiste pytanie StackOverflow, zrobię to. – AJP
@ gm2008 Próbowałem wyodrębnić tekst z pliku PDF za pomocą funkcji. Nie mogę jednak wyodrębnić tekstu. Pełny tekst zwraca pusty ciąg na końcu. Czy możesz mi pomóc? – suzee
Nie mogłem tego przekonać (API się zmieniło). Dodałem mój własny przykład poniżej. – SchizoDuckie