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

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

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

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

Я считаю крайне маловероятным, что вы могли бы добиться этого без использования COM.

Peter Bailey 09.10.2008 22:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
32
1
130 294
16
Перейти к ответу Данный вопрос помечен как решенный

Ответы 16

Я не знаю, как читать собственные документы Word на PHP, но если вы хотите написать документ Word на PHP, WordprocessingML (он же WordML) может быть хорошим решением. Все, что вам нужно сделать, это создать XML-документ в правильном формате. Я считаю, что Word 2003 и 2007 поддерживают WordML.

Скорее всего, вы не сможете читать документы Word без COM.

Написание было описано в этом тема

Office 2007 .docx должен быть возможен, поскольку это стандарт XML. Word 2003, скорее всего, требует чтения COM, даже с учетом стандартов, которые сейчас публикуются MS, поскольку эти стандарты огромны. Я еще не видел много библиотек, написанных для них.

2007 год тоже может быть немного сложным.

Формат .docx - это zip-файл, который содержит несколько папок с другими файлами для форматирования и прочего.

Переименуйте файл .docx в .zip, и вы поймете, что я имею в виду.

Так что, если вы можете работать с zip-файлами в PHP, вы должны быть на правильном пути.

Я не знаю, для чего вы собираетесь его использовать, но мне нужна была поддержка .doc для индексации поиска; Я использовал небольшой инструмент командной строки под названием «catdoc»; Это переводит содержимое документа Word в обычный текст, чтобы его можно было проиндексировать. Если вам нужно сохранить форматирование и прочее, это не ваш инструмент.

это работает с vs <office 2007 и его чистым PHP, без дерьма COM, все еще пытается вычислить 2007

<?php



/*****************************************************************
This approach uses detection of NUL (chr(00)) and end line (chr(13))
to decide where the text is:
- divide the file contents up by chr(13)
- reject any slices containing a NUL
- stitch the rest together again
- clean up with a regular expression
*****************************************************************/

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;


?>

Не используйте это, если хотите сохранить Umlaute.

Jan Beck 04.05.2012 19:41

Я нашел некоторые специальные символы, которые нельзя проанализировать в этой функции.

Roger Ng 23.07.2013 15:24
Ответ принят как подходящий

Чтение двоичных документов Word потребует создания парсера в соответствии с опубликованными спецификациями формата файла для формата DOC. Я считаю, что это нереально возможное решение.

Вы можете использовать Форматы Microsoft Office XML для чтения и записи файлов Word - это совместимо с версиями Word 2003 и 2007 годов. Для чтения вы должны убедиться, что документы Word сохранены в правильном формате (в Word 2007 он называется XML-документ Word 2003). Для написания вам просто нужно следовать открытой 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.

Кажется, что сотрудники PHPExcel сделали PHPWord для создания текстовых документов.

Basic 22.07.2012 20:45

Подойдет ли формат .rtf для ваших целей? .rtf можно легко преобразовать в формат .doc и из него, но он записывается в виде обычного текста (со встроенными управляющими командами). Вот как я планирую интегрировать свое приложение с документами Word.

Обстоятельства не имеют значения, вопрос был в том, возможно ли это, но спасибо.

UnkwnTech 24.01.2009 14:54

phpLiveDocx - это компонент Zend Framework, который может читать и записывать файлы DOC и DOCX в PHP в Linux, Windows и Mac.

См. Веб-сайт проекта по адресу:

http://www.phplivedocx.org

Ссылка ссылка мертва

Zameer Khan 19.03.2017 16:00

Вы можете использовать Antiword, это бесплатная программа для чтения MS Word для Linux и самой популярной ОС.

$document_file = 'c:\file.doc';
$text_from_doc = shell_exec('/usr/local/bin/antiword '.$document_file);

Проблема с этим типом решения заключается в том, что он предполагает, что на сервере можно установить программное обеспечение.

UnkwnTech 24.05.2009 11:42

Немного долго, но поправьте меня, если я ошибаюсь. C:\file.doc - это каталог Windows, а /usr/local/bin - это каталог Linux / Unix?

Daryl Gill 04.04.2013 04:54

@UnkwnTech: если программе не требуются повышенные права доступа, большинство программ можно установить в любой каталог, в который у вас есть разрешение на запись. Затем вы можете использовать полный путь для ссылки на программу или добавить каталог установки в свою переменную PATH.

Lie Ryan 05.01.2014 08:14

@LieRyan, вы упустили суть, если вы запускаете это в среде общего хостинга, вы чаще всего не можете установить какое-либо программное обеспечение независимо от каталога.

UnkwnTech 07.01.2014 04:23

@UnkwnTech: под установкой я имел в виду просто скопировать его в любой каталог, в котором у вас есть разрешение на запись, и установить бит выполнения. Это работает в любой среде общего хостинга, которая дает вам доступ по ssh или, по крайней мере, возможность выполнять сценарии (то есть единственная среда, в которой это не сработает, - это хостинг только для статических файлов, но тогда вы все равно не будете говорить о PHP). Если у вас есть только ftp-доступ и нет ssh, это все еще возможно, хотя вам может потребоваться написать несколько PHP-скриптов для установки бита выполнения.

Lie Ryan 07.01.2014 11:03

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

даже я работаю над таким же проектом [текстовый процессор Onlinw]! Но я выбрал C# .net и ASP.net. Но через опрос я сделал; я должен знать это

By Using Open XML SDK and VSTO [Visual Studio Tools For Office]

мы можем легко работать с текстовыми файлами, манипулировать ими и даже внутренне преобразовывать их в различные форматы, такие как .odt, .pdf, .docx и т. д.

So, goto msdn.microsoft.com and be thorough about the office development tab. Its the easiest way to do this as all functions we need to implement are already available in .net!!

Но поскольку вы хотите сделать свой проект на PHP, вы можете сделать это в Visual Studio и .net, поскольку PHP также является одним из языков, совместимых с .net !!

У меня такой же случай Думаю, я собираюсь использовать дешевый 50-мегапиксельный хостинг на базе Windows с бесплатным доменом, чтобы использовать его для преобразования моих файлов на PHP-сервере. И связать их легко. Все, что вам нужно, это создать страницу ASP.NET, которая получает файл документа по почте и отвечает на него через HTTP. такой простой CURL сделает это.

Похоже, в конце концов, это единственный способ сделать это. Вы можете предоставить более подробную информацию? Я имею в виду, должен ли я пойти и купить хостинг Windows и использовать его для запуска кода PHP (который использует библиотеку COM) для создания файла .doc / x?

Dewan159 03.07.2012 20:30

Просто обновляю код

<?php

/*****************************************************************
This approach uses detection of NUL (chr(00)) and end line (chr(13))
to decide where the text is:
- divide the file contents up by chr(13)
- reject any slices containing a NUL
- stitch the rest together again
- clean up with a regular expression
*****************************************************************/

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;


?>

Хотя это интересно, при этом не удалось найти начало документа Word97 и отрезать документ. Я обнаружил, что это числа 1536 и 1996, которые следует определять путем синтаксического анализа, а не произвольного жесткого кодирования. Кроме того, были удалены специальные символы, такие как умные кавычки, многоточие, длинное тире и специальные одинарные кавычки, и я увидел много амперсандов во всем выводе. Итак, это интересное начало, но оно требует большой доработки.

Volomike 11.08.2011 20:51

Вы также можете обратиться к этому руководству о том, как преобразовать специальные символы MS Word: toao.net/48-replacing-smart-quotes-and-em-dashes-in-mysql

Volomike 11.08.2011 20:52

функция выдает странные символы: "Œ’ÛJA † ïßaÈ} 7Û" ÒÙÞH¡w "ë„ ™ ìw̤ھ½ ... "

Yoong Kim 16.07.2012 14:04

@Volomike измените $nulus на большее число, чтобы избежать разрыва.

Peyman 03.08.2017 18:19

Один из способов управления файлами Word с помощью PHP, который может вас заинтересовать, - это PHPDocX. Вы можете увидеть, как это работает, взглянув на его онлайн-учебник. Вы можете вставлять или извлекать содержимое или даже объединять несколько файлов Word в один.

Источник получен из

Use following class directly to read word document

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"); //replace your document name with correct extension doc or docx 
echo $docText= $docObj->convertToText();

Другие вопросы по теме