Поиск изображении в файлах 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"
}
Как-то так получается.