От автора: не так давно на нашем сайте был опубликован урок по созданию документов MS Word средствами языка PHP, и с использованием специальной библиотеки PHPWord. Но в комментариях к данному видео – прозвучал вопрос, как при помощи данной библиотеки читать готовые документы, что собственно и подтолкнуло меня к записи данного урока, в котором мы с Вами научимся, используя выше указанную библиотеку, читать ранее созданные документы MSWord.
В данном уроке мы продолжаем изучать возможности PHPWord, а именно рассмотрим инструменты по чтению готовых документов MS Word. Хотел бы отметить, что сегодня мы будем работать с уже установленной библиотекой, потому как это уже второй урок по данной теме, а значит, на основах подробно останавливаться не будем. Поэтому рекомендую, перед просмотром данного видео ознакомиться с первой часть урока – PHPWord — создание MS Word документов средствами PHP.
Итак, заготовка, тестового скрипта состоит из одного единственного файла index.php, в коде которого выполнена установка библиотеки.
Итак, заготовка, тестового скрипта состоит из одного единственного файла index.php, в коде которого выполнена установка библиотеки.
1 |
require 'vendor/autoload.php'; |
Для начала создадим переменную, в которой будет храниться путь к документу MSWord, с которым мы будем работать.
1 |
$source = __DIR__."/docs/text.docx"; |
Далее, вспомним, что в начале работы с библиотекой необходимо создать объект главного класса PHPWord, но это в том случае если создается новый документ. Если же осуществляется чтение готового файла MS Word – объект указанного класса необходимо создать для интересующего документа, но перед этим его нужно прочитать.
Для чтения готовых документов в PHPWord предусмотрена группа классов, отвечающих за чтение документов различных форматов. А значит, первым делом создадим объект специального “класса-риддера“.
1 |
$objReader = \PhpOffice\PhpWord\IOFactory::createReader('Word2007'); |
Далее, используя данный объект – выполним чтение документа формата MS Word.
1 |
$phpWord = $objReader->load($source); |
Таким образом, по сути, задача урока выполнена, так как документ прочитан и его данные располагаются в структуре только что созданного объекта $phpWord. Но давайте поговорим о том, как же получить данные хранящиеся в объекте.
По официальной документации любая информация документа MS Word, согласно библиотеке PHPWord, располагается в отдельных секциях. При этом каждая секция содержит определенный набор элементов – текст, таблица, изображение, ссылка и т.д. Элементы – же в свою очередь, так же могут быть сложными и включать в себя некий набор вложенных элементов, к примеру таблицы.
Поэтому, вызывая на исполнение метод getSections(), мы получаем доступ к секциям документа, при этом в качестве результата будет возвращен массив, а значит мы его можем обойти циклом foreach().
1 2 3 4 |
foreach($phpWord->getSections() as $section) { $arrays = $section->getElements(); } |
При этом в коде цикла, для каждой секции, получим массив входящих элементов, вызывая на исполнение метод getElements(). Так как возвращаемое значение – это массив, значит, используя выше указанный цикл, мы можем получить доступ к каждой его ячейке.
1 2 3 |
foreach($arrays as $e) { } |
При этом в переменной $e на каждой итерации цикла, содержится объект одного из элементов массива секций. Казалось бы, мы сразу можем получить текстовые данные MS Word, но для начала нужно проверить, что содержится в переменной $e.
1 |
if(get_class($e) === 'PhpOffice\PhpWord\Element\TextRun') { |
Если в данной переменной содержится объект класса ‘PhpOffice\PhpWord\Element\TextRun’, значит мы работаем с сложной текстовой областью, в которой располагается несколько более простых элементов. Поэтому повторно вызываем метод getElements() и по результату проходимся в цикле foreach().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php require 'vendor/autoload.php'; $source = __DIR__."/docs/text.docx"; $objReader = \PhpOffice\PhpWord\IOFactory::createReader('Word2007'); $phpWord = $objReader->load($source); $body = ''; foreach($phpWord->getSections() as $section) { $arrays = $section->getElements(); foreach($arrays as $e) { if(get_class($e) === 'PhpOffice\PhpWord\Element\TextRun') { foreach($e->getElements() as $text) { $font = $text->getFontStyle(); $size = $font->getSize()/10; $bold = $font->isBold() ? 'font-weight:700;' :''; $color = $font->getColor(); $fontFamily = $font->getName(); $body .= '<span style="font-size:' . $size . 'em;font-family:' . $fontFamily . '; '.$bold.'; color:#'.$color.'">'; $body .= $text->getText().'</span>'; } } } } include 'templ.php'; |
Таким образом, для текущего документа, в переменную $text, попадает объект элемента Text, то есть элемент простейшего текст, для получения которого достаточно вызвать на исполнение метод getText(). Для получения информации о форматировании текущего элемента, необходимо обратиться к методу getFontStyle(), который вернет объект в закрытых свойствах которого содержится указанная информация. Соответственно для доступа к значениям этих свойств необходимо использовать специальные методы:
getSize() – размер шрифта;
isBold() — возвращает истину, если используется полужирный шрифт;
getColor() – цвет текста;
getName() – имя шрифта.
Все содержимое документа, записывается в переменную $body, значение которой будет отображено на экране, используя шаблон. Пустые строки документа представляют собой объект элемента TextBreak, который можно обработать следующим образом:
1 2 3 |
else if(get_class($e) === 'PhpOffice\PhpWord\Element\TextBreak') { $body .= '<br />'; } |
Для обработки таблиц, придется добавить достаточно много строк кода, потому как таблица – это сложный элемент Table, который состоит из отдельных строк, а те в свою очередь из отдельных ячеек. И более того, каждая ячейка, может содержать еще вложенные элементы, потому как, к примеру в одной ячейке так же можно сформировать таблицу. Ниже приведу весь код, вместе с кодом обработки таблиц.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<?php require 'vendor/autoload.php'; $source = __DIR__."/docs/text.docx"; $objReader = \PhpOffice\PhpWord\IOFactory::createReader('Word2007'); $phpWord = $objReader->load($source); $body = ''; foreach($phpWord->getSections() as $section) { $arrays = $section->getElements(); foreach($arrays as $e) { if(get_class($e) === 'PhpOffice\PhpWord\Element\TextRun') { foreach($e->getElements() as $text) { $font = $text->getFontStyle(); $size = $font->getSize()/10; $bold = $font->isBold() ? 'font-weight:700;' :''; $color = $font->getColor(); $fontFamily = $font->getName(); $body .= '<span style="font-size:' . $size . 'em;font-family:' . $fontFamily . '; '.$bold.'; color:#'.$color.'">'; $body .= $text->getText().'</span>'; } } else if(get_class($e) === 'PhpOffice\PhpWord\Element\TextBreak') { $body .= '<br />'; } else if(get_class($e) === 'PhpOffice\PhpWord\Element\Table') { $body .= '<table border="2px">'; $rows = $e->getRows(); foreach($rows as $row) { $body .= '<tr>'; $cells = $row->getCells(); foreach($cells as $cell) { $body .= '<td style="width:'.$cell->getWidth().'">'; $celements = $cell->getElements(); foreach($celements as $celem) { if(get_class($celem) === 'PhpOffice\PhpWord\Element\Text') { $body .= $celem->getText(); } else if(get_class($celem) === 'PhpOffice\PhpWord\Element\TextRun') { foreach($celem->getElements() as $text) { $body .= $text->getText(); } } } $body .= '</td>'; } $body .= '</tr>'; } $body .= '</table>'; } else { $body .= $e->getText(); } } break; } include 'templ.php'; |
Для получения строк, необходимо вызвать метод getRows(), при этом в качестве результата будет возвращен массив объектов с информацией по каждой строке (элемент Row). Используя foreach(), обходим данный массив и для каждой строки получаем ячейки, при помощи метода getCells(). При этом опять же возвращается массив, который все так же мы обходим циклом. А далее для каждой ячейки вызываем на исполнение метод getElements(), для получения ее элементов. И так далее по принципу описанным выше.
Далее, осталось только отобразить значение переменной $body, любым удобным для Вас способом.
На этом данный урок я буду завершать. Как Вы видите, PHPWord предоставляет достаточно мощные инструменты по работе с документами MS Word, но и в тоже время сложные в плане получения данных из объектов.
Всего Вам доброго и удачного кодирования!!!
Комментарии (9)