PHPWord — читання MSWord документів засобами PHP

25

Від автора: не так давно на нашому сайті було опубліковано урок по створенню документів MS Word засобами мови PHP, і з використанням спеціальної бібліотеки PHPWord. Але в коментарях до даного відео – прозвучало питання, як за допомогою даної бібліотеки читати готові документи, що власне і підштовхнуло мене до запису даного уроку, в якому ми з Вами навчимося, використовуючи зазначену вище бібліотеку, читати раніше створені документи ms word.

PHPWord — читання MSWord документів засобами PHPPHPWord — читання MSWord документів засобами PHP

У даному уроці ми продовжуємо вивчати можливості PHPWord, а саме розглянемо інструменти з читання готових документів MS Word. Хотів би зазначити, що сьогодні ми будемо працювати з вже встановленою бібліотекою, тому як це вже другий урок з даної теми, а значить, на засадах докладно зупинятися не будемо. Тому рекомендую, перед переглядом даного відео ознайомитися з першою частина уроку – PHPWord — створення MS Word документів засобами PHP.

Отже, заготівля, тестового сценарію складається з одного єдиного файлу index.php у коді якого виконана установка бібліотеки.

Отже, заготівля, тестового сценарію складається з одного єдиного файлу index.php у коді якого виконана установка бібліотеки.

require ‘vendor/autoload.php’;

Для початку створимо змінну, в якій буде зберігатися шлях до документа ms word, з яким ми будемо працювати.

$source = __DIR__.»/docs/text.docx»;

Далі, згадаймо, що на початку роботи з бібліотекою необхідно створити об’єкт головного класу PHPWord, але це в тому випадку якщо створюється новий документ. Якщо ж здійснюється читання готового файлу MS Word – об’єкт зазначеного класу необхідно створити для документа, але перед цим його потрібно прочитати.

Для читання готових документів в PHPWord передбачена група класів, що відповідають за читання документів різних форматів. А отже, першим ділом створимо об’єкт спеціального класу-риддера“.

$objReader = \PhpOffice\PhpWord\IOFactory::createReader(‘Word2007’);

Далі, використовуючи даний об’єкт – виконаємо читання документу формату MS Word.

$phpWord = $objReader->load($source);

Таким чином, по суті, завдання уроку виконана, так як документ прочитаний і його дані розташовуються в структурі тільки що створеного об’єкта $phpWord. Але давайте поговоримо про те, як отримати дані, що зберігаються в об’єкті.

По офіційній документації будь-яка інформація документа MS Word, згідно бібліотеці PHPWord, розташовується в окремих секціях. При цьому кожна секція містить певний набір елементів – текст, таблиці, зображення, посилання і т. д. Елементи в свою чергу, так само можуть бути складними і включати в себе певний набір вкладених елементів, наприклад таблиці.

Тому, викликаючи на виконання метод getSections(), ми отримуємо доступ до секцій документа, при цьому в якості результату буде повернутий масив, а значить ми його можемо обійти цикл foreach().

foreach($phpWord->getSections() as $section) {
$arrays = $section->getElements();
}

При цьому в коді циклу, для кожної секції, отримаємо масив вхідних елементів, викликаючи на виконання метод getElements(). Так як значення, що повертається – це масив, значить, використовуючи вище зазначений цикл, ми можемо отримати доступ до кожній його клітинці.

foreach($arrays as $e) {
}

При цьому у змінній $e на кожній ітерації циклу, міститься об’єкт одного з елементів масиву секцій. Здавалося б, ми відразу можемо отримати текстові дані MS Word, але для початку потрібно перевірити, що міститься в змінній $e.

if(get_class($e) === ‘PhpOffice\PhpWord\Element\TextRun’) {

Якщо в даної змінної міститься об’єкт класу ‘PhpOffice\PhpWord\Element\TextRun’, значить ми працюємо з складною текстовою областю, в якій розташовується декілька більш простих елементів. Тому повторно викликаємо метод getElements() і по результату проходимся в циклі foreach().

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 .= ‘‘;
$body .= $text->getText().’
‘;
}
}
}
}
include ‘templ.php’;

Таким чином, для поточного документа, в змінну $text, потрапляє об’єкт елемента Text, тобто елемент найпростішого текст, для отримання якого достатньо викликати на виконання метод getText(). Для отримання інформації про форматування поточного елемента, необхідно звернутися до методу getFontStyle(), який повертає об’єкт в закритих властивості якого міститься зазначена інформація. Відповідно для доступу до значень цих властивостей необхідно використовувати спеціальні методи:

getSize() – розмір шрифту;

isBold() — повертає істину, якщо використовується напівжирний шрифт;

getColor() – колір тексту;

getName() – ім’я шрифту.

Весь вміст документа, записується в змінну $body, значення якої буде відображено на екрані, використовуючи шаблон. Порожні рядки документа являють собою об’єкт елемента TextBreak, який можна обробити наступним чином:

else if(get_class($e) === ‘PhpOffice\PhpWord\Element\TextBreak’) {
$body .= ‘
‘;
}

Для обробки таблиць, доведеться додати досить багато рядків коду, тому як таблиця – це складний елемент Table, який складається з окремих рядків, а ті в свою чергу з окремих осередків. І більш того, кожна комірка може містити ще вкладені елементи, тому як, приміром, у одній клітинці так само можна сформувати таблицю. Нижче наведу весь код, разом з кодом обробки таблиць.

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 .= ‘‘;
$body .= $text->getText().’
‘;
}
}
else if(get_class($e) === ‘PhpOffice\PhpWord\Element\TextBreak’) {
$body .= ‘
‘;
}
else if(get_class($e) === ‘PhpOffice\PhpWord\Element\Table’) {
$body .= ‘

‘;
$rows = $e->getRows();
foreach($rows as $row) {
$body .= ‘

‘;
$cells = $row->getCells();
foreach($cells as $cell) {
$body .= ‘

‘;
}
$body .= ‘

‘;
}
$body .= ‘

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 .= ‘

‘;
}
else {
$body .= $e->getText();
}
}
break;
}
include ‘templ.php’;

Для отримання рядків, необхідно викликати метод getRows(), при цьому в якості результату буде повернутий масив об’єктів з інформацією по кожному рядку (елемент Row). Використовуючи foreach(), обходимо даний масив для кожного рядка отримуємо осередку, за допомогою методу getCells(). При цьому знову ж таки повертається масив, який так само ми обходимо циклом. А далі для кожної клітинки викликаємо на виконання метод getElements(), для отримання її елементів. І так далі за принципом, описаним вище.

Далі, залишилося тільки відобразити значення змінної $body, будь-яким зручним для Вас способом.

На цьому даний урок я буду завершувати. Як Ви бачите, PHPWord надає досить потужні інструменти по роботі з документами MS Word, але і в теж час складні в плані отримання даних об’єктів.

Всього Вам доброго і вдалого кодування!!!