За последние 24 часа нас посетили 20307 программистов и 1192 робота. Сейчас ищут 807 программистов ...

Помогите прочитать DOC

Тема в разделе "PHP для профи", создана пользователем Sergey_k6, 5 апр 2024.

  1. Sergey_k6

    Sergey_k6 Новичок

    С нами с:
    28 май 2022
    Сообщения:
    32
    Симпатии:
    0
    Коллеги добрый день.
    Помогите решить проблему с чтением DOC файлов.
    Именно DOC а не DOCX (некоторые путаю) ну то есть это не архив XML
    Вот код который я использую:
    Код (Text):
    1.  
    2. function read_doc_file($filename) {
    3.   if (file_exists($filename)) {
    4.   if (($fh = fopen($filename, 'r')) !== false) {
    5.   $headers = fread($fh, 0xA00);
    6.  
    7.   // 1 = (ord(n)*1) ; Document has from 0 to 255 characters
    8.   $n1 = ( ord($headers[0x21C]) - 1 );
    9.  
    10.   // 1 = ((ord(n)-8)*256) ; Document has from 256 to 63743 characters
    11.   $n2 = ( ( ord($headers[0x21D]) - 8 ) * 256 );
    12.  
    13.   // 1 = ((ord(n)*256)*256) ; Document has from 63744 to 16775423 characters
    14.   $n3 = ( ( ord($headers[0x21E]) * 256 ) * 256 );
    15.  
    16.   // 1 = (((ord(n)*256)*256)*256) ; Document has from 16775424 to 4294965504 characters
    17.   $n4 = ( ( ( ord($headers[0x21F]) * 256 ) * 256 ) * 256 );
    18.  
    19.   // Total length of text in the document
    20.   $textLength = ($n1 + $n2 + $n3 + $n4);
    21.  
    22.   $extracted_plaintext = fread($fh, $textLength);
    23.   $extracted_plaintext = mb_convert_encoding( $extracted_plaintext, 'UTF-8', 'UTF-16LE' );
    24.   return nl2br($extracted_plaintext);
    25.   fclose($fh);
    26.   } else {
    27.   return FALSE;
    28.   }
    29.   } else {
    30.   return FALSE;
    31.   }
    32.   }
    33.  
    34.   $text = read_doc_file($filename_doc);
    35.   $text = str_replace('<', "&lt;", $text);
    36.   $text = str_replace('>', "&gt;", $text);
    37.   echo "\$extracted_plaintext => ".$text."<br><br><br><br>";
    Он работает, но иногда попадаются козявки и кубики, и при этом из разметки остался только тег переноса строки <br />

    Мне бы хотелось бы обработать документ с разбором и анализом содержания таблиц.
    Для этого нужны теги, но я не совсем могу правильно понимать, так как документации по DOC у меня нет.
    Думал использовать PHPword
    Но во первых у меня версия PHP 5.4
    А во вторых это тяжёлая библиотека которая при массовой обработки документов, будет очень медленно это делать.

    Мне бы всё-таки хотелось справиться базовыми возможностями PHP
    Подскажите пожалуйста кто сталкивался с подобной задачей.

    Я прикрепил файл для тестирования, поправьте расширение в DOC так как сюда нельзя было подцепить иначе.
    Файл начинается с символов РП, то есть это наверное ODG формат.

    Но при этом Zip_ом он не читается.
     

    Вложения:

  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.768
    Симпатии:
    1.322
    Адрес:
    Лень
    ПОисковик начиная с - github ...

    Динозавров не поддерживаем в 2024 году.
     
  3. Sergey_k6

    Sergey_k6 Новичок

    С нами с:
    28 май 2022
    Сообщения:
    32
    Симпатии:
    0
    Хорошо, вы можете показать мастер класс, напишите пожалуйста реализацию на PHP 7 или PHP 8
    Консольный режим ни кто не отменял, поэтому shell_exec() мне в помощь для PHP 7 или 8, которые сделают парсинг и загрузят данные в БД, или в файл, или socket, да куда угодно. Я в любом случае парсиг буду запускать в параллельном режиме через proc_open(). Чтобы ускорить выполнение разбора большого кол-ва документов.

    Так что коллега, просьба напишите решение как вы это видите. Я вам Спасибо скажу :)
    Только, как я выше написал, просьба, не надо мне грузить библиотеку PHPword, так как мочить воробьёв ракетами это через чур! :)
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.768
    Симпатии:
    1.322
    Адрес:
    Лень
    "Мой дом на той стороне реки, но я обойду пешком до конца ее, чем воспользуюсь мостом. (с)"

    Религия "непринятия" лечится временем.
     
  5. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    874
    Симпатии:
    138
    @Sergey_k6, код научился бы на форуме сначала оформлять
     
  6. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    270
    Симпатии:
    52
    Адрес:
    Бавария, Германия
    Добрый день!
    К сожалению, могу помочь только этим
    https://www.loc.gov/preservation/di...97-2007BinaryFileFormat(doc)Specification.pdf
    Удачи!
     
  7. Sergey_k6

    Sergey_k6 Новичок

    С нами с:
    28 май 2022
    Сообщения:
    32
    Симпатии:
    0
    Я так понимаю что PHPword что-то тоже не очень.
    PHP:
    1. $phpWord = new \PhpOffice\PhpWord\PhpWord();
    2.         $docReader = \PhpOffice\PhpWord\IOFactory::createReader('MsDoc');
    3.         $doc = $docReader->load($filename);
    4.        
    5.         foreach ($doc->getSections() as $section) {
    6.             $phpWord->addSection($section);
    7.         }
    8.  
    9.         $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
    10.         $xmlWriter->save($t_file."My_".$n_file.".docx");
    Записывает чистый файл и всё.
    Может кто-то подсказать что не правильно.
    --- Добавлено ---
    Сп
    Спасибо огромное, здесь хоть понятны откуда взять разделители для анализа текста.
     
  8. Sergey_k6

    Sergey_k6 Новичок

    С нами с:
    28 май 2022
    Сообщения:
    32
    Симпатии:
    0
    Попробовал через COM
    Вроде должно работать, но, по не понятным для меня причинам, Open не возвращает объект для дальнейшей работы.

    PHP:
    1. try {
    2.      @com_load_typelib('Word.Application');
    3.      @$word = new COM("word.application") or die("Unable to instantiate Word");
    4.      $word->Visible = 0;
    5.      $word->DisplayAlerts = 0;
    6.    
    7.      $docPath = $filename_utf8_doc;
    8.      $t_file=strrev(substr(strrev($docPath),strpos(strrev($docPath),"/")));
    9.      $n_file=strrev(substr(strrev($docPath),0,strpos(strrev($docPath),"/")));
    10.      $n_file=strrev(substr(strrev($n_file),strpos(strrev($n_file),".")+1));
    11.      $docxPath = $t_file."My_".$n_file.".docx";
    12.    
    13.      echo "\$docPath => ".$docPath."<br>\$docxPath => ".$docxPath."<br>";
    14.    
    15.      $doc = $word->Documents->Open(realpath(to_code($docPath,"utf-8","cp1251")));
    16.    
    17.      if ($doc) {
    18.        $doc->SaveAs(realpath($docxPath), 16); // 16 is the value for saving as DOCX format
    19.        $doc->Close();
    20.      } else {
    21.        die("Unable to open the document.");
    22.      }
    23.    
    24.      $word->Quit();
    25.      unset($word);
    26.    } catch (com_exception $e) {
    27.      echo '<pre>';
    28.      print_r(to_code($e,"cp1251","utf-8"));
    29.      echo '</pre>';
    30.    }