Поиск изображении в файлах MS Word с помощью PHP или JS

У нас есть файл формата docx или dox, в этом файле есть текст и парочка картинок. Как с помощью скрипта найти картинки из файла и записать их в массив. Чтобы при вызове массива потом можно было вывести все найденные изображения.

Есть ли вообще такая функция или можно как-то импровизировать? Нужен код выполняющий выше описанные действия.


Ответы (1 шт):

Автор решения: Антон Виноградов

Вопрос интересный. Для примера я создал такой документ и написал строку TEXT_TEST1, ниже вставил картинку в формате png, ниже строку TEXT_TEST2, и после ещё картинку в формате jpg. Сохранил документ под именем test.docx.

Если разобраться, то файл в формате docx - это ничто иное как архив. Если открыть его zip-архиватором, то получим структуру:

test.docx
|   [Content_Types].xml
|
+---docProps
|       app.xml
|       core.xml
|
+---word
|   |   document.xml
|   |   endnotes.xml
|   |   fontTable.xml
|   |   footnotes.xml
|   |   settings.xml
|   |   styles.xml
|   |   webSettings.xml
|   |
|   +---media
|   |       image1.png
|   |       image2.jpg
|   |
|   +---theme
|   |       theme1.xml
|   |
|   \---_rels
|           comments.xml.rels
|           document.xml.rels
|           endnotes.xml.rels
|           footnotes.xml.rels
|
\---_rels
        .rels

Нас интересует директория \word\media, тут хранятся оригинальные файлы изображений. Осталось написать скрипт, который, распакует документ, извлечёт все изображения из него в отдельную папку, и вернёт массив имён этих изображений.

<?php
error_reporting(E_ERROR | E_PARSE);

$file = 'test.docx'; // Путь до нашего документа .docx
$images = get_img_array($file); // Получить массив с именами изображений
var_dump($images); // Вывод результата

function get_img_array($file){ // Функция распаковки, копирования файлов и чтения названий изображений.
    $filename = pathinfo($file, PATHINFO_FILENAME);
    $zip = new ZipArchive;
    $zip->open($file);
    $zip->extractTo('./'.$filename);
    $zip->close();
    $files = scandir('./'.$filename.'/word/media');
    unset($files[0]);
    unset($files[1]);
    $files = array_values($files);
    if(!file_exists('./images')) mkdir('./images', 0700);
    if(!file_exists('./images/'.$filename)) mkdir('./images/'.$filename, 0700);
    for($i = 0; $i <= count($files)-1; $i++){
        copy('./'.$filename.'/word/media/'.$files[$i], './images/'.$filename.'/'.$files[$i]);
        $files[$i] = './images/'.$filename.'/'.$files[$i];
    }
    remove_dir('./'.$filename);
    return $files;
}

function remove_dir($dir){ // Функция удаления директории с содержимым архива
    rename($dir.'/_rels/.rels', $dir.'/_rels/0.rels');
    if ($objs = glob($dir.'/*')) {
        foreach($objs as $obj) {
            is_dir($obj) ? remove_dir($obj) : unlink($obj);
        }
    }
    rmdir($dir);
}   

В итоге мы имеем директорию images, в которой хранятся картинки в директории с именем документа test, а скрипт вернул нам ещё и массив с прямыми адресами к этим картинкам:

array(2) {
  [0]=>
  string(24) "./images/test/image1.png"
  [1]=>
  string(24) "./images/test/image2.jpg"
}

Как-то так получается.

→ Ссылка