2012-01-24 19 views
10

Widziałem to pytanie PHP - Get number of pages in a Word document. Muszę również określić liczbę stron z danego pliku tekstowego (doc/docx). Próbowałem zbadać phplivedocx/ZF (@hobodave połączone z tymi w oryginalnych odpowiedziach), ale straciłem tam ręce i nogi. Nie mogę też korzystać z żadnej zewnętrznej usługi internetowej (np. Witryn DOC2PDF, a następnie liczyć strony w wersji PDF, lub tak ...).Jak uzyskać liczbę stron w dokumencie Word na Linuksie?

prostu: Czy jest jakiś kod PHP (przy użyciu ZF lub cokolwiek innego w PHP, wyłączeniem obiekt COM lub inne wykonanie-plików, na przykład „AbiWord”; używam udostępnionego serwera Linux, bez exec lub podobnej funkcji) , aby znaleźć liczbę stron w pliku tekstowym?

EDIT: Wersje słowo, które ma być wspierane przez Microsoft programu Word 2003 & 2007.

+1

Do jakiego standardu plików pliku msword się odwołujesz? Dodaj specyfikację, jeśli chcesz uzyskać konkretne odpowiedzi. – hakre

Odpowiedz

17

Uzyskiwanie liczbę stron dla plików docx jest bardzo proste:

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

Dla 97-2003 Format to z pewnością trudne, ale nie oznacza niemożliwe. Liczba stron jest przechowywana w sekcji SummaryInformation dokumentu, ale ze względu na format plików OLE sprawia, że ​​znalezienie go jest trudne. Struktura jest zdefiniowana bardzo dokładnie (choć źle imo) here i prostsza here. Spoglądałem na to dzisiaj przez godzinę, ale nie dotarłem zbyt daleko! (Nie jest to poziom abstrakcji jestem przyzwyczajony), ale wyjście hex, aby lepiej zrozumieć strukturę:

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

który będzie się umieścić kod, gdzie można znaleźć sekcje takie jak:

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

który pozwoli Ci zobaczyć powoływanie informacji takich jak:

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

co pozwoli na określenie właściwości opisane:

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

Która pozwoli ci znaleźć odpowiednią sekcję kodu, rozpakuj ją i uzyskaj numer strony. Oczywiście jest to trudny moment, na który po prostu nie mam czasu, ale powinienem skierować cię we właściwym kierunku.

M $ nie ułatwiają!

+0

Cudownie! To naprawdę wspaniała rzecz. Mam nadzieję, że sukces uzupełnię lukę. –

+0

Łącza do dokumentów specyfikacji są martwe: Inne lokalizacje - [Format pliku binarnego złożonego] (http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/WindowsCompoundBinaryFileFormatSpecification.pdf) i [Microsoft Office Word 97-2007 Format pliku binarnego (.doc) Specyfikacja] (http://www.digitalpreservation.gov/formats/digformatspecs/Word97-2007BinaryFileFormat (doc) Specification.pdf). – Orbling

+0

Liczba stron znajduje się na stronie 120 tego dokumentu - specyfikacja, jest przechowywana we Właściwościach dokumentu (tag: 'DOP') - przy przesunięciu 46 (x2E), właściwość' int' (2 bajt), nazwa właściwości to 'cPg' - odzwierciedla ostatnią obliczoną liczbę. Tak więc procedura znajduje DOP w tabeli plików, a następnie pobiera liczbę całkowitą z bajtu 42 tej tabeli. – Orbling

-1

Bez korzystania Abiword czy OpenOffice? Niemożliwe - liczba stron zależy od liczby słów/liter, użytych czcionek, uzasadnienia i kerningu, rozmiaru marginesów, odstępów między wierszami, odstępów między akapitami, liczby akapitów, kolumn, rozmiaru grafiki/osadzonych obiektów, podziałów strony/kolumny i marginesów strony .

Potrzebujesz czegoś, co może je zrozumieć.

Nawet jeśli używasz OpenOffice lub Abiword, zmiana tekstu może zmienić liczbę stron. Rzeczywiście, w niektórych przypadkach otwarcie tego samego dokumentu na innym wystąpieniu MSWord może spowodować różnicę.

Najlepszą rzeczą, jaką można by było poradzić, byłoby podejście statystyczne oparte na reprezentacji dokumentu - ale nadal widać ogromną różnicę.

+1

Otworzyłem 7zip zarówno plik 2003 (.doc) i 2007 (.docx). W wyodrębnionych plikach w 2007 znalazłem plik XML (docProps/app.xml), który zawiera jawnie liczbę stron (''). W 2003 roku nie znalazłem XML-a, ale niektóre inne pliki, ale w Eksploratorze Windows możesz spojrzeć na Właściwości pliku, na karcie Podsumowanie, w części Zaawansowane i zobaczyć liczbę stron. Nie mogę tego teraz przetestować, ale uważam, że te dane nie są obliczane w locie, ale w jakiś sposób jawnie, w połączonym pliku Worda. Właściwie to właśnie ta liczba jest mi potrzebna. –

+0

moja nazwa docx to UTF8, ale zipArchive ma problem z otwarciem tego DOCXa. https://stackoverflow.com/questions/45154025/php-ziparchive-dont-support-utf8-files-for-open?noredirect=1#comment77280333_45154025 – user3770797

3

Zobacz PhpWord z Microsoft Codeplex ..."http://phpword.codeplex.com/

Pozwoli to otworzyć i odczytać słowa sformatowany plik w PHP i zrobić cokolwiek przetwarzanie potrzebują.

+0

Nie myśl, że obsługuje on stare formaty słowne bez pakietu kompatybilności, który nie może wymuszać na użytkownikach, więc jest to bezużyteczne tutaj ... –

2

Aby uzyskać właściwości Meta danych z doc, docx, ppt i pptx jak liczba stron, liczba slajdów z wykorzystaniem PHP i następnie następujący proces i to działało podobało urok i iam tak szczęśliwy, poniżej jest procesem śledziłem, nadzieję, że pomoże ktoś

Download and configure Apache Tika. 

raz jej zrobić można spróbować wykonywania następujących commadn da wszystkie metadane dotyczące pliku

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 

Po przetestowaniu można wykonać ten komand w skrypcie PHP. Dzięki.

Powiązane problemy