2013-12-11 11 views
5

Ich versuche, Text aus einer PDF in eine Zeichenfolge mit Hilfe der iTextSharp-Bibliothek zu lesen.Lesen von Text aus 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); 

Dies funktioniert in der Regel in Ordnung, aber alle paar Zeilen die Leerzeichen weggelassen, wie ich mit Ausgang zu verlassen: „thisismyoutputwithoutwhitespace“. Der Text, der korrekt analysiert, scheint derselbe zu sein wie der Text, der nicht korrekt analysiert wird. Derselbe Text wird immer falsch geparst, was mich glauben lässt, dass es sich um etwas in den PDFs handelt.

Antwort

6

Im Content-Stream einer PDF gibt es keine Vorstellung von "Wörtern". Also gibt es in iText (Sharp) 's Text Extraction Implementation einige Heuristiken, um zu bestimmen, wie man Zeichen in Wörter gruppiert. Wenn der Abstand zwischen zwei Zeichen größer als die halbe Breite eines Leerzeichens in der aktuellen Schriftart ist, wird Leerraum eingefügt.

Höchstwahrscheinlich hat der Text, der ohne Leerzeichen extrahiert wird, Abstände zwischen den Wörtern, die kleiner sind als "spacebright/2".

In SimpleTextExtractionStrategy.RenderText():

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

Sie können SimpleTextExtractionStrategy erweitern und die RenderText() einzustellen.

In LocationTextExtractionStrategy ist es bequemer. Sie müssen nur IsChunkAtWordBoundary() außer Kraft zu setzen:

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; 
} 

Du musst ein wenig experimentieren, um gute Ergebnisse für Ihre PDF-Dateien zu bekommen. "spacebreite/2" ist in Ihrem Fall offensichtlich zu groß. Aber wenn Sie es zu klein einstellen, erhalten Sie falsch positive Ergebnisse: Leerzeichen werden in Wörter eingefügt.

+0

Vielen Dank! Das ist sehr hilfreich. Sind Sie jedoch sicher, dass IsChunkAtBounary() überschrieben werden kann? Ich bekomme ein "kann nicht überschreiben, weil es nicht als abstrakt, virtuell markiert ist.". Ich habe eine neue Klasse erstellt, LocationTextExtractionStrategy erweitert und die Methode überschrieben. –

+0

Dies scheint ein Portierungsfehler von Java zu C# zu sein. Ich werde sicherstellen, dass dies in der nächsten Version behoben wird. Zur Problemumgehung müssen Sie den Code "LocationTextExtractionStrategy" kopieren und so eine vollständig neue Implementierung der ITextExtractionStrategy-Schnittstelle erstellen. In Ihrer neuen Implementierung können Sie die isChunkAtWordBoundary-Methode anpassen. Ich weiß ... nicht die sauberste Lösung. Ich bin nicht sehr vertraut mit C#; vielleicht kann jemand mit mehr C# -Erfahrung an eine elegantere Lösung denken. – rhens

+0

Wenn Sie den Quellcode von LocationTextExtractionStrategy nicht zur Verfügung haben, können Sie ihn hier (neueste Version) finden: http://sourceforge.net/p/itextsharp/code/HEAD/tree/trunk/src/core/iTextSharp /text/pdf/parser/LocationTextExtractionStrategy.cs – rhens