/** * Get styles * * @return string */ private function writeStyles() { $css = '<style>' . PHP_EOL; // Default styles $defaultStyles = array('*' => array('font-family' => Settings::getDefaultFontName(), 'font-size' => Settings::getDefaultFontSize() . 'pt'), 'a.NoteRef' => array('text-decoration' => 'none'), 'hr' => array('height' => '1px', 'padding' => '0', 'margin' => '1em 0', 'border' => '0', 'border-top' => '1px solid #CCC')); foreach ($defaultStyles as $selector => $style) { $styleWriter = new GenericStyleWriter($style); $css .= $selector . ' {' . $styleWriter->write() . '}' . PHP_EOL; } // Custom styles $customStyles = Style::getStyles(); if (is_array($customStyles)) { foreach ($customStyles as $name => $style) { if ($style instanceof Font) { $styleWriter = new FontStyleWriter($style); if ($style->getStyleType() == 'title') { $name = str_replace('Heading_', 'h', $name); } else { $name = '.' . $name; } $css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL; } elseif ($style instanceof Paragraph) { $styleWriter = new ParagraphStyleWriter($style); $name = '.' . $name; $css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL; } } } $css .= '</style>' . PHP_EOL; return $css; }
/** * Write part * * @return string */ public function write() { $xmlWriter = $this->getXmlWriter(); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startElement('w:styles'); $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); // Write default styles $styles = Style::getStyles(); $this->writeDefaultStyles($xmlWriter, $styles); // Write styles if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if ($styleName == 'Normal') { continue; } // Get style class and execute if the private method exists $styleClass = substr(get_class($style), strrpos(get_class($style), '\\') + 1); $method = "write{$styleClass}Style"; if (method_exists($this, $method)) { $this->{$method}($xmlWriter, $styleName, $style); } } } $xmlWriter->endElement(); // w:styles return $xmlWriter->getData(); }
/** * Write font faces declaration */ protected function writeFontFaces(XMLWriter $xmlWriter) { $xmlWriter->startElement('office:font-face-decls'); $fontTable = array(); $styles = Style::getStyles(); $numFonts = 0; if (count($styles) > 0) { foreach ($styles as $style) { // Font if ($style instanceof Font) { $numFonts++; $name = $style->getName(); if (!in_array($name, $fontTable)) { $fontTable[] = $name; // style:font-face $xmlWriter->startElement('style:font-face'); $xmlWriter->writeAttribute('style:name', $name); $xmlWriter->writeAttribute('svg:font-family', $name); $xmlWriter->endElement(); } } } } if (!in_array(Settings::getDefaultFontName(), $fontTable)) { $xmlWriter->startElement('style:font-face'); $xmlWriter->writeAttribute('style:name', Settings::getDefaultFontName()); $xmlWriter->writeAttribute('svg:font-family', Settings::getDefaultFontName()); $xmlWriter->endElement(); } $xmlWriter->endElement(); }
/** * Get font and paragraph styles */ protected function getStyles() { /** @var \PhpOffice\PhpWord\Writer\RTF $parentWriter Type hint */ $parentWriter = $this->parentWriter; /** @var \PhpOffice\PhpWord\Element\Text $element Type hint */ $element = $this->element; // Font style if (method_exists($element, 'getFontStyle')) { $this->fontStyle = $element->getFontStyle(); if (is_string($this->fontStyle)) { $this->fontStyle = Style::getStyle($this->fontStyle); } } // Paragraph style if (method_exists($element, 'getParagraphStyle')) { $this->paragraphStyle = $element->getParagraphStyle(); if (is_string($this->paragraphStyle)) { $this->paragraphStyle = Style::getStyle($this->paragraphStyle); } if ($this->paragraphStyle !== null && !$this->withoutP) { if ($parentWriter->getLastParagraphStyle() != $element->getParagraphStyle()) { $parentWriter->setLastParagraphStyle($element->getParagraphStyle()); } else { $parentWriter->setLastParagraphStyle(); $this->paragraphStyle = null; } } else { $parentWriter->setLastParagraphStyle(); $this->paragraphStyle = null; } } }
/** * Write font faces declaration */ protected function writeFontFaces(XMLWriter $xmlWriter) { $xmlWriter->startElement('office:font-face-decls'); $arrFonts = array(); $styles = Style::getStyles(); $numFonts = 0; if (count($styles) > 0) { foreach ($styles as $style) { // Font if ($style instanceof Font) { $numFonts++; $name = $style->getName(); if (!in_array($name, $arrFonts)) { $arrFonts[] = $name; // style:font-face $xmlWriter->startElement('style:font-face'); $xmlWriter->writeAttribute('style:name', $name); $xmlWriter->writeAttribute('svg:font-family', $name); $xmlWriter->endElement(); } } } } if (!in_array(PhpWord::DEFAULT_FONT_NAME, $arrFonts)) { $xmlWriter->startElement('style:font-face'); $xmlWriter->writeAttribute('style:name', PhpWord::DEFAULT_FONT_NAME); $xmlWriter->writeAttribute('svg:font-family', PhpWord::DEFAULT_FONT_NAME); $xmlWriter->endElement(); } $xmlWriter->endElement(); }
/** * Add title with predefined style * * @coversNothing */ public function testAddTitleWithStyle() { Style::addTitleStyle(1, array('size' => 14)); $section = new Section(0); $section->setPhpWord(new PhpWord()); $section->addTitle('Test', 1); $elementCollection = $section->getElements(); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Title', $elementCollection[0]); }
/** * Create a new Title Element * * @param string $text * @param int $depth */ public function __construct($text, $depth = 1) { $this->text = String::toUTF8($text); $this->depth = $depth; if (array_key_exists("Heading_{$this->depth}", Style::getStyles())) { $this->style = "Heading{$this->depth}"; } return $this; }
/** * Write part * * @return string */ public function write() { $xmlWriter = $this->getXmlWriter(); $styles = Style::getStyles(); $drawingSchema = 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'; $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startElement('w:numbering'); $xmlWriter->writeAttribute('xmlns:ve', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); $xmlWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $xmlWriter->writeAttribute('xmlns:m', 'http://schemas.openxmlformats.org/officeDocument/2006/math'); $xmlWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); $xmlWriter->writeAttribute('xmlns:wp', $drawingSchema); $xmlWriter->writeAttribute('xmlns:w10', 'urn:schemas-microsoft-com:office:word'); $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); $xmlWriter->writeAttribute('xmlns:wne', 'http://schemas.microsoft.com/office/word/2006/wordml'); // Abstract numbering definitions foreach ($styles as $style) { if ($style instanceof NumberingStyle) { $levels = $style->getLevels(); $xmlWriter->startElement('w:abstractNum'); $xmlWriter->writeAttribute('w:abstractNumId', $style->getIndex()); $xmlWriter->startElement('w:nsid'); $xmlWriter->writeAttribute('w:val', $this->getRandomHexNumber()); $xmlWriter->endElement(); // w:nsid $xmlWriter->startElement('w:multiLevelType'); $xmlWriter->writeAttribute('w:val', $style->getType()); $xmlWriter->endElement(); // w:multiLevelType if (is_array($levels)) { foreach ($levels as $level) { $this->writeLevel($xmlWriter, $level); } } $xmlWriter->endElement(); // w:abstractNum } } // Numbering definition instances foreach ($styles as $style) { if ($style instanceof NumberingStyle) { $xmlWriter->startElement('w:num'); $xmlWriter->writeAttribute('w:numId', $style->getIndex()); $xmlWriter->startElement('w:abstractNumId'); $xmlWriter->writeAttribute('w:val', $style->getIndex()); $xmlWriter->endElement(); // w:abstractNumId $xmlWriter->endElement(); // w:num } } $xmlWriter->endElement(); // w:numbering return $xmlWriter->getData(); }
/** * Write word/styles.xml * * @param \PhpOffice\PhpWord\PhpWord $phpWord */ public function writeStyles(PhpWord $phpWord = null) { if (is_null($phpWord)) { throw new Exception("No PhpWord assigned."); } $xmlWriter = $this->getXmlWriter(); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startElement('w:styles'); $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); // Write default styles $styles = Style::getStyles(); $this->writeDefaultStyles($xmlWriter, $phpWord, $styles); // Write styles if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if ($styleName == 'Normal') { continue; } // Font style if ($style instanceof Font) { $paragraphStyle = $style->getParagraphStyle(); $styleType = $style->getStyleType(); $type = $styleType == 'title' ? 'paragraph' : 'character'; if (!is_null($paragraphStyle)) { $type = 'paragraph'; } $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', $type); if ($styleType == 'title') { $arrStyle = explode('_', $styleName); $styleId = 'Heading' . $arrStyle[1]; $styleName = 'heading ' . $arrStyle[1]; $styleLink = 'Heading' . $arrStyle[1] . 'Char'; $xmlWriter->writeAttribute('w:styleId', $styleId); $xmlWriter->startElement('w:link'); $xmlWriter->writeAttribute('w:val', $styleLink); $xmlWriter->endElement(); } $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); if (!is_null($paragraphStyle)) { // Point parent style to Normal $xmlWriter->startElement('w:basedOn'); $xmlWriter->writeAttribute('w:val', 'Normal'); $xmlWriter->endElement(); $styleWriter = new ParagraphStyleWriter($xmlWriter, $paragraphStyle); $styleWriter->write(); } $styleWriter = new FontStyleWriter($xmlWriter, $style); $styleWriter->write(); $xmlWriter->endElement(); // Paragraph style } elseif ($style instanceof Paragraph) { $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', 'paragraph'); $xmlWriter->writeAttribute('w:customStyle', '1'); $xmlWriter->writeAttribute('w:styleId', $styleName); $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); // Parent style $basedOn = $style->getBasedOn(); if (!is_null($basedOn)) { $xmlWriter->startElement('w:basedOn'); $xmlWriter->writeAttribute('w:val', $basedOn); $xmlWriter->endElement(); } // Next paragraph style $next = $style->getNext(); if (!is_null($next)) { $xmlWriter->startElement('w:next'); $xmlWriter->writeAttribute('w:val', $next); $xmlWriter->endElement(); } $styleWriter = new ParagraphStyleWriter($xmlWriter, $style); $styleWriter->write(); $xmlWriter->endElement(); // Table style } elseif ($style instanceof Table) { $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', 'table'); $xmlWriter->writeAttribute('w:customStyle', '1'); $xmlWriter->writeAttribute('w:styleId', $styleName); $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); $xmlWriter->startElement('w:uiPriority'); $xmlWriter->writeAttribute('w:val', '99'); $xmlWriter->endElement(); $styleWriter = new TableStyleWriter($xmlWriter, $style); $styleWriter->write(); $xmlWriter->endElement(); // w:style } } } $xmlWriter->endElement(); // w:styles return $xmlWriter->getData(); }
/** * Write named styles. * * @param \PhpOffice\Common\XMLWriter $xmlWriter * @return void */ private function writeNamed(XMLWriter $xmlWriter) { $styles = Style::getStyles(); if (count($styles) > 0) { foreach ($styles as $style) { if ($style->isAuto() === false) { $styleClass = str_replace('\\Style\\', '\\Writer\\ODText\\Style\\', get_class($style)); if (class_exists($styleClass)) { /** @var $styleWriter \PhpOffice\PhpWord\Writer\ODText\Style\AbstractStyle Type hint */ $styleWriter = new $styleClass($xmlWriter, $style); $styleWriter->write(); } } } } }
/** * Test default paragraph style * * @covers ::setDefaultParagraphStyle * @test */ public function testDefaultParagraphStyle() { $paragraph = array('alignment' => Jc::CENTER); Style::setDefaultParagraphStyle($paragraph); $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Paragraph', Style::getStyle('Normal')); }
/** * Set default paragraph style definition to styles.xml * * @param array $styles Paragraph style definition * @return \PhpOffice\PhpWord\Style\Paragraph */ public function setDefaultParagraphStyle($styles) { return Style::setDefaultParagraphStyle($styles); }
/** * Add a Title Element * * @param string $text * @param int $depth * @return Title * @todo Enable title element in other containers */ public function addTitle($text, $depth = 1) { $this->checkValidity('title'); $styles = Style::getStyles(); if (array_key_exists('Heading_' . $depth, $styles)) { $style = 'Heading' . $depth; } else { $style = null; } $text = String::toUTF8($text); $title = new Title($text, $depth, $style); $title->setDocPart($this->getDocPart(), $this->getDocPartId()); $data = Titles::addTitle($text, $depth); $anchor = $data[0]; $bookmarkId = $data[1]; $title->setAnchor($anchor); $title->setBookmarkId($bookmarkId); $this->addElement($title); return $title; }
/** * Adds a heading style definition to styles.xml * * @param int $depth * @param mixed $fontStyle * @param mixed $paragraphStyle * @return \PhpOffice\PhpWord\Style\Font */ public function addTitleStyle($depth, $fontStyle, $paragraphStyle = null) { return Style::addTitleStyle($depth, $fontStyle, $paragraphStyle); }
/** * Test add title style */ public function testAddTitleStyle() { $phpWord = new PhpWord(); $titleLevel = 1; $titleName = "Heading_{$titleLevel}"; $phpWord->addTitleStyle($titleLevel, array()); $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Font', Style::getStyle($titleName)); }
/** * Write word/numbering.xml */ public function writeNumbering() { $styles = Style::getStyles(); $xmlWriter = $this->getXmlWriter(); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startElement('w:numbering'); $xmlWriter->writeAttribute('xmlns:ve', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); $xmlWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $xmlWriter->writeAttribute('xmlns:m', 'http://schemas.openxmlformats.org/officeDocument/2006/math'); $xmlWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); $xmlWriter->writeAttribute('xmlns:wp', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'); $xmlWriter->writeAttribute('xmlns:w10', 'urn:schemas-microsoft-com:office:word'); $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); $xmlWriter->writeAttribute('xmlns:wne', 'http://schemas.microsoft.com/office/word/2006/wordml'); // Abstract numbering definitions foreach ($styles as $style) { if ($style instanceof NumberingStyle) { $levels = $style->getLevels(); $xmlWriter->startElement('w:abstractNum'); $xmlWriter->writeAttribute('w:abstractNumId', $style->getNumId()); $xmlWriter->startElement('w:nsid'); $xmlWriter->writeAttribute('w:val', $this->getRandomHexNumber()); $xmlWriter->endElement(); // w:nsid $xmlWriter->startElement('w:multiLevelType'); $xmlWriter->writeAttribute('w:val', $style->getType()); $xmlWriter->endElement(); // w:multiLevelType if (is_array($levels)) { foreach ($levels as $levelNum => $levelObject) { if ($levelObject instanceof NumberingLevel) { $start = $levelObject->getStart(); $format = $levelObject->getFormat(); $restart = $levelObject->getRestart(); $suffix = $levelObject->getSuffix(); $text = $levelObject->getText(); $align = $levelObject->getAlign(); $tabPos = $levelObject->getTabPos(); $left = $levelObject->getLeft(); $hanging = $levelObject->getHanging(); $font = $levelObject->getFont(); $hint = $levelObject->getHint(); $xmlWriter->startElement('w:lvl'); $xmlWriter->writeAttribute('w:ilvl', $levelNum); if (!is_null($start)) { $xmlWriter->startElement('w:start'); $xmlWriter->writeAttribute('w:val', $start); $xmlWriter->endElement(); // w:start } if (!is_null($format)) { $xmlWriter->startElement('w:numFmt'); $xmlWriter->writeAttribute('w:val', $format); $xmlWriter->endElement(); // w:numFmt } if (!is_null($restart)) { $xmlWriter->startElement('w:lvlRestart'); $xmlWriter->writeAttribute('w:val', $restart); $xmlWriter->endElement(); // w:lvlRestart } if (!is_null($suffix)) { $xmlWriter->startElement('w:suff'); $xmlWriter->writeAttribute('w:val', $suffix); $xmlWriter->endElement(); // w:suff } if (!is_null($text)) { $xmlWriter->startElement('w:lvlText'); $xmlWriter->writeAttribute('w:val', $text); $xmlWriter->endElement(); // w:start } if (!is_null($align)) { $xmlWriter->startElement('w:lvlJc'); $xmlWriter->writeAttribute('w:val', $align); $xmlWriter->endElement(); // w:lvlJc } if (!is_null($tabPos) || !is_null($left) || !is_null($hanging)) { $xmlWriter->startElement('w:pPr'); if (!is_null($tabPos)) { $xmlWriter->startElement('w:tabs'); $xmlWriter->startElement('w:tab'); $xmlWriter->writeAttribute('w:val', 'num'); $xmlWriter->writeAttribute('w:pos', $tabPos); $xmlWriter->endElement(); // w:tab $xmlWriter->endElement(); // w:tabs } if (!is_null($left) || !is_null($hanging)) { $xmlWriter->startElement('w:ind'); if (!is_null($left)) { $xmlWriter->writeAttribute('w:left', $left); } if (!is_null($hanging)) { $xmlWriter->writeAttribute('w:hanging', $hanging); } $xmlWriter->endElement(); // w:ind } $xmlWriter->endElement(); // w:pPr } if (!is_null($font) || !is_null($hint)) { $xmlWriter->startElement('w:rPr'); $xmlWriter->startElement('w:rFonts'); if (!is_null($font)) { $xmlWriter->writeAttribute('w:ascii', $font); $xmlWriter->writeAttribute('w:hAnsi', $font); $xmlWriter->writeAttribute('w:cs', $font); } if (!is_null($hint)) { $xmlWriter->writeAttribute('w:hint', $hint); } $xmlWriter->endElement(); // w:rFonts $xmlWriter->endElement(); // w:rPr } $xmlWriter->endElement(); // w:lvl } } } $xmlWriter->endElement(); // w:abstractNum } } // Numbering definition instances foreach ($styles as $style) { if ($style instanceof NumberingStyle) { $xmlWriter->startElement('w:num'); $xmlWriter->writeAttribute('w:numId', $style->getNumId()); $xmlWriter->startElement('w:abstractNumId'); $xmlWriter->writeAttribute('w:val', $style->getNumId()); $xmlWriter->endElement(); // w:abstractNumId $xmlWriter->endElement(); // w:num } } $xmlWriter->endElement(); // w:numbering return $xmlWriter->getData(); }
/** * Write Styles file to XML format * * @param \PhpOffice\PhpWord\PhpWord $phpWord * @return string XML Output */ public function writeStyles(PhpWord $phpWord = null) { if (is_null($phpWord)) { throw new Exception("No PhpWord assigned."); } // Create XML writer $xmlWriter = $this->getXmlWriter(); // XML header $xmlWriter->startDocument('1.0', 'UTF-8'); // Styles:Styles $xmlWriter->startElement('office:document-styles'); $this->writeCommonRootAttributes($xmlWriter); // office:font-face-decls $this->writeFontFaces($xmlWriter); // office:styles $xmlWriter->startElement('office:styles'); // style:default-style $xmlWriter->startElement('style:default-style'); $xmlWriter->writeAttribute('style:family', 'paragraph'); // style:paragraph-properties $xmlWriter->startElement('style:paragraph-properties'); $xmlWriter->writeAttribute('fo:hyphenation-ladder-count', 'no-limit'); $xmlWriter->writeAttribute('style:text-autospace', 'ideograph-alpha'); $xmlWriter->writeAttribute('style:punctuation-wrap', 'hanging'); $xmlWriter->writeAttribute('style:line-break', 'strict'); $xmlWriter->writeAttribute('style:tab-stop-distance', '1.249cm'); $xmlWriter->writeAttribute('style:writing-mode', 'page'); $xmlWriter->endElement(); // style:text-properties $xmlWriter->startElement('style:text-properties'); $xmlWriter->writeAttribute('style:use-window-font-color', 'true'); $xmlWriter->writeAttribute('style:font-name', PhpWord::DEFAULT_FONT_NAME); $xmlWriter->writeAttribute('fo:font-size', PhpWord::DEFAULT_FONT_SIZE . 'pt'); $xmlWriter->writeAttribute('fo:language', 'fr'); $xmlWriter->writeAttribute('fo:country', 'FR'); $xmlWriter->writeAttribute('style:letter-kerning', 'true'); $xmlWriter->writeAttribute('style:font-name-asian', PhpWord::DEFAULT_FONT_NAME . '2'); $xmlWriter->writeAttribute('style:font-size-asian', PhpWord::DEFAULT_FONT_SIZE . 'pt'); $xmlWriter->writeAttribute('style:language-asian', 'zh'); $xmlWriter->writeAttribute('style:country-asian', 'CN'); $xmlWriter->writeAttribute('style:font-name-complex', PhpWord::DEFAULT_FONT_NAME . '2'); $xmlWriter->writeAttribute('style:font-size-complex', PhpWord::DEFAULT_FONT_SIZE . 'pt'); $xmlWriter->writeAttribute('style:language-complex', 'hi'); $xmlWriter->writeAttribute('style:country-complex', 'IN'); $xmlWriter->writeAttribute('fo:hyphenate', 'false'); $xmlWriter->writeAttribute('fo:hyphenation-remain-char-count', '2'); $xmlWriter->writeAttribute('fo:hyphenation-push-char-count', '2'); $xmlWriter->endElement(); $xmlWriter->endElement(); // Write Style Definitions $styles = Style::getStyles(); if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if (preg_match('#^T[0-9]+$#', $styleName) == 0 && preg_match('#^P[0-9]+$#', $styleName) == 0) { $styleClass = str_replace('Style', 'Writer\\ODText\\Style', get_class($style)); if (class_exists($styleClass)) { $styleWriter = new $styleClass($xmlWriter, $style); $styleWriter->write(); } } } } $xmlWriter->endElement(); // office:automatic-styles $xmlWriter->startElement('office:automatic-styles'); // style:page-layout $xmlWriter->startElement('style:page-layout'); $xmlWriter->writeAttribute('style:name', 'Mpm1'); // style:page-layout-properties $xmlWriter->startElement('style:page-layout-properties'); $xmlWriter->writeAttribute('fo:page-width', "21.001cm"); $xmlWriter->writeAttribute('fo:page-height', '29.7cm'); $xmlWriter->writeAttribute('style:num-format', '1'); $xmlWriter->writeAttribute('style:print-orientation', 'portrait'); $xmlWriter->writeAttribute('fo:margin-top', '2.501cm'); $xmlWriter->writeAttribute('fo:margin-bottom', '2cm'); $xmlWriter->writeAttribute('fo:margin-left', '2.501cm'); $xmlWriter->writeAttribute('fo:margin-right', '2.501cm'); $xmlWriter->writeAttribute('style:writing-mode', 'lr-tb'); $xmlWriter->writeAttribute('style:layout-grid-color', '#c0c0c0'); $xmlWriter->writeAttribute('style:layout-grid-lines', '25199'); $xmlWriter->writeAttribute('style:layout-grid-base-height', '0.423cm'); $xmlWriter->writeAttribute('style:layout-grid-ruby-height', '0cm'); $xmlWriter->writeAttribute('style:layout-grid-mode', 'none'); $xmlWriter->writeAttribute('style:layout-grid-ruby-below', 'false'); $xmlWriter->writeAttribute('style:layout-grid-print', 'false'); $xmlWriter->writeAttribute('style:layout-grid-display', 'false'); $xmlWriter->writeAttribute('style:layout-grid-base-width', '0.37cm'); $xmlWriter->writeAttribute('style:layout-grid-snap-to', 'true'); $xmlWriter->writeAttribute('style:footnote-max-height', '0cm'); //style:footnote-sep $xmlWriter->startElement('style:footnote-sep'); $xmlWriter->writeAttribute('style:width', '0.018cm'); $xmlWriter->writeAttribute('style:line-style', 'solid'); $xmlWriter->writeAttribute('style:adjustment', 'left'); $xmlWriter->writeAttribute('style:rel-width', '25%'); $xmlWriter->writeAttribute('style:color', '#000000'); $xmlWriter->endElement(); $xmlWriter->endElement(); // style:header-style $xmlWriter->startElement('style:header-style'); $xmlWriter->endElement(); // style:footer-style $xmlWriter->startElement('style:footer-style'); $xmlWriter->endElement(); $xmlWriter->endElement(); $xmlWriter->endElement(); // office:master-styles $xmlWriter->startElement('office:master-styles'); // style:master-page $xmlWriter->startElement('style:master-page'); $xmlWriter->writeAttribute('style:name', 'Standard'); $xmlWriter->writeAttribute('style:page-layout-name', 'Mpm1'); $xmlWriter->endElement(); $xmlWriter->endElement(); $xmlWriter->endElement(); // Return return $xmlWriter->getData(); }
/** * Set default paragraph style */ public function testDefaultParagraphStyle() { $paragraph = array('align' => 'center'); Style::setDefaultParagraphStyle($paragraph); $this->assertInstanceOf("PhpOffice\\PhpWord\\Style\\Paragraph", Style::getStyle('Normal')); }
/** * Write numbering. * * @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter * @param array $numbering * @return void */ private function writeNumbering(XMLWriter $xmlWriter, $numbering) { $numStyle = $numbering['style']; $numLevel = $numbering['level']; /** @var \PhpOffice\PhpWord\Style\Numbering $numbering */ $numbering = Style::getStyle($numStyle); if ($numStyle !== null && $numbering !== null) { $xmlWriter->startElement('w:numPr'); $xmlWriter->startElement('w:numId'); $xmlWriter->writeAttribute('w:val', $numbering->getIndex()); $xmlWriter->endElement(); // w:numId $xmlWriter->startElement('w:ilvl'); $xmlWriter->writeAttribute('w:val', $numLevel); $xmlWriter->endElement(); // w:ilvl $xmlWriter->endElement(); // w:numPr $xmlWriter->startElement('w:outlineLvl'); $xmlWriter->writeAttribute('w:val', $numLevel); $xmlWriter->endElement(); // w:outlineLvl } }
/** * Adds a numbering style * * @param string $styleName * @param mixed $styles */ public function addNumberingStyle($styleName, $styles) { Style::addNumberingStyle($styleName, $styles); }
/** * Write element */ public function write() { $rtfText = ''; $fontStyle = $this->element->getFontStyle(); if (is_string($fontStyle)) { $fontStyle = Style::getStyle($fontStyle); } $paragraphStyle = $this->element->getParagraphStyle(); if (is_string($paragraphStyle)) { $paragraphStyle = Style::getStyle($paragraphStyle); } if ($paragraphStyle && !$this->withoutP) { if ($this->parentWriter->getLastParagraphStyle() != $this->element->getParagraphStyle()) { $rtfText .= '\\pard\\nowidctlpar'; if ($paragraphStyle->getSpaceAfter() != null) { $rtfText .= '\\sa' . $paragraphStyle->getSpaceAfter(); } if ($paragraphStyle->getAlign() != null) { if ($paragraphStyle->getAlign() == 'center') { $rtfText .= '\\qc'; } } $this->parentWriter->setLastParagraphStyle($this->element->getParagraphStyle()); } else { $this->parentWriter->setLastParagraphStyle(); } } else { $this->parentWriter->setLastParagraphStyle(); } if ($fontStyle instanceof Font) { if ($fontStyle->getColor() != null) { $idxColor = array_search($fontStyle->getColor(), $this->parentWriter->getColorTable()); if ($idxColor !== false) { $rtfText .= '\\cf' . ($idxColor + 1); } } else { $rtfText .= '\\cf0'; } if ($fontStyle->getName() != null) { $idxFont = array_search($fontStyle->getName(), $this->parentWriter->getFontTable()); if ($idxFont !== false) { $rtfText .= '\\f' . $idxFont; } } else { $rtfText .= '\\f0'; } if ($fontStyle->getBold()) { $rtfText .= '\\b'; } if ($fontStyle->getItalic()) { $rtfText .= '\\i'; } if ($fontStyle->getSize()) { $rtfText .= '\\fs' . $fontStyle->getSize() * 2; } } if ($this->parentWriter->getLastParagraphStyle() != '' || $fontStyle) { $rtfText .= ' '; } $rtfText .= $this->element->getText(); if ($fontStyle instanceof Font) { $rtfText .= '\\cf0'; $rtfText .= '\\f0'; if ($fontStyle->getBold()) { $rtfText .= '\\b0'; } if ($fontStyle->getItalic()) { $rtfText .= '\\i0'; } if ($fontStyle->getSize()) { $rtfText .= '\\fs' . PhpWord::DEFAULT_FONT_SIZE * 2; } } if (!$this->withoutP) { $rtfText .= '\\par' . PHP_EOL; } return $rtfText; }
/** * Get all styles of each elements in container recursively * * Table style can be null or string of the style name * * @param \PhpOffice\PhpWord\Element\AbstractContainer $container * @param int &$paragraphStyleCount * @param int &$fontStyleCount * @return void * @todo Simplify the logic */ private function getContainerStyle($container, &$paragraphStyleCount, &$fontStyleCount) { $elements = $container->getElements(); foreach ($elements as $element) { if ($element instanceof TextRun) { $this->getContainerStyle($element, $paragraphStyleCount, $fontStyleCount); } elseif ($element instanceof Text) { $this->getElementStyle($element, $paragraphStyleCount, $fontStyleCount); } elseif ($element instanceof Image) { $style = $element->getStyle(); $style->setStyleName('fr' . $element->getMediaIndex()); $this->autoStyles['Image'][] = $style; } elseif ($element instanceof Table) { $style = $element->getStyle(); if ($style === null) { $style = new TableStyle(); } elseif (is_string($style)) { $style = Style::getStyle($style); } $style->setStyleName($element->getElementId()); $this->autoStyles['Table'][] = $style; } } }
/** * Register all fonts and colors in both named and inline styles to appropriate header table */ private function registerFont() { $phpWord = $this->getParentWriter()->getPhpWord(); $this->fontTable[] = Settings::getDefaultFontName(); // Search named styles $styles = Style::getStyles(); foreach ($styles as $style) { $this->registerFontItems($style); } // Search inline styles $sections = $phpWord->getSections(); foreach ($sections as $section) { $elements = $section->getElements(); foreach ($elements as $element) { if (method_exists($element, 'getFontStyle')) { $style = $element->getFontStyle(); $this->registerFontItems($style); } } } }
/** * Get legacy numbering definition * * @return array * @since 0.10.0 */ private function getListTypeStyle() { // Check if legacy style already registered in global Style collection $numStyle = "PHPWordList{$this->listType}"; if (Style::getStyle($numStyle) !== null) { $this->setNumStyle($numStyle); return; } // Property mapping for numbering level information $properties = array('start', 'format', 'text', 'alignment', 'tabPos', 'left', 'hanging', 'font', 'hint'); // Legacy level information $listTypeStyles = array(self::TYPE_SQUARE_FILLED => array('type' => 'hybridMultilevel', 'levels' => array(0 => '1, bullet, , left, 720, 720, 360, Wingdings, default', 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default')), self::TYPE_BULLET_FILLED => array('type' => 'hybridMultilevel', 'levels' => array(0 => '1, bullet, , left, 720, 720, 360, Symbol, default', 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default')), self::TYPE_BULLET_EMPTY => array('type' => 'hybridMultilevel', 'levels' => array(0 => '1, bullet, o, left, 720, 720, 360, Courier New, default', 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default')), self::TYPE_NUMBER => array('type' => 'hybridMultilevel', 'levels' => array(0 => '1, decimal, %1., left, 720, 720, 360, , default', 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default')), self::TYPE_NUMBER_NESTED => array('type' => 'multilevel', 'levels' => array(0 => '1, decimal, %1., left, 360, 360, 360, , ', 1 => '1, decimal, %1.%2., left, 792, 792, 432, , ', 2 => '1, decimal, %1.%2.%3., left, 1224, 1224, 504, , ', 3 => '1, decimal, %1.%2.%3.%4., left, 1800, 1728, 648, , ', 4 => '1, decimal, %1.%2.%3.%4.%5., left, 2520, 2232, 792, , ', 5 => '1, decimal, %1.%2.%3.%4.%5.%6., left, 2880, 2736, 936, , ', 6 => '1, decimal, %1.%2.%3.%4.%5.%6.%7., left, 3600, 3240, 1080, , ', 7 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8., left, 3960, 3744, 1224, , ', 8 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8.%9., left, 4680, 4320, 1440, , ')), self::TYPE_ALPHANUM => array('type' => 'multilevel', 'levels' => array(0 => '1, decimal, %1., left, 720, 720, 360, , ', 1 => '1, lowerLetter, %2., left, 1440, 1440, 360, , ', 2 => '1, lowerRoman, %3., right, 2160, 2160, 180, , ', 3 => '1, decimal, %4., left, 2880, 2880, 360, , ', 4 => '1, lowerLetter, %5., left, 3600, 3600, 360, , ', 5 => '1, lowerRoman, %6., right, 4320, 4320, 180, , ', 6 => '1, decimal, %7., left, 5040, 5040, 360, , ', 7 => '1, lowerLetter, %8., left, 5760, 5760, 360, , ', 8 => '1, lowerRoman, %9., right, 6480, 6480, 180, , '))); // Populate style and register to global Style register $style = $listTypeStyles[$this->listType]; foreach ($style['levels'] as $key => $value) { $level = array(); $levelProperties = explode(', ', $value); $level['level'] = $key; for ($i = 0; $i < count($properties); $i++) { $property = $properties[$i]; $level[$property] = $levelProperties[$i]; } $style['levels'][$key] = $level; } Style::addNumberingStyle($numStyle, $style); $this->setNumStyle($numStyle); }
/** * Get all colors * * @return array */ private function populateColorTable() { $phpWord = $this->phpWord; $arrColors = array(); // PhpWord object : $this->phpWord // Browse styles $styles = Style::getStyles(); if (count($styles) > 0) { foreach ($styles as $style) { // Font if ($style instanceof Font) { $color = $style->getColor(); $fgcolor = $style->getFgColor(); if (in_array($color, $arrColors) == false && $color != PhpWord::DEFAULT_FONT_COLOR && !empty($color)) { $arrColors[] = $color; } if (in_array($fgcolor, $arrColors) == false && $fgcolor != PhpWord::DEFAULT_FONT_COLOR && !empty($fgcolor)) { $arrColors[] = $fgcolor; } } } } // Search all fonts used $sections = $phpWord->getSections(); $countSections = count($sections); if ($countSections > 0) { $pSection = 0; foreach ($sections as $section) { $pSection++; $elements = $section->getElements(); foreach ($elements as $element) { if ($element instanceof Text) { $fontStyle = $element->getFontStyle(); if ($fontStyle instanceof Font) { if (in_array($fontStyle->getColor(), $arrColors) == false) { $arrColors[] = $fontStyle->getColor(); } if (in_array($fontStyle->getFgColor(), $arrColors) == false) { $arrColors[] = $fontStyle->getFgColor(); } } } } } } return $arrColors; }
/** * Write automatic styles */ private function writeAutomaticStyles(XMLWriter $xmlWriter, PhpWord $phpWord) { $xmlWriter->startElement('office:automatic-styles'); // Font and paragraph $styles = Style::getStyles(); $paragraphStyleCount = 0; if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if (preg_match('#^T[0-9]+$#', $styleName) != 0 || preg_match('#^P[0-9]+$#', $styleName) != 0) { $styleClass = str_replace('Style', 'Writer\\ODText\\Style', get_class($style)); if (class_exists($styleClass)) { $styleWriter = new $styleClass($xmlWriter, $style); $styleWriter->setIsAuto(true); $styleWriter->write(); } if ($style instanceof Paragraph) { $paragraphStyleCount++; } } } if ($paragraphStyleCount == 0) { $style = new Paragraph(); $style->setStyleName('P1'); $styleWriter = new \PhpOffice\PhpWord\Writer\ODText\Style\Paragraph($xmlWriter, $style); $styleWriter->setIsAuto(true); $styleWriter->write(); } } // Images $images = Media::getElements('section'); foreach ($images as $image) { if ($image['type'] == 'image') { $xmlWriter->startElement('style:style'); $xmlWriter->writeAttribute('style:name', 'fr' . $image['rID']); $xmlWriter->writeAttribute('style:family', 'graphic'); $xmlWriter->writeAttribute('style:parent-style-name', 'Graphics'); $xmlWriter->startElement('style:graphic-properties'); $xmlWriter->writeAttribute('style:vertical-pos', 'top'); $xmlWriter->writeAttribute('style:vertical-rel', 'baseline'); $xmlWriter->endElement(); $xmlWriter->endElement(); } } // Tables $sections = $phpWord->getSections(); $sectionCount = count($sections); if ($sectionCount > 0) { $sectionId = 0; foreach ($sections as $section) { $sectionId++; $elements = $section->getElements(); foreach ($elements as $element) { if ($elements instanceof Table) { $xmlWriter->startElement('style:style'); $xmlWriter->writeAttribute('style:name', $element->getElementId()); $xmlWriter->writeAttribute('style:family', 'table'); $xmlWriter->startElement('style:table-properties'); //$xmlWriter->writeAttribute('style:width', 'table'); $xmlWriter->writeAttribute('style:rel-width', 100); $xmlWriter->writeAttribute('table:align', 'center'); $xmlWriter->endElement(); $xmlWriter->endElement(); } } } } $xmlWriter->endElement(); // office:automatic-styles }