2012-01-24 13 views
10

Ho visto questa domanda PHP - Get number of pages in a Word document. Devo anche determinare il conteggio delle pagine da un determinato file di parole (doc/docx). Ho provato a indagare su phplivedocx/ZF (@hobodave collegato a quelli nelle risposte originali), ma ho perso le mie mani e le mie gambe lì. Non posso usare nessun servizio web esterno (come i siti DOC2PDF e poi contare le pagine nella versione PDF, o giù di lì ...).Come ottenere il numero di pagine in un documento di Word su linux?

Semplicemente: C'è qualche codice PHP (usando ZF o qualsiasi altra cosa in PHP, escluso oggetto COM o altri esecuzione-files, come ad esempio 'AbiWord'; sto usando server Linux condiviso, senza exec o funzione simile) , per trovare il numero di pagine del file word?

EDIT: versioni di Word che sta per essere supportati sono Microsoft-Word 2003 & 2007.

+1

A quale standard di file in formato di un file msword si riferisce? Si prega di aggiungere le specifiche se si desidera ottenere risposte specifiche. – hakre

risposta

17

Ottenere il numero di pagine per file docx è molto semplice:

function get_num_pages_docx($filename) 
{ 
    $zip = new ZipArchive(); 

    if($zip->open($filename) === true) 
    { 
     if(($index = $zip->locateName('docProps/app.xml')) !== false) 
     { 
      $data = $zip->getFromIndex($index); 
      $zip->close(); 

      $xml = new SimpleXMLElement($data); 
      return $xml->Pages; 
     } 

     $zip->close(); 
    } 

    return false; 
} 

Per 97-2003 formato è certamente impegnativo, ma affatto impossibile. Il numero di pagine è archiviato nella sezione SummaryInformation del documento, ma a causa del formato OLE dei file che lo rende difficile da trovare. La struttura è definita in modo estremamente accurato (anche se in cattive condizioni) here e più semplice here. L'ho guardato per un'ora oggi, ma non sono andato molto lontano! (Non un livello di astrazione ci sono abituato), ma la produzione l'esagono per comprendere meglio la struttura:

function get_num_pages_doc($filename) 
{ 
    $handle = fopen($filename, 'r'); 
    $line = @fread($handle, filesize($filename)); 

    echo '<div style="font-family: courier new;">'; 

     $hex = bin2hex($line); 
     $hex_array = str_split($hex, 4); 
     $i = 0; 
     $line = 0; 
     $collection = ''; 
     foreach($hex_array as $key => $string) 
     { 
      $collection .= hex_ascii($string); 
      $i++; 

      if($i == 1) 
      { 
       echo '<b>'.sprintf('%05X', $line).'0:</b> '; 
      } 

      echo strtoupper($string).' '; 

      if($i == 8) 
      { 
       echo ' '.$collection.' <br />'."\n"; 
       $collection = ''; 
       $i = 0; 

       $line += 1; 
      } 
     } 

    echo '</div>'; 

    exit(); 
} 

function hex_ascii($string, $html_safe = true) 
{ 
    $return = ''; 

    $conv = array($string); 
    if(strlen($string) > 2) 
    { 
     $conv = str_split($string, 2); 
    } 

    foreach($conv as $string) 
    { 
     $num = hexdec($string); 

     $ascii = '.'; 
     if($num > 32) 
     { 
      $ascii = unichr($num); 
     } 

     if($html_safe AND ($num == 62 OR $num == 60)) 
     { 
      $return .= htmlentities($ascii); 
     } 
     else 
     { 
      $return .= $ascii; 
     } 
    } 

    return $return; 
} 

function unichr($intval) 
{ 
    return mb_convert_encoding(pack('n', $intval), 'UTF-8', 'UTF-16BE'); 
} 

che fuori ha messo il codice dove si possono trovare sezioni come:

007000: 0500 5300 7500 6D00 6D00 6100 7200 7900 ..S.u.m.m.a.r.y. 
007010: 4900 6E00 6600 6F00 7200 6D00 6100 7400 I.n.f.o.r.m.a.t. 
007020: 6900 6F00 6E00 0000 0000 0000 0000 0000 i.o.n........... 
007030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 

che vi permetterà di vedere le informazioni riferimento come ad esempio:

007040: 2800 0201 FFFF FFFF FFFF FFFF FFFF FFFF (...ÿÿÿÿÿÿÿÿÿÿÿÿ 
007050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
007060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
007070: 0000 0000 2500 0000 0010 0000 0000 0000 ....%........... 

che vi permetterà di determinare le proprietà descritte:

_ab = ("SummaryInformation") 
_cb = 0028 
_mse = 02 (STGTY_STREAM) 
_bflags = 01 (DE_BLACK) 
_sidLeftSib = FFFF FFFF 
_sidRightSib = FFFF FFFF (none) 
_sidChild = FFFF FFFF (n/a for STGTY_STREAM) 
_clsid = 0000 0000 0000 0000 0000 0000 0000 0000 (n/a) 
_dwUserFlags = 0000 0000 (n/a) 
_time[0] = CreateTime = 0000 0000 0000 0000 (n/a) 
_time[1] = ModifyTime = 0000 0000 0000 0000 (n/a) 
_startSect = 0000 0000 
_ulSize = 0000 1000 
_dptPropType = 0000 (n/a) 

Che consente di trovare la sezione di codice pertinente, decomprimerlo e ottenere il numero di pagina. Ovviamente questo è il momento difficile per il quale non ho tempo, ma dovrei indirizzarti nella giusta direzione.

M $ non è facile!

+0

Meraviglioso! È davvero una cosa eccellente. Spero di riuscire a completare il divario. –

+0

I collegamenti del documento di specifica sono morti: Altre posizioni - [Formato file binario composto] (http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/WindowsCompoundBinaryFileFormatSpecification.pdf) e [Specifica del formato di file binario di Microsoft Office Word 97-2007 (.doc)] (http://www.digitalpreservation.gov/formats/digformatspecs/Word97-2007BinaryFileFormat (doc) Specification.pdf). – Orbling

+0

Il conteggio delle pagine si trova a pagina 120 di quel documento: la specifica è memorizzata nelle Proprietà del documento (tag: 'DOP') - all'offset 46 (x2E), un' int' (2 byte), il nome della proprietà è 'cPg' - riflette l'ultimo conteggio calcolato. Quindi la procedura è trovare DOP nella tabella dei file, quindi prendere un intero dal byte 42 di quella tabella. – Orbling

-1

Escludendo utilizzando Abiword o OpenOffice? Impossibile: il numero di pagine dipenderà dal numero di parole/lettere, caratteri utilizzati, giustificazione e crenatura, dimensione del margine, spaziatura tra i paragrafi, spaziatura del paragrafo, numero di paragrafi, colonne, dimensioni della grafica/oggetti incorporati, interruzioni di pagina/colonna e margini della pagina .

Hai bisogno di qualcosa che possa comprendere tutto questo.

Anche se si utilizza OpenOffice o Abiword, il rendering del testo può modificare il numero di pagine. Infatti, in alcuni casi l'apertura dello stesso documento su una diversa istanza di MSWord può comportare una differenza.

Il meglio che potresti gestire sarebbe un approccio statistico basato su una rappresentazione del documento, ma vedrai comunque un'enorme varianza.

+1

Ho aperto 7zip con entrambi i file 2003 (.doc) e file 2007 (.docx). Nei file estratti 2007 ho trovato il file XML (docProps/app.xml) che include esplicitamente il numero di pagine (''). Nel 2003 non ho trovato un XML, ma alcuni altri file, ma in Esplora risorse è possibile visualizzare le Proprietà del file, nella scheda Riepilogo, nella parte Avanzata e vedere il numero di pagine. Non posso testarlo ora, ma credo che questi dati non siano calcolati al volo, ma incapsulati in qualche modo, esplicitamente, nel file Word combinato. In realtà, questo numero è esattamente quello di cui ho bisogno. –

+0

il mio nome docx è UTF8 ma zipArchive presenta problemi per l'apertura di questo DOCX. https://stackoverflow.com/questions/45154025/php-ziparchive-dont-support-utf8-files-for-open?noredirect=1#comment77280333_45154025 – user3770797

3

Dai un'occhiata a PhpWord da microsoft codeplex ..."http://phpword.codeplex.com/

Essa vi permetterà di aprire e leggere la parola file formattato in PHP e fare tutto ciò che l'elaborazione si richiede.

+0

Non pensare che gestisca i vecchi formati di parole senza un pacchetto di compatibilità, che non posso forzare gli utenti, quindi è tristemente inutile qui ... –

2

ottenere le proprietà di meta-dati di doc, docx, ppt e pptx come il numero di pagine, il numero di di diapositive utilizzando PHP ho seguito il seguente processo e ha funzionato fascino piaciuto e iam così felice, al di sotto è il processo ho seguito, spero che aiuta qualcuno

Download and configure Apache Tika. 

una volta il suo fare si potrebbe provare a eseguire la seguente commadn darà tutti i metadati sul tuo file

java -jar tika-app-1.5.jar -m test.docx 
java -jar tika-app-1.5.jar -m test.doc 
java -jar tika-app-1.5.jar -m test.pptx 
java -jar tika-app-1.5.jar -m test.ppt 

una volta testato è possibile eseguire questo comando in script PHP. Grazie.

Problemi correlati