Можно ли читать и записывать файлы 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