From ec514f310fdad3958c30e4ddedec29722c5ea4d9 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Tue, 11 Mar 2014 16:27:42 +0700 Subject: [PATCH] Reader: Read section settings and font/paragraph styles --- Classes/PHPWord/Reader/Word2007.php | 289 ++++++++++++++++-- Classes/PHPWord/Section.php | 9 + Classes/PHPWord/Shared/File.php | 2 +- Classes/PHPWord/Style/Paragraph.php | 2 +- Classes/PHPWord/Writer/Word2007/Base.php | 6 +- changelog.txt | 1 + samples/Sample_10_ReadWord2007.php | 91 ++---- samples/resources/Sample_10_ReadWord2007.docx | Bin 0 -> 22104 bytes samples/results/.gitkeep | 0 9 files changed, 295 insertions(+), 105 deletions(-) create mode 100644 samples/resources/Sample_10_ReadWord2007.docx create mode 100644 samples/results/.gitkeep diff --git a/Classes/PHPWord/Reader/Word2007.php b/Classes/PHPWord/Reader/Word2007.php index c17d4074..78a9875c 100644 --- a/Classes/PHPWord/Reader/Word2007.php +++ b/Classes/PHPWord/Reader/Word2007.php @@ -35,7 +35,8 @@ if (!defined('PHPWORD_BASE_PATH')) { /** * PHPWord_Reader_Word2007 */ -class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord_Reader_IReader +class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements + PHPWord_Reader_IReader { /** @@ -54,7 +55,8 @@ class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord { // Check if file exists if (!file_exists($pFilename)) { - throw new PHPWord_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + throw new PHPWord_Exception("Could not open " . $pFilename . + " for reading! File does not exist."); } $return = false; @@ -86,9 +88,13 @@ class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord * * @param ZipArchive $archive * @param string $fileName + * @param bool $removeNamespace */ - public function getFromZipArchive($archive, $fileName = '') - { + public function getFromZipArchive( + $archive, + $fileName = '', + $removeNamespace = false + ) { // Root-relative paths if (strpos($fileName, '//') !== false) { @@ -103,9 +109,9 @@ class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord $contents = $archive->getFromName(substr($fileName, 1)); } - // Stupid hack for namespace - if ($contents != '' && $fileName = 'word/document.xml') { - $contents = preg_replace('~(open($pFilename); - // Read relationships + // Read properties and documents $rels = simplexml_load_string($this->getFromZipArchive($zip, "_rels/.rels")); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { // Core properties - case "http://schemas.openxmlformats.org/package/2006//relationships/metadata/core-properties": + case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": $xmlCore = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}")); if (is_object($xmlCore)) { $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); - $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006//metadata/core-properties"); + $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); $docProps = $word->getProperties(); $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); @@ -188,32 +195,75 @@ class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord $dir = dirname($rel["Target"]); $archive = "$dir/_rels/" . basename($rel["Target"]) . ".rels"; $relsDoc = simplexml_load_string($this->getFromZipArchive($zip, $archive)); - $relsDoc->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006//relationships"); + $relsDoc->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $xpath = self::array_item($relsDoc->xpath("rel:Relationship[@Type='" . "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlDoc = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}")); - if ($xmlDoc->body) { + $xmlDoc = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}", true)); + if (is_object($xmlDoc)) { $section = $word->createSection(); - foreach ($xmlDoc->body->children() as $element) { - switch ($element->getName()) { - case 'p': - if ($element->pPr->sectPr) { - $section = $word->createSection(); - continue; - } - if ($element->r) { - if (count($element->r) == 1) { - $section->addText($element->r->t); - } else { - $textRun = $section->createTextRun(); - foreach ($element->r as $r) { - $textRun->addText($r->t); - } - } + + foreach ($xmlDoc->body->children() as $elm) { + $elmName = $elm->getName(); + if ($elmName == 'p') { // Paragraph/section + // Create new section if section section found + if ($elm->pPr->sectPr) { + $section->setSettings($this->loadSectionSettings($elm->pPr)); + $section = $word->createSection(); + continue; + } + // Has w:r? It's either text or textrun + if ($elm->r) { + // w:r = 1? It's a plain paragraph + if (count($elm->r) == 1) { + $section->addText($elm->r->t, + $this->loadFontStyle($elm->r)); + // w:r more than 1? It's a textrun } else { - $section->addTextBreak(); + $textRun = $section->createTextRun(); + foreach ($elm->r as $r) { + $textRun->addText($r->t, + $this->loadFontStyle($r)); + } } - break; + // No, it's a textbreak + } else { + $section->addTextBreak(); + } + } elseif ($elmName == 'sectPr') { + // Last section setting + $section->setSettings($this->loadSectionSettings($xmlDoc->body)); + } + } + } + break; + } + } + + // Read styles + $docRels = simplexml_load_string($this->getFromZipArchive($zip, "word/_rels/document.xml.rels")); + foreach ($docRels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles": + $xmlStyle = simplexml_load_string($this->getFromZipArchive($zip, "word/{$rel['Target']}", true)); + if (is_object($xmlStyle)) { + foreach ($xmlStyle->children() as $elm) { + if ($elm->getName() != 'style') { + continue; + } + unset($pStyle); + unset($fStyle); + $hasParagraphStyle = $elm->pPr && ($elm->pPr != ''); + $hasFontStyle = $elm->rPr && ($elm->rPr != ''); + $styleName = (string)$elm->name['val']; + if ($hasParagraphStyle) { + $pStyle = $this->loadParagraphStyle($elm); + if (!$hasFontStyle) { + $word->addParagraphStyle($styleName, $pStyle); + } + } + if ($hasFontStyle) { + $fStyle = $this->loadFontStyle($elm); + $word->addFontStyle($styleName, $fStyle, $pStyle); } } } @@ -225,6 +275,181 @@ class PHPWord_Reader_Word2007 extends PHPWord_Reader_Abstract implements PHPWord return $word; } + /** + * Load section settings from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + * + * @todo Implement gutter + */ + private function loadSectionSettings($elm) + { + if ($xml = $elm->sectPr) { + $setting = array(); + if ($xml->type) { + $setting['breakType'] = (string)$xml->type['val']; + } + if ($xml->pgSz) { + if (isset($xml->pgSz['w'])) { + $setting['pageSizeW'] = (int)$xml->pgSz['w']; + } + if (isset($xml->pgSz['h'])) { + $setting['pageSizeH'] = (int)$xml->pgSz['h']; + } + if (isset($xml->pgSz['orient'])) { + $setting['orientation'] = (string)$xml->pgSz['orient']; + } + } + if ($xml->pgMar) { + if (isset($xml->pgMar['top'])) { + $setting['topMargin'] = (int)$xml->pgMar['top']; + } + if (isset($xml->pgMar['left'])) { + $setting['leftMargin'] = (int)$xml->pgMar['left']; + } + if (isset($xml->pgMar['bottom'])) { + $setting['bottomMargin'] = (int)$xml->pgMar['bottom']; + } + if (isset($xml->pgMar['right'])) { + $setting['rightMargin'] = (int)$xml->pgMar['right']; + } + if (isset($xml->pgMar['header'])) { + $setting['headerHeight'] = (int)$xml->pgMar['header']; + } + if (isset($xml->pgMar['footer'])) { + $setting['footerHeight'] = (int)$xml->pgMar['footer']; + } + if (isset($xml->pgMar['gutter'])) { + // $setting['gutter'] = (int)$xml->pgMar['gutter']; + } + } + if ($xml->cols) { + if (isset($xml->cols['num'])) { + $setting['colsNum'] = (int)$xml->cols['num']; + } + if (isset($xml->cols['space'])) { + $setting['colsSpace'] = (int)$xml->cols['space']; + } + } + return $setting; + } else { + return null; + } + } + + /** + * Load paragraph style from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + */ + private function loadParagraphStyle($elm) + { + if ($xml = $elm->pPr) { + if ($xml->pStyle) { + return (string)$xml->pStyle['val']; + } + $style = array(); + if ($xml->jc) { + $style['align'] = (string)$xml->jc['val']; + } + if ($xml->ind) { + if (isset($xml->ind->left)) { + $style['indent'] = (int)$xml->ind->left; + } + if (isset($xml->ind->hanging)) { + $style['hanging'] = (int)$xml->ind->hanging; + } + if (isset($xml->ind->line)) { + $style['spacing'] = (int)$xml->ind->line; + } + } + if ($xml->spacing) { + if (isset($xml->spacing['after'])) { + $style['spaceAfter'] = (int)$xml->spacing['after']; + } + if (isset($xml->spacing['before'])) { + $style['spaceBefore'] = (int)$xml->spacing['before']; + } + if (isset($xml->spacing['line'])) { + $style['spacing'] = (int)$xml->spacing['line']; + } + } + if ($xml->basedOn) { + $style['basedOn'] = (string)$xml->basedOn['val']; + } + if ($xml->next) { + $style['next'] = (string)$xml->next['val']; + } + if ($xml->widowControl) { + $style['widowControl'] = false; + } + if ($xml->keepNext) { + $style['keepNext'] = true; + } + if ($xml->keepLines) { + $style['keepLines'] = true; + } + if ($xml->pageBreakBefore) { + $style['pageBreakBefore'] = true; + } + return $style; + } else { + return null; + } + } + + /** + * Load font style from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + */ + private function loadFontStyle($elm) + { + if ($xml = $elm->rPr) { + if ($xml->rStyle) { + return (string)$xml->rStyle['val']; + } + $style = array(); + if ($xml->rFonts) { + $style['name'] = (string)$xml->rFonts['ascii']; + } + if ($xml->sz) { + $style['size'] = (int)$xml->sz['val'] / 2; + } + if ($xml->color) { + $style['color'] = (string)$xml->color['val']; + } + if ($xml->b) { + $style['bold'] = true; + } + if ($xml->i) { + $style['italic'] = true; + } + if ($xml->u) { + $style['underline'] = (string)$xml->u['val']; + } + if ($xml->strike) { + $style['strikethrough'] = true; + } + if ($xml->highlight) { + $style['fgColor'] = (string)$xml->highlight['val']; + } + if ($xml->vertAlign) { + if ($xml->vertAlign['val'] == 'superscript') { + $style['superScript'] = true; + } else { + $style['subScript'] = true; + } + } + return $style; + } else { + return null; + } + } + /** * Get array item * diff --git a/Classes/PHPWord/Section.php b/Classes/PHPWord/Section.php index c50e2d0c..3ed55ee5 100755 --- a/Classes/PHPWord/Section.php +++ b/Classes/PHPWord/Section.php @@ -77,7 +77,16 @@ class PHPWord_Section { $this->_sectionCount = $sectionCount; $this->_settings = new PHPWord_Section_Settings(); + $this->setSettings($settings); + } + /** + * Set Section Settings + * + * @param array $settings + */ + public function setSettings($settings = null) + { if (!is_null($settings) && is_array($settings)) { foreach ($settings as $key => $value) { if (substr($key, 0, 1) != '_') { diff --git a/Classes/PHPWord/Shared/File.php b/Classes/PHPWord/Shared/File.php index 7c1470fe..84cd2e84 100755 --- a/Classes/PHPWord/Shared/File.php +++ b/Classes/PHPWord/Shared/File.php @@ -76,7 +76,7 @@ class PHPWord_Shared_File // Found something? if ($returnValue == '' || is_null($returnValue)) { - $pathArray = split('/', $pFilename); + $pathArray = explode('/', $pFilename); while (in_array('..', $pathArray) && $pathArray[0] != '..') { for ($i = 0; $i < count($pathArray); ++$i) { if ($pathArray[$i] == '..' && $i > 0) { diff --git a/Classes/PHPWord/Style/Paragraph.php b/Classes/PHPWord/Style/Paragraph.php index bf0ae182..754589cb 100755 --- a/Classes/PHPWord/Style/Paragraph.php +++ b/Classes/PHPWord/Style/Paragraph.php @@ -506,4 +506,4 @@ class PHPWord_Style_Paragraph { return $this->lineHeight; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Writer/Word2007/Base.php b/Classes/PHPWord/Writer/Word2007/Base.php index 77f4d0d7..3ee0823e 100755 --- a/Classes/PHPWord/Writer/Word2007/Base.php +++ b/Classes/PHPWord/Writer/Word2007/Base.php @@ -128,8 +128,8 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart protected function _writeParagraphStyle( PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Paragraph $style, - $withoutPPR = false) - { + $withoutPPR = false + ) { $align = $style->getAlign(); $spacing = $style->getSpacing(); $spaceBefore = $style->getSpaceBefore(); @@ -926,4 +926,4 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $objWriter->endElement(); // w:p } } -} \ No newline at end of file +} diff --git a/changelog.txt b/changelog.txt index 2230f687..a76efb00 100755 --- a/changelog.txt +++ b/changelog.txt @@ -50,6 +50,7 @@ Changes in branch for release 0.7.1 : - Bugfix: (ivanlanin) GH-94 - General: PHPWord_Shared_Drawing::centimetersToPixels() conversion - Feature: (ivanlanin) - Paragraph: setTabs() function - Feature: (ivanlanin) GH-99 - General: Basic support for TextRun on ODT and RTF +- Feature: (ivanlanin) - Reader: Initial effort for Word2007 - QA: (Progi1984) - UnitTests Changes in branch for release 0.7.0 : diff --git a/samples/Sample_10_ReadWord2007.php b/samples/Sample_10_ReadWord2007.php index d7f81925..a837a574 100644 --- a/samples/Sample_10_ReadWord2007.php +++ b/samples/Sample_10_ReadWord2007.php @@ -5,74 +5,29 @@ define('EOL', (PHP_SAPI == 'cli') ? PHP_EOL : '
'); require_once '../Classes/PHPWord.php'; -$files = array( - "Sample_01_SimpleText.docx", - "Sample_02_TabStops.docx", - "Sample_03_Sections.docx", - "Sample_04_Textrun.docx", - "Sample_05_Multicolumn.docx", - "Sample_06_Footnote.docx", - "Sample_07_TemplateCloneRow.docx", - "Sample_08_ParagraphPagination.docx", - "Sample_09_Tables.docx", -); +// Read contents +$sample = 'Sample_10_ReadWord2007'; +$source = "resources/{$sample}.docx"; +$target = "results/{$sample}"; +echo '

', date('H:i:s'), " Reading contents from `{$source}`

"; +$PHPWord = PHPWord_IOFactory::load($source); -foreach ($files as $file) { - echo '
'; - echo '

', date('H:i:s'), " Load from {$file} with contents:

"; - unset($PHPWord); - try { - $PHPWord = PHPWord_IOFactory::load($file); - } catch (Exception $e) { - echo '

Caught exception: ', $e->getMessage(), '

'; - continue; - } - $sections = $PHPWord->getSections(); - $countSections = count($sections); - $pSection = 0; +// Rewrite contents +echo date('H:i:s') , " Write to Word2007 format" , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); +$objWriter->save("{$sample}.docx"); +rename("{$sample}.docx", "{$target}.docx"); - if ($countSections > 0) { - foreach ($sections as $section) { - $pSection++; - echo "

Section {$pSection}:

"; - $elements = $section->getElements(); - foreach ($elements as $element) { - if ($element instanceof PHPWord_Section_Text) { - echo '

' . htmlspecialchars($element->getText()) . '

'; - } elseif ($element instanceof PHPWord_Section_TextRun) { - $subelements = $element->getElements(); - echo '

'; - if (count($subelements) > 0) { - foreach ($subelements as $subelement) { - if ($subelement instanceof PHPWord_Section_Text) { - echo htmlspecialchars($subelement->getText()); - } - } - } - echo '

'; - } elseif ($element instanceof PHPWord_Section_Link) { - echo '

Link not yet supported.

'; - } elseif ($element instanceof PHPWord_Section_Title) { - echo '

Title not yet supported.

'; - } elseif ($element instanceof PHPWord_Section_TextBreak) { - echo '
'; - } elseif ($element instanceof PHPWord_Section_PageBreak) { - echo '

Page break not yet supported.

'; - } elseif ($element instanceof PHPWord_Section_Table) { - echo '

Table not yet supported.

'; - } elseif ($element instanceof PHPWord_Section_ListItem) { - echo '

List item not yet supported.

'; - } elseif ($element instanceof PHPWord_Section_Image || - $element instanceof PHPWord_Section_MemoryImage - ) { - echo '

Image not yet supported.

'; - } elseif ($element instanceof PHPWord_TOC) { - echo '

TOC not yet supported.

'; - } elseif($element instanceof PHPWord_Section_Footnote) { - echo '

Footnote not yet supported.

'; - } - } - } - } -} +echo date('H:i:s') , ' Write to OpenDocumentText format' , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); +$objWriter->save("{$sample}.odt"); +rename("{$sample}.odt", "{$target}.odt"); +echo date('H:i:s') , ' Write to RTF format' , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); +$objWriter->save("{$sample}.rtf"); +rename("{$sample}.rtf", "{$target}.rtf"); + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; +echo date('H:i:s') , " Done writing file" , EOL; diff --git a/samples/resources/Sample_10_ReadWord2007.docx b/samples/resources/Sample_10_ReadWord2007.docx new file mode 100644 index 0000000000000000000000000000000000000000..fe8ec7acae8a53e80cf6219fed8b439465c7cea8 GIT binary patch literal 22104 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 literal 0 HcmV?d00001 diff --git a/samples/results/.gitkeep b/samples/results/.gitkeep new file mode 100644 index 00000000..e69de29b