работаю с шаблоном phpword'a, возникло желание получать содержимое шаблона (только текст, желательно сохраняя настройки форматирования). собственно, просто выводить содержимое шаблона я не могу Код (PHP): $template = $PHPWord->loadTemplate('***************.docx'); echo $template; вардамп отдает мне вот такую структуру, необходимый мне текст содержится вот в последнем свойстве этого объекта. вопрос: как оптимально получить этот текст?
быстро взглянул - вроде ничего подходящего нет. Код (PHP): class PHPWord_Template { /** * ZipArchive * * @var ZipArchive */ private $_objZip; /** * Temporary Filename * * @var string */ private $_tempFileName; /** * Document XML * * @var string */ private $_documentXML; /** * Create a new Template Object * * @param string $strFilename */ public function __construct($strFilename) { $path = dirname($strFilename); $this->_tempFileName = $path.DIRECTORY_SEPARATOR.time().'.docx'; copy($strFilename, $this->_tempFileName); // Copy the source File to the temp File $this->_objZip = new ZipArchive(); $this->_objZip->open($this->_tempFileName); $this->_documentXML = $this->_objZip->getFromName('word/document.xml'); } /** * Set a Template value * * @param mixed $search * @param mixed $replace */ public function setValue($search, $replace, $limit=-1) { if(substr($search, 0, 1) !== '{' && substr($search, -1) !== '}') { $search = '{'.$search.'}'; } preg_match_all('/\{[^}]+\}/', $this->_documentXML, $matches); foreach ($matches[0] as $k => $match) { $no_tag = strip_tags($match); if ($no_tag == $search) { $match = '{'.$match.'}'; $this->_documentXML = preg_replace($match, $replace, $this->_documentXML, $limit); if ($limit == 1) { break; } } } } /** * Save Template * * @param string $strFilename */ public function save($strFilename) { if(file_exists($strFilename)) { unlink($strFilename); } $this->_objZip->addFromString('word/document.xml', $this->_documentXML); // Close zip file if($this->_objZip->close() === false) { throw new Exception('Could not close zip file.'); } rename($this->_tempFileName, $strFilename); } /** * Clone Rows in tables * * @param string $search * @param array $data */ public function cloneRow($search, $data=array()) { // remove ooxml-tags inside pattern foreach ($data as $nn => $fieldset) { foreach ($fieldset as $field => $val) { $key = '{'.$search.'.'.$field.'}'; $this->setValue($key, $key, 1); } } // how many clons we need $numberOfClones = 0; if (is_array($data)) { foreach ($data as $colName => $dataArr) { if (is_array($dataArr)) { $c = count($dataArr); if ($c > $numberOfClones) $numberOfClones = $c; } } } if ($numberOfClones > 0) { // read document as XML $xml = new DOMDocument(); $xml->loadXML($this->_documentXML, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING); //$xml = DOMDocument::loadXML($this->_documentXML, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING); // search for tables $tables = $xml->getElementsByTagName('tbl'); foreach ($tables as $table) { $text = $table->textContent; // search for pattern. Like {TBL1. if (mb_strpos($text, '{'.$search.'.') !== false) { // search row for clone $patterns = array(); $rows = $table->getElementsByTagName('tr'); $isUpdate = false; $isFind = false; foreach ($rows as $row) { $text = $row->textContent; $TextWithTags = $xml->saveXML($row); if ( mb_strpos($text, '{'.$search.'.') !== false // Pattern found in this row OR (mb_strpos($TextWithTags, '<w:vMerge/>') !== false AND $isFind) // This row is merged with upper row (Upper row have pattern) ) { // This row need to clone $patterns[] = $row->cloneNode(true); $isFind = true; } else { // This row don't have any patterns. It's table header or footer if (!$isUpdate and $isFind) { // This is table footer // Insert new rows before footer $this->InsertNewRows($table, $patterns, $row, $numberOfClones); $isUpdate = true; } } } // if table without footer if (!$isUpdate and $isFind) { $this->InsertNewRows($table, $patterns, $row, $numberOfClones); } } } // save document $res_string = $xml->saveXML(); $this->_documentXML = $res_string; // parsing data foreach ($data as $colName => $dataArr) { $pattern = '{' . $search . '.' . $colName . '}'; foreach ($dataArr as $value) { $this->setValue($pattern, $value, 1); } } } } /** * Insert new rows in table * * @param object &$table * @param object $patterns * @param object $row * @param int $numberOfClones */ protected function InsertNewRows(&$table, $patterns, $row, $numberOfClones) { for ($i = 1; $i < $numberOfClones; $i++) { foreach ($patterns as $pattern) { $new_row = $pattern->cloneNode(true); $table->insertBefore($new_row, $row); } } } Добавлено спустя 3 минуты 11 секунд: разве что какая-то связь с xml
Ну docx простой, раз в документации нет нужного функционала, то допиши. Может не открывать как шаблон, а просто как документ и вытягивать данные.
ну-с, попробовал я вот так: Код (PHP): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body><?php require_once 'lib/PHPWord_0.6.2_Beta/PHPWord.php'; $template = file_get_contents('templates/AttorneyLetter/upowaznienie_do_odbioru_opinnie_szewcow.docx'); echo mb_detect_encoding($template); echo "<pre>"; var_dump($template); echo "</pre>"; ?> </body> </html> получил вот так: Добавлено спустя 37 секунд: там польские символы по большей части. Добавлено спустя 8 минут 39 секунд: та и с русскими такая же беда. вообще странно, что при таком маленьком тексте содержится такая длинная строка. видимо, работает напрямую с xml, хотя все равно странно.
http://habrahabr.ru/post/69417/ если поможет. Добавлено спустя 21 минуту 27 секунд: кажется это то что тебе надо.
да, действительно подойдет. а есть идеи, как сохранить форматирование? вдруг я захочу передать содержимое одного ворда в другое? (пример)
Ну я увидел слово Catchable и вспомнил что в PHP 7 толи ошибки можно перехватывать(не путать с error_handler) толи ошибки кидают какието исключения свои. Добавлено спустя 52 секунды: Ида бенчмарки показывают что PHP 7 просто летать научился =)
не нашел способа, как адекватно можно получить содержимое шаблона сохраняя форматирование, поэтому запилил руками. почти идеально )
там и показывать-то нечего, специфический текст с форматированием характерным для документов различных. на соседней вкладке открыл доку по этой либе и пилил.