2013-12-11 28 views
5

Sto cercando di leggere il testo da un PDF in una stringa utilizzando la libreria iTextSharp.Leggere il testo da PDF in .NET

iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(@"C:\mypdf.pdf"); 
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, 1, strategy); 
text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); 
pdfReader.Close(); 
Console.WriteLine(text); 

Questo funziona normalmente OK, ma ogni poche righe gli spazi verrà omesso, lasciandomi con uscita del tipo: "thisismyoutputwithoutwhitespace". Il testo che analizza correttamente sembra essere lo stesso del testo che non lo fa; lo stesso testo sarà costantemente analizzato in modo errato, il che mi fa pensare che sia qualcosa all'interno dei PDF.

risposta

6

Nel flusso di contenuti di un PDF non c'è la nozione di "parole". Quindi nell'implementazione dell'estrazione del testo di iText (Sharp) ci sono alcune euristiche per determinare come raggruppare i caratteri in parole. Quando la distanza tra 2 caratteri è maggiore della metà della larghezza di uno spazio nel carattere corrente, viene inserito uno spazio bianco.

Molto probabilmente, il testo che viene estratto senza spazi vuoti ha distanze tra le parole che sono più piccole di "spacewidth/2".

In SimpleTextExtractionStrategy.RenderText():

if (spacing > renderInfo.GetSingleSpaceWidth()/2f){ 
    AppendTextChunk(' '); 
} 

È possibile estendere SimpleTextExtractionStrategy e regolare il RenderText().

In LocationTextExtractionStrategy è più conveniente. Hai solo bisogno di sovrascrivere IsChunkAtWordBoundary():

protected bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk) { 
    float dist = chunk.DistanceFromEndOf(previousChunk); 
    if(dist < -chunk.CharSpaceWidth || dist > chunk.CharSpaceWidth/2.0f) 
     return true; 

    return false; 
} 

dovrete sperimentare un po 'per ottenere buoni risultati per i tuoi PDF. "spacewidth/2" è apparentemente troppo grande nel tuo caso. Ma se lo aggiusti troppo piccolo, otterrai dei falsi positivi: lo spazio bianco verrà inserito all'interno delle parole.

+0

Grazie mille! Questo è molto utile. Tuttavia, sei sicuro che IsChunkAtBounary() sia sovrascrivibile? Sto ottenendo un "impossibile eseguire l'override perché non è contrassegnato come astratto, virtuale ..". Ho creato una nuova classe, esteso LocationTextExtractionStrategy e ho sovrascritto il metodo. –

+0

Questo sembra essere un errore di porting, da Java a C#. Mi assicurerò che questo sia corretto nella prossima versione. Come soluzione, penso che dovrai copiare il codice LocationTextExtractionStrategy, creando in modo efficace un'implementazione completamente nuova dell'interfaccia ITextExtractionStrategy. Nella tua nuova implementazione puoi regolare il metodo isChunkAtWordBoundary. Lo so ... non la soluzione più pulita. Non ho molta familiarità con C#; forse qualcuno con più esperienza in C# può pensare ad una soluzione più elegante. – rhens

+0

Se non si dispone del codice sorgente di LocationTextExtractionStrategy, è possibile trovarlo qui (la versione più recente): http://sourceforge.net/p/itextsharp/code/HEAD/tree/trunk/src/core/iTextSharp /text/pdf/parser/LocationTextExtractionStrategy.cs – rhens