Convert from PDF to TXT

yerl

Mitglied
Hallo liebe Java-Community,

ich habe da ein kleines Problem. Ich versuche aus einer Pdf-Datei das Inhaltsverzeichnis auszulesen.
Zunächst wird die ganze Datei in eine Txt kopiert, dann "schneide" ich das Inhaltsverz. raus und verarbeite es weiter, dabei ist die Form des Inh.verz. immer gleich. Soweit so gut.

Ich habe hier ein paar tausend Dateien vorliegen, sowohl im Pdf als auch im .doc Format. Bei einigen funktioniert die oben beschriebene Prozedur einwandfrei, bei anderen widerrum gar nicht.

Die ursprünglichen .doc Dateien wurden mit Hilfe von versch. Convertern in Pdf umgewandelt. (PDFCreator, Adobe PDf, PDFFactory usw.). Nehme ich eine ursprüngliche fehlerhafte Pdf, sieht sie aber zur 100% (optisch) genau so aus wie die .doc. Das Inhaltsverz. wird aber falsch dargestellt. (In der txt).

Jetzt kommts. Gehe ich wieder zur der .doc, wandle sie nochnal um in Pdf mit Adobe, funktioniert alles einwanndfrei, das Inhaltsverz. wird 100%ig richtig dargestellt (in der TXt).

Hat jemand eine Idee, wie es dazu kommt? Ich habe nur nicht die Möglichkeit, die Dateien ständig neu zu konvertieren, sondern muss immer die mir zur Verfügung gestellten .pdfs verwenden.

Ich verwende folgende Konvertierungsvariante:

Itext:

Java:
			PdfReader reader = new PdfReader(quelle);
			PdfReaderContentParser parser = new PdfReaderContentParser(reader);
			PrintWriter out = new PrintWriter(new FileOutputStream(ziel));
			TextExtractionStrategy strategy;
			for (int i = 1; i <= reader.getNumberOfPages(); i++) 
			{
				strategy = parser.processContent(i, new SimpleTextExtractionStrategy());
				out.println(strategy.getResultantText());
			}


habe es aber auch mit:

Java:
		        PdfReader reader = new PdfReader(quelle);
		        PrintWriter out = new PrintWriter(new FileOutputStream(ziel));
		        Rectangle rect = new Rectangle(70,80,595,842);
		        RenderFilter filter = new RegionTextRenderFilter(rect);
		        TextExtractionStrategy strategy;
		        for (int i = 1; i <= reader.getNumberOfPages(); i++) 
		        {
		            strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), filter);
		            out.println(PdfTextExtractor.getTextFromPage(reader, i, strategy));
		        }
		        out.flush();
		        out.close();

oder mit:

Java:
			for (int i = 1; i <= reader.getNumberOfPages(); i++) 
			{
				out.write(PdfTextExtractor.getTextFromPage(reader, i));
			}    
			out.flush();
			out.close();
versucht.

Aber auch die PDfBox:

Java:
		    PDFTextStripper stripper = new PDFTextStripper();
		    PDDocument pdDoc = PDDocument.load(quelle);
		    StringWriter writer = new StringWriter();
		    stripper.writeText(pdDoc, writer);
		    System.out.println(writer.toString());

leider alles ohne Erfolg, das Ergebnis sieht immer gleich aus.

Inhalt.verz. in der Txt

Falsch:

Inhaltsverzeichnis:
......................................................................................................................... 7 1 Allgemeines
......................................................................................................... 7 1.1 Gültigkeitsbereich
.................................................................................................. 7 1.2 Prüflingsbeschreibung
................................................................................................. 9 1.3 Technische Unterlagen

Richtig:

Inhaltsverzeichnis:
1 Allgemeines.......................................................................................................................7
1.1 Gültigkeitsbereich .......................................................................................................7
1.2 Prüflingsbeschreibung ................................................................................................7
1.3 Technische Unterlagen...............................................................................................9



Zusammengefasst: :)) Die zwei .Pdf Dateien (ursprünglich und neu konvertiert) sehen optisch zu 100% identisch aus. Die Ergebnisse in der Txt sind aber verschieden, bei ursprünglich falsch, bei neu konv. richtig. Bei einigen pdfs funktionierts (Ergebnis in er Txt einwandfrei), bei anderen widerrum nicht...

Bitte helft mir Leute.
Danke im Voraus.
yerl.
 

yerl

Mitglied
Das tue ich, aber das Inhaltsverzeichnis wird dann falsch dargestellt und meine Methode die es weiter verarbeitet, um es dann in eine ListBox einzufügen, kommt mit der falsch dargestellten Form nicht zurecht.

Also das Einfügen in die ListBox ist natürlich nicht das Problem, sondern das Weiterverarbeiten, die linke Seite sind meine Punkte in der List und die rechte Seite sind die Seitennummern, welche an eine andere Methode übergeben werden. Die widerrum stellt die benötigte PdfSeite über den PDFRenderer in einem Label dar.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
was gibt es da groß zu überlegen?
durch die Umwandlung, mit der du anscheinend leben musst, hast du mal das eine, mal das andere Ergebnis,
auch damit wirst du nun also Leben müssen, wenn das im PDF so drin ist
(woher sollten die Unterschiede sonst kommen und du sprichst die Erzeugung ja direkt an)
dann kann man das nicht wegzaubern,

vom Parsen einer graphischen Darstellung kann man sich generell nicht allzu viel erhoffen, sei froh dass es nicht noch schlimmer ist, etwa

Inhaltsverzeichnis:
7 7 7 9
1 1.1 1.2 1.3
Allg. Gült. ...

!

die bisherigen beiden Varianten scheinen ja noch akzeptabel verwendbar zu sein,
untersuche sie eben genau, ob jede Zeile mit einer Zahl beginnt oder endet usw.,
und wandle je nachdem den Text passend um
 

Andi_CH

Top Contributor
Sicher gehts mit Regexp VIEL kompakter, aber das ist eine 2-Minuten-Lösung (höchstens)
Ach ja StringBuilder --- es hat noch SEHR VIEL Optimierungspotential :)

Java:
public class Convert {

	private static final int zeilenlänge = 50;
	private static final String[] arr = {
		"......................................................................................................................... 7 1 Allgemeines",
		"......................................................................................................... 7 1.1 Gültigkeitsbereich",
		".................................................................................................. 7 1.2 Prüflingsbeschreibung",
		"................................................................................................. 9 1.3 Technische Unterlagen"};
	
	public static String separator(int anz) {
		String ret = " ";
		for (int i=0; i<anz; i++)
			ret += ".";
		return ret + " ";
	}
	public static String conv ( String pIn ) {
		// Seitenzahl extrahieren
		int anfang = pIn.indexOf(' ');
		int ende = pIn.indexOf(' ', anfang+1);
		String seite = pIn.substring(anfang, ende).trim();
		// Kapitelnummer extrahieren
		anfang = ende;
		ende = pIn.indexOf(' ', anfang+1);
		String kapitel = pIn.substring(anfang, ende).trim();
		// Titel extrahieren
		anfang = ende;
		ende = pIn.indexOf(' ', anfang+1);
		String titel;
		if (ende == -1) {
			titel = pIn.substring(anfang).trim();
		} else {
			titel = pIn.substring(anfang, ende).trim();
		}
		int anzSepChar = zeilenlänge - seite.length() - kapitel.length() - titel.length() - 2;
		return kapitel + " " + titel + separator(anzSepChar) + seite;
	}
	public static void main(String[] args) {
		for (String s : arr) {
			System.out.println(conv(s));
		}
	}
}

EDIT: Das war die komplizierte Variante - das ist die Einfache:
Java:
	public static String conv(String pIn) {
		String[] arr = pIn.split(" ");
		int anzSepChar = zeilenlänge - arr[1].length() - arr[2].length() - arr[3].length() - 2;
		return arr[2] + " " + arr[3] + separator(anzSepChar) + arr[1];
	}
 
Zuletzt bearbeitet:

faetzminator

Gesperrter Benutzer
Ein kleiner Regex - in weniger als 2min geschrieben :bae:
Java:
public static String parse(String str) {
    final String pattern = "^(\\.+)\\s+(\\d+)\\s+([\\d+\\.]+)\\s+(.*)$";
    if (str.matches(pattern)) {
        str = str.replaceFirst(pattern, "$3 $4$1$2");
    }
    return str;
}
 

yerl

Mitglied
@ faetzminator ==> dein 2 min. regex hat mir den ganzen Tag gerettet. Einfach genial. Vielen Dank dafür. Auch Danke an Andi_CH!!

Könntest du mir kurz erklären was genau du da machst, möchte gerne mehr verstehen. thx.

Ich habe da noch ein kleines Problem, wenn ich an deine Methode parse(), die bei mir perfekt funktioniert(mit den falsch konvertierten pdfs) *danke*, eine richtig konvertierte Zeile übergebe(aus richtig konvertierten pdfs), macht die Methode nichts.

Da ich aber meine Methode für die ListBox, an die Ausgabe deiner parse() angepasst habe, bräuche ich jetzt wieder die gleiche Ausgabe wie aus der parse()-Methode.

Richtige konvertierung(wird von parse() nicht verarbeitet)
1.1 Gültigkeitsbereich .........................................................................................................5

Falsche konvertierung(mit parse() verarbeitet)
1.1 Gültigkeitsbereich.........................................................................................................4

sieht fast identisch aus, aber parse() möchte diese(obere) nicht verarbeiten. Könntest du mir erklären warum?

Vielen Vielen Dank.
yerl
 
Zuletzt bearbeitet:
S

SlaterB

Gast
die parse-Methode ist eben dafür da, das falsche Format ins richtige zu überführen,
erwartet dafür die Seitenzahl vorne, die Nummerierung ([\\d+\\.]+) hinten,
wenn schon das richtige Format vorliegt, was sollte parse dann machen?

> aber parse() möchte diese(obere) nicht verarbeiten

wie stellst du überhaupt fest ob verarbeitet wurde und nochmal nachgefragt:
was erwartest du denn als Verarbeitungsergebnis?



([\\d+\\.]+) usw. kann man kaum näher erklären, alles hat eine Funktion, aber dafür einfach 'reguläre Ausdrücke' lernen
 

yerl

Mitglied
ich möchte das die parse() das richtige format in das identisch gleiche bringt, wie sie aus dem falschen erzeugt. Muss leider nach Hause, sorry, bin morgen früh wieder online. Vielen Dank für die schnellen Antworten.

p.s.

Im Studium werden reguläre Ausdrücke einem, leider nicht gezeigt, bei mir zumindest nicht.
 
S

SlaterB

Gast
schade dass für das Forum nicht dieselben Regeln gelten (keiner hat es dir gezeigt, also fragst du hier auch nicht ;) )
 

yerl

Mitglied
Gibt es natürlich nicht!! Asche über mein Haupt, sorry Leute, habe ein Fehler bei mir gehabt. Nochmals vielen Dank an alle, besonders an faetzminator. Werd mir die Regex genauer anschauen, sehr hilfreich.

thx @ all.
yerl.
 

Ähnliche Java Themen

Neue Themen


Oben