Web

Чтение/запись файла MS Word на PHP

Можно ли читать и записывать файлы Word (2003 и 2007) на PHP без использования COM-объекта? Я знаю, что можно сделать так:

$file = fopen('c:\file.doc', 'w+');

fwrite($file, $text);

fclose();

но Word будет читать его как HTML-файл, а не как собственный файл .doc.

 

Ответ 1

Чтение двоичных документов Word потребовало бы создания анализатора в соответствии с опубликованными спецификациями формата файлов DOC. Я думаю, что это не является реально выполнимым решением. Вы можете использовать форматы Microsoft Office XML для чтения и записи файлов Word они совместимы с версиями Word 2003 и 2007. Для чтения необходимо убедиться, что документы Word сохранены в правильном формате (он называется Word 2003 XML-Document в Word 2007). Для записи достаточно следовать общедоступной XML-схеме. Я никогда не использовал этот формат для записи документов Office из PHP, но я использую его для чтения рабочего листа Excel (естественно, сохраненного как XML-Spreadsheet 2003) и отображения его данных на веб-странице. Поскольку файлы представляют собой обычные XML-данные, не составляет труда сориентироваться в них и понять, как извлечь нужные данные. Другой вариант вариант только для Word 2007 (если форматы файлов OpenXML не установлены в вашем Word 2003) это пересортировка в OpenXML. Формат файла DOCX это просто ZIP-архив с включенными XML-файлами. На MSDN есть много ресурсов по формату файлов OpenXML, так что вы должны быть в состоянии понять, как читать нужные вам данные. Запись будет намного сложнее, я думаю, все зависит от того, сколько времени вы потратите на это. Возможно, вы можете взглянуть на PHPExcel библиотеку, способную писать в файлы Excel 2007 и читать из файлов Excel 2007, используя стандарт OpenXML. Вы можете получить представление о работе, связанной с чтением и записью документов OpenXML Word.

 

Ответ 2

Данное решение работает с vs < office 2007, и это чистый PHP без всякого COM:

<?php

 /*****************************************************************

Этот подход использует обнаружение NUL (chr(00)) и конца строки (chr(13))

чтобы определить, где находится текст:

- разделяем содержимое файла на фрагменты по chr(13)

- отбрасываем все фрагменты, содержащие NUL

- сшиваем оставшиеся вместе

- очищаем с помощью регулярного выражения

*****************************************************************/

 

function parseWord($userDoc)  {

    $fileHandle = fopen($userDoc, "r");

    $line = @fread($fileHandle, filesize($userDoc));   

    $lines = explode(chr(0x0D),$line);

    $outtext = "";

    foreach($lines as $thisline) {

        $pos = strpos($thisline, chr(0x00));

        if (($pos !== FALSE)||(strlen($thisline)==0)) {

          } else {

            $outtext .= $thisline." ";

          }

      }

     $outtext = preg_replace("/[^a-zA-Z0-9\s\,\.\-\n\r\t@\/\_\(\)]/","",$outtext);

    return $outtext;

$userDoc = "cv.doc";

$text = parseWord($userDoc);

echo $text;

?>

 

Ответ 3

Просто обновляем код из предыдущего ответа:

<?php

 /*****************************************************************

Этот подход использует обнаружение NUL (chr(00)) и конца строки (chr(13))

чтобы определить, где находится текст:

- разделяем содержимое файла на фрагменты по chr(13)

- отбрасываем все фрагменты, содержащие NUL

- сшиваем оставшиеся вместе

- очищаем с помощью регулярного выражения

*****************************************************************/

 

function parseWord($userDoc)  {

    $fileHandle = fopen($userDoc, "r");

    $word_text = @fread($fileHandle, filesize($userDoc));

    $line = "";

    $tam = filesize($userDoc);

    $nulos = 0;

    $caracteres = 0;

    for($i=1536; $i<$tam; $i++) {

        $line .= $word_text[$i];

        if( $word_text[$i] == 0) {

            $nulos++;

        } else {

            $nulos=0;

            $caracteres++;

        }

        if( $nulos>1996)

        {   

            break;  

        }

    }

    //echo $caracteres;

    $lines = explode(chr(0x0D),$line);

    //$outtext = "<pre>";

    $outtext = "";

    foreach($lines as $thisline) {

        $tam = strlen($thisline);

        if( !$tam ) {

            continue;

        }

        $new_line = ""; 

        for($i=0; $i<$tam; $i++) {

            $onechar = $thisline[$i];

            if( $onechar > chr(240) ) {

                continue;

            }

            if( $onechar >= chr(0x20) ) {

                $caracteres++;

                $new_line .= $onechar;

            }

            if( $onechar == chr(0x14) ) {

                $new_line .= "</a>";

            }

            if( $onechar == chr(0x07) ) {

                $new_line .= "\t";

                if( isset($thisline[$i+1]) ) {

                    if( $thisline[$i+1] == chr(0x07) ) {

                        $new_line .= "\n";

                    }

                }

            }

        }

        //troca por hiperlink

        $new_line = str_replace("HYPERLINK" ,"<a href=",$new_line); 

        $new_line = str_replace("\o" ,">",$new_line); 

        $new_line .= "\n";

        //link de imagens

        $new_line = str_replace("INCLUDEPICTURE" ,"<br><img src=",$new_line); 

        $new_line = str_replace("\*" ,"><br>",$new_line); 

        $new_line = str_replace("MERGEFORMATINET" ,"",$new_line); 

        $outtext .= nl2br($new_line);

    }

    return $outtext;

$userDoc = "custo.doc";

$userDoc = "Cultura.doc";

$text = parseWord($userDoc);

echo $text;

?>

 

Ответ 4

www.phplivedocx.org это сервис на основе SOAP, который выполняет онлайн-тестирование файлов. Файлы также имеют достаточно примеров для его использования. Я думаю, что без COM это просто невозможно на Linux-сервере, и единственная идея изменить doc файл в другой файл, который PHP может разобрать...

 

Ответ 5

Используя Open XML SDK и VSTO [Visual Studio Tools For Office], мы можем легко работать с файлами Word, манипулировать ими и даже конвертировать внутри в различные форматы, такие как .odt,.pdf,.docx и т. д. Итак, зайдите на сайт msdn.microsoft.com и внимательно изучите вкладку office development. Это самый простой способ сделать это, так как все функции, которые нам нужно реализовать, уже доступны в .net!!! Но так как вы хотите сделать свой проект на PHP, вы можете сделать это в Visual Studio и .net, потому как PHP также является одним из .net Compliant Language!!!

 

Ответ 6

Используйте следующий класс непосредственно для чтения документа Word:

class DocxConversion{

    private $filename;

    public function __construct($filePath) {

        $this->filename = $filePath;

    }

    private function read_doc() {

        $fileHandle = fopen($this->filename, "r");

        $line = @fread($fileHandle, filesize($this->filename));   

        $lines = explode(chr(0x0D),$line);

        $outtext = "";

        foreach($lines as $thisline) {

            $pos = strpos($thisline, chr(0x00));

            if (($pos !== FALSE)||(strlen($thisline)==0)) {

              } else {

                $outtext .= $thisline." ";

              }

          }

         $outtext = preg_replace("/[^a-zA-Z0-9\s\,\.\-\n\r\t@\/\_\(\)]/","",$outtext);

        return $outtext;

    }

    private function read_docx(){

        $striped_content = '';

        $content = '';

        $zip = zip_open($this->filename);

        if (!$zip || is_numeric($zip)) return false;

        while ($zip_entry = zip_read($zip)) {

            if (zip_entry_open($zip, $zip_entry) == FALSE) continue;

            if (zip_entry_name($zip_entry) != "word/document.xml") continue;

            $content .= zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));

            zip_entry_close($zip_entry);

        }// end while

        zip_close($zip);

        $content = str_replace('</w:r></w:p></w:tc><w:tc>', " ", $content);

        $content = str_replace('</w:r></w:p>', "\r\n", $content);

        $striped_content = strip_tags($content);

 

        return $striped_content;

    }

 

 /************************excel sheet************************************/

 

function xlsx_to_text($input_file){

    $xml_filename = "xl/sharedStrings.xml"; //content file name

    $zip_handle = new ZipArchive;

    $output_text = "";

    if(true === $zip_handle->open($input_file)){

        if(($xml_index = $zip_handle->locateName($xml_filename)) !== false){

            $xml_datas = $zip_handle->getFromIndex($xml_index);

            $xml_handle = DOMDocument::loadXML($xml_datas, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);

            $output_text = strip_tags($xml_handle->saveXML());

        }else{

            $output_text .="";

        }

        $zip_handle->close();

    }else{

    $output_text .="";

    }

    return $output_text;

}

 

/*************************power point files*****************************/

function pptx_to_text($input_file){

    $zip_handle = new ZipArchive;

    $output_text = "";

    if(true === $zip_handle->open($input_file)){

        $slide_number = 1; //loop through slide files

        while(($xml_index = $zip_handle->locateName("ppt/slides/slide".$slide_number.".xml")) !== false){

            $xml_datas = $zip_handle->getFromIndex($xml_index);

            $xml_handle = DOMDocument::loadXML($xml_datas, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);

            $output_text .= strip_tags($xml_handle->saveXML());

            $slide_number++;

        }

        if($slide_number == 1){

            $output_text .="";

        }

        $zip_handle->close();

    }else{

    $output_text .="";

    }

    return $output_text;

}

 

    public function convertToText() {

       if(isset($this->filename) && !file_exists($this->filename)) {

            return "File Not exists";

        }

        $fileArray = pathinfo($this->filename);

        $file_ext  = $fileArray['extension'];

        if($file_ext == "doc" || $file_ext == "docx" || $file_ext == "xlsx" || $file_ext == "pptx") {

            if($file_ext == "doc") {

                return $this->read_doc();

            } elseif($file_ext == "docx") {

                return $this->read_docx();

            } elseif($file_ext == "xlsx") {

                return $this->xlsx_to_text();

            }elseif($file_ext == "pptx") {

                return $this->pptx_to_text();

            }

        } else {

            return "Invalid File Type";

        }

    }

}

$docObj = new DocxConversion("test.docx"); //замените имя документа правильным расширением doc или docx

echo $docText= $docObj->convertToText();

 

Схожие статьи

Web

Что с точки зрения непрофессионала, является рекурсивной функцией в PHP

Web

Как и где устанавливается $ _SERVER ['APP_DEBUG'] в Symfony >= 5.1?

Web

Как получить значения функции при вводе значения из PHP формы?

Web

Как получить информацию об операционной системе посетителя сайта