Word .doc zu .txt mittels PHP

Vor ein paar Tagen stand ich vor dem Problem, mittels PHP Word-Documente, die auf den Webserver geladen wurde, auszulesen. Sinn der ganzen Übung ist, den reinen Text des Dokumentes in einer mySQL-Datenbank zu speichern, um dann darüber recherchieren zu können.  Stichwort webbasierendes Dokumentenmanagement, an dem ich für meine Firma arbeite. Außerdem war das Problem vorhanden, .pdf Dokumente ebenso mit indexieren zu können. Nach vielem Basteln und googlen habe ich eine brauchbare Lösung gefunden.

PDF zu Text:

Die einfachste und brauchbarste Methode, um .pdf Dokumente auszulesen, ist meiner Ansicht das Shellscript pdftotext von Xpdf, welches frei Verfügbar ist. Es gibt unter Anderem eine Windows Version, und, wie kann es wohl sein :) , auch eine Linuxversion.
Ich lade mir das PDF Dokument auf den Server (mittels Formular, oder wie auch immer), stoße die pdftotext.exe (ja es ist ein Windows Server) mittels shellexecute an und lese die erzeugte Temp-Datei wieder aus. Dies klappt wunderbar. Das Ergebnis speichere ich dann in einem “TEXT-Spalte” in mySQL und kann wunderbar per LIKE im Text suchen lassen. Für alle Nachahmer: beachtet, das bei großen Datenmengen die Suche natürlich ein wenig dauern kann ;)

.doc zu Text

Bei den alten Word .doc habe ich im Internet diverse Möglichkeiten gefunden, wie zB das Nutzen des COM Objektes von PHP. Nachteil: auf dem Server muss WORD installiert sein (tseses!). Hier stelle ich aber eine andere Methode vor, die etwas einfacher zu handhaben ist:

Ich habe bei der Suche nach einer Lösung folgendes Script im Netz gefunden:

function doc2text($filename)
{
if ( file_exists($filename) )
{
if ( ($fh = fopen($filename, 'r')) !== false )
{
$headers = fread($fh, 0xA00);
# 1 = (ord(n)*1) ; Document has from 0 to 255 characters
$n1 = ( ord($headers[0x21C]) - 1 );
# 1 = ((ord(n)-8)*256) ; Document has from 256 to 63743 characters
$n2 = ( ( ord($headers[0x21D]) - 8 ) * 256 );
# 1 = ((ord(n)*256)*256) ; Document has from 63744 to 16775423 characters
$n3 = ( ( ord($headers[0x21E]) * 256 ) * 256 );
# (((ord(n)*256)*256)*256) ; Document has from 16775424 to 4294965504 characters
$n4 = ( ( ( ord($headers[0x21F]) * 256 ) * 256 ) * 256 );
# Total length of text in the document
$textLength = ($n1 + $n2 + $n3 + $n4);
$extracted_plaintext = fread($fh, $textLength);
# if you want the plain text with no formatting, do this
//echo $extracted_plaintext;
# if you want to see your paragraphs in a web page, do this
return nl2br($extracted_plaintext);
}
}
}

Diese Minifunktion reicht für meine Bedürfnisse vollkommen aus, auch wenn manchmal ein paar Datenkrüppel vorhanden sind. Häufig auftretende fehlerhaften Strings werden vor dem Speichern in die DB noch entfernt.

.docx zu Text

Bei .docx wird es etwas umfangreicher, da das das Datenformat eine komprimierte XML Datei ist, in der der Klartext dann in einer weiteren Datei ‘versteckt’ ist. Folgende Funktion(en) habe ich gefunden, die mit den Klartext auch daraus extrahiert.

/*
* docx zu text wandeln
*/
function docx2text($filename) {
return readZippedXML($filename, "word/document.xml");
//echo docx2text('d:\\web\\ppm\\bin\\test.docx')
}

function readZippedXML($archiveFile, $dataFile) {
// Create new ZIP archive
$zip = new ZipArchive;

// Open received archive file
if (true === $zip->open($archiveFile)) {
// If done, search for the data file in the archive
if (($index = $zip->locateName($dataFile)) !== false) {
// If found, read it to the string
$data = $zip->getFromIndex($index);
// Close archive file
$zip->close();
// Load XML from a string
// Skip errors and warnings
$xml = DOMDocument::loadXML($data, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
// Return data without XML formatting tags
return strip_tags($xml->saveXML());
}
$zip->close();
}

// In case of failure return empty string
return "";
}

Vor Aufruf der jeweiligen Word-Funktion habe ich noch eine Funktion gesetzt, die mir dann die entsprechende Funktion nach der Endung automatisch aufruft:

function word2txt($filename)
{
$lastpoint=strrpos($filename,".");
$extension=substr($filename,$lastpoint,5);
if ($extension==".doc")
{
$r=doc2text($filename);
return utf8_decode($r);
}
else
{
return utf8_decode(docx2text($filename));
}
}

Es gibt bestimmt noch andere Methoden diese hat mich aber bisher gut vorangebracht. Evtl. weiß ja jemand eine noch einfachere Art, Worddokumente auszulesen. Zumindest für die .doc Dateien, da doch manchmal größerer Datenmüll entsteht.  Außerdem werde ich mich wohl noch nach einer Methode umsehen müssen, die  xls und xlsx Daten ausschnüffeln, da manchen User Excel gerne als Textverarbeitung missbrauchen.

Schlagworte: , ,

Kommentieren