0

Как извлечь текст из файлов .doc, .docx, .xlsx, .pptx с помощью PHP

16

Описание проблемы:

Существует задача, при которой необходимо извлекать текст из загруженных пользователями документов Word для дальнейшего поиска по строкам, например, в резюме. Однако возникает общая проблема: как получить текст, открыть и прочитать загруженный пользователем документ Word. Есть несколько полезных ссылок, но они не решают всю проблему. Нам нужно извлечь текст во время загрузки документа и сохранить его в базе данных, чтобы мы могли легко производить поиск в базе данных.

Как правильно реализовать этот процесс, чтобы избежать сложностей с обработкой документов и обеспечить корректное сохранение текста для последующего поиска?

3 ответ(ов)

0

Вопрос: Как извлечь текст и адреса электронной почты из файлов формата DOC и DOCX с помощью PHP?

Ответ:

Вы можете использовать следующий код для извлечения текста и адресов электронной почты из файлов DOC и DOCX. Вот как это можно сделать:

Для файлов DOC:

$filename = 'your_file.doc';         
if (file_exists($filename)) {        
    if (($fh = fopen($filename, 'r')) !== false) {
        $headers = fread($fh, 0xA00); // Чтение заголовков файла

        // Вычисление длины текста
        $n1 = (ord($headers[0x21C]) - 1);
        $n2 = ((ord($headers[0x21D]) - 8) * 256);
        $n3 = ((ord($headers[0x21E]) * 256) * 256);
        $n4 = (((ord($headers[0x21F]) * 256) * 256) * 256);
        $textLength = ($n1 + $n2 + $n3 + $n4);

        $extracted_plaintext = fread($fh, $textLength); // Извлечение текста

        echo nl2br($extracted_plaintext); // Вывод текста с переносами строк
        print_r(extract_emails_from($extracted_plaintext)); // Извлечение и вывод адресов электронной почты
    }
}

// Функция для извлечения адресов электронной почты
function extract_emails_from($string) {
    preg_match_all("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i", $string, $matches);
    return $matches[0]; // Возвращаем массив найденных email
}

Для файлов DOCX:

$document = 'your_file.docx'; // Название файла

// Функция для извлечения текста
function extracttext($filename) {
    // Проверка расширения файла
    $ext = pathinfo($filename, PATHINFO_EXTENSION);

    // Определение файла данных в зависимости от расширения
    if ($ext == 'docx') {
        $dataFile = "word/document.xml";
    } else {
        $dataFile = "content.xml"; // Для формата ODT
    }

    // Создание нового объекта ZIP архив
    $zip = new ZipArchive;

    // Открытие архивного файла
    if (true === $zip->open($filename)) {
        // Поиск файла данных в архиве
        if (($index = $zip->locateName($dataFile)) !== false) {
            // Чтение файла данных в строку
            $text = $zip->getFromIndex($index);
            // Загрузка XML из строки
            $xml = DOMDocument::loadXML($text, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
            // Удаление тегов форматирования и возврат текста
            return strip_tags($xml->saveXML());
        }
        // Закрытие архивного файла
        $zip->close();
    }

    // В случае ошибки возвращаем сообщение
    return "Файл не найден";
}

echo extracttext($document); // Выводим извлеченный текст

Обратите внимание, что для работы с DOCX файлами используется класс ZipArchive для доступа к содержимому файла в формате ZIP. Убедитесь, что у вас установлен расширение Zip для PHP. Также стоит позаботиться о том, что текст может содержать определенные теги, поэтому используйте strip_tags для очистки.

0

Если вы хотите сохранить пробелы при извлечении текста из документов формата DOCX, а также правильно обрабатывать таблицы (элементы <w:tr> и <w:tc>), используйте следующий код. Он загружает файл с удаленного или локального адреса и работает с содержимым DOCX:

//=========DOCX===========
function extractDocxText($url, $file_name) {
    $docx = get_url($url);
    file_put_contents("tempf.docx", $docx);
    $xml_filename = "word/document.xml"; // имя файла с содержимым
    $zip_handle = new ZipArchive;
    $output_text = "";

    if (true === $zip_handle->open("tempf.docx")) {
        if (($xml_index = $zip_handle->locateName($xml_filename)) !== false) {
            $xml_datas = $zip_handle->getFromIndex($xml_index);
            // Заменяем элементы на соответствующие символы
            $replace_newlines = preg_replace('/<w:p w[0-9-Za-z]+:[a-zA-Z0-9]+="[a-zA-z"0-9 :="]+">/', "\n\r", $xml_datas);
            $replace_tableRows = preg_replace('/<w:tr>/', "\n\r", $replace_newlines);
            $replace_tab = preg_replace('/<w:tab\/>/', "\t", $replace_tableRows);
            $replace_paragraphs = preg_replace('/<\/w:p>/', "\n\r", $replace_tab);
            $replace_other_Tags = strip_tags($replace_paragraphs);
            $output_text = $replace_other_Tags;
        } else {
            $output_text .= "";
        }
        $zip_handle->close();
    } else {
        $output_text .= " ";
    }

    chmod("tempf.docx", 0777);
    unlink(realpath("tempf.docx"));
    
    // Сохранить в файл или вывести содержимое
    file_put_contents($file_name, $output_text);
    echo $output_text;
}

// Функция для получения URL, лучше чем file_get_contents()
function get_url($url, $timeout = 5) {
    $url = str_replace("&amp;", "&", urldecode(trim($url)));
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  // требуется для HTTPS URL
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
    $content = curl_exec($ch);
    curl_close($ch);
    return $content;
}

Не забудьте адаптировать код под свои нужды, так как это пример для извлечения текста только из формата DOCX. Если у вас есть дополнительные вопросы или необходима помощь с другими форматами (PDF, DOC, XLSX, PPTX и т.д.), дайте знать!

0

Для работы с документами формата .docx я рекомендую использовать инструмент docx2txt, который доступен, как минимум, в системах Debian/Ubuntu:

docx2txt < ваш_файл.docx

В файле README объясняется, как интегрировать его с Vim. Добавьте в ваш файл .vimrc следующие строки:

" используйте docx2txt.pl, чтобы позволить Vim просматривать текстовое содержимое .docx файла напрямую.
autocmd BufReadPre *.docx set ro
autocmd BufReadPost *.docx %!docx2txt

(Также объясняется, как интегрировать инструмент с Emacs).

Для тех, кто интересуется техническими подробностями, этот инструмент написан на Perl.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь