2012-01-24 28 views
10

Vi esta pregunta PHP - Get number of pages in a Word document. También necesito determinar el número de páginas del archivo de palabras dado (doc/docx). Traté de investigar phplivedocx/ZF (@hobodave vinculado a aquellos en las respuestas de la publicación original), pero perdí las manos y las piernas allí. No puedo usar ningún servicio web externo (como sitios DOC2PDF, y luego contar las páginas en la versión PDF, más o menos ...).¿Cómo obtener el número de páginas en un documento de Word en Linux?

Simplemente: ¿Hay algún código PHP (usando ZF o cualquier otra cosa en PHP, excluyendo objeto COM u otros archivos de ejecución, tales 'AbiWord'; estoy usando Linux servidor compartido, sin exec o función similar) , para encontrar el conteo de páginas del archivo de palabras?

EDIT: Las versiones de Word que a punto de ser soportados son Microsoft-Word 2003 & 2007.

+1

¿A qué estándar (s) de formato de archivo se está refiriendo? Por favor, agregue la especificación si desea obtener respuestas específicas. – hakre

Respuesta

17

Conseguir el número de páginas de archivos docx es muy fácil:

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

Por 97-2003 es ciertamente difícil, pero no imposible. El número de páginas se almacena en la sección Información resumida del documento, pero debido al formato OLE de los archivos es difícil de encontrar. La estructura se define extremadamente a fondo (aunque muy mal) here y más simple here. Lo miré durante una hora hoy, ¡pero no llegué muy lejos! (No es un nivel de abstracción que estoy acostumbrado a), pero la producción de la hexagonal para entender mejor la estructura:

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

que salir código en el que se encuentran las secciones tales como poner:

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 ................ 

que le permitirá ver la información hace referencia tales como:

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 ....%........... 

que le permitirá determinar las propiedades descritas:

_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) 

Lo que le permitirá encontrar la sección relevante del código, descomprimirlo y obtener el número de página. Por supuesto, esta es la parte difícil para la que simplemente no tengo tiempo, pero debería orientarte en la dirección correcta.

M $ no lo hacen fácil!

+0

¡Maravilloso! Es realmente excelente. Espero que tenga éxito para completar la brecha. –

+0

Los enlaces del documento de especificación están muertos: otras ubicaciones: [Formato binario del archivo compuesto] (http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/WindowsCompoundBinaryFileFormatSpecification.pdf) y [Microsoft Office Word 97-2007 formato de archivo binario (.doc) especificación] (http://www.digitalpreservation.gov/formats/digformatspecs/Word97-2007BinaryFileFormat (doc) Specification.pdf). – Orbling

+0

El recuento de páginas está en la página 120 de ese documento; la especificación, se almacena en las Propiedades del documento (etiqueta: 'DOP') - en el desplazamiento 46 (x2E),' int' (2 bytes), el nombre de propiedad es 'cPg' - refleja el último recuento calculado. Entonces el procedimiento es encontrar DOP en la tabla de archivos, luego tomar un entero del byte 42 de esa tabla. – Orbling

-1

Excluyendo el uso de Abiword o OpenOffice? Imposible: el número de páginas dependerá del número de palabras/letras, fuentes utilizadas, justificación y interletraje, tamaño del margen, espaciado entre líneas, espaciado entre párrafos, cantidad de párrafos, columnas, tamaño de gráficos/objetos incrustados, saltos de página/columna y márgenes de página .

Necesita algo que pueda comprender todo esto.

Incluso si usa OpenOffice o Abiword, si vuelve a utilizar el texto puede cambiar el número de páginas. De hecho, en algunos casos, abrir el mismo documento en una instancia diferente de MSWord puede generar una diferencia.

Lo mejor que probablemente podría administrar sería un enfoque estadístico basado en una representación del documento, pero aún verá enormes variaciones.

+1

He abierto con 7zip el archivo 2003 (.doc) y el archivo 2007 (.docx). En los archivos extraídos de 2007, encontré el archivo XML (docProps/app.xml) que incluye explícitamente el número de páginas (''). En 2003 no encontré un archivo XML, sino algunos otros archivos, pero en el Explorador de Windows puede mirar las Propiedades del archivo, en la pestaña Resumen, en la parte Avanzada, y ver el número de páginas. No puedo probarlo ahora, pero creo que estos datos no se calculan sobre la marcha, sino que se encapsulan de alguna manera, explícitamente, en el archivo combinado de Word. En realidad, excatlly este número es lo que necesito. –

+0

mi nombre docx es UTF8 pero zipArchive tiene un problema para abrir este DOCX. https://stackoverflow.com/questions/45154025/php-ziparchive-dont-support-utf8-files-for-open?noredirect=1#comment77280333_45154025 – user3770797

3

Eche un vistazo a PhpWord desde microsoft codeplex ..."http://phpword.codeplex.com/

Se le permitirá abrir y leer la palabra archivo con formato en PHP y hacer lo procesamiento que requiere.

+0

No creo que maneje formatos de palabras viejas sin un paquete de compatibilidad, que no puede forzar a los usuarios, por lo que es tristemente inútil aquí ... –

2

Para obtener las propiedades de metadatos de doc, docx, ppt y pptx como el número de páginas, el número de de diapositivas utilizando PHP i seguido el siguiente proceso y funcionó encanto gustado y iam tan feliz, a continuación es el proceso i seguido, espero que ayude a alguien

Download and configure Apache Tika. 

una vez que su hecho usted podría intentar ejecutar el siguiente commadn que dará todos los metadatos sobre su archivo

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 vez probado, puede ejecutar este comando en el script PHP. Gracias.

Cuestiones relacionadas