diff --git a/Classes/PHPWord.php b/Classes/PHPWord.php index d24b9e44..658585b7 100755 --- a/Classes/PHPWord.php +++ b/Classes/PHPWord.php @@ -39,6 +39,9 @@ if (!defined('PHPWORD_BASE_PATH')) { class PHPWord { + const DEFAULT_FONT_NAME = 'Arial'; + const DEFAULT_FONT_SIZE = 20; + /** * Document properties * @@ -74,8 +77,8 @@ class PHPWord public function __construct() { $this->_properties = new PHPWord_DocumentProperties(); - $this->_defaultFontName = 'Arial'; - $this->_defaultFontSize = 20; + $this->_defaultFontName = PHPWord::DEFAULT_FONT_NAME; + $this->_defaultFontSize = PHPWord::DEFAULT_FONT_SIZE; } /** diff --git a/Classes/PHPWord/Section/Settings.php b/Classes/PHPWord/Section/Settings.php index fce8d7b1..ba595259 100755 --- a/Classes/PHPWord/Section/Settings.php +++ b/Classes/PHPWord/Section/Settings.php @@ -168,6 +168,34 @@ class PHPWord_Section_Settings */ private $footerHeight; + /** + * Section columns count + * + * @var int + */ + private $_colsNum; + + /** + * Section spacing between columns + * + * @var int + */ + private $_colsSpace; + + /** + * Section break type + * + * Options: + * - nextPage: Next page section break + * - nextColumn: Column section break + * - continuous: Continuous section break + * - evenPage: Even page section break + * - oddPage: Odd page section break + * + * @var string + */ + private $_breakType; + /** * Create new Section Settings */ @@ -190,6 +218,9 @@ class PHPWord_Section_Settings $this->_borderBottomColor = null; $this->headerHeight = 720; // set default header and footer to 720 twips (.5 inches) $this->footerHeight = 720; + $this->_colsNum = 1; + $this->_colsSpace = 720; + $this->_breakType = null; } /** @@ -618,4 +649,62 @@ class PHPWord_Section_Settings $this->footerHeight = $pValue; return $this; } + + /** + * Set Section Columns Count + * + * @param in $pValue + */ + public function setColsNum($pValue = '') { + $this->_colsNum = $pValue; + return $this; + } + + /** + * Get Section Columns Count + * + * @return int + */ + public function getColsNum() { + return $this->_colsNum; + } + + /** + * Set Section Space Between Columns + * + * @param int $pValue + */ + public function setColsSpace($pValue = '') { + $this->_colsSpace = $pValue; + return $this; + } + + /** + * Get Section Space Between Columns + * + * @return int + */ + public function getColsSpace() { + return $this->_colsSpace; + } + + /** + * Set Break Type + * + * @param string $pValue + */ + public function setBreakType($pValue = null) { + $this->_breakType = $pValue; + return $this; + } + + /** + * Get Break Type + * + * @return string + */ + public function getBreakType() { + return $this->_breakType; + } + } diff --git a/Classes/PHPWord/Section/Table.php b/Classes/PHPWord/Section/Table.php index 6d68351a..081b6484 100755 --- a/Classes/PHPWord/Section/Table.php +++ b/Classes/PHPWord/Section/Table.php @@ -45,13 +45,6 @@ class PHPWord_Section_Table */ private $_rows = array(); - /** - * Row heights - * - * @var array - */ - private $_rowHeights = array(); - /** * Table holder * @@ -66,6 +59,13 @@ class PHPWord_Section_Table */ private $_pCount; + /** + * Table width + * + * @var int + */ + private $_width = null; + /** * Create a new table @@ -100,10 +100,11 @@ class PHPWord_Section_Table * * @param int $height */ - public function addRow($height = null) + public function addRow($height = null, $style = null) { - $this->_rows[] = array(); - $this->_rowHeights[] = $height; + $row = new PHPWord_Section_Table_Row($this->_insideOf, $this->_pCount, $height, $style); + $this->_rows[] = $row; + return $row; } /** @@ -113,11 +114,10 @@ class PHPWord_Section_Table * @param mixed $style * @return PHPWord_Section_Table_Cell */ - public function addCell($width, $style = null) + public function addCell($width = null, $style = null) { - $cell = new PHPWord_Section_Table_Cell($this->_insideOf, $this->_pCount, $width, $style); $i = count($this->_rows) - 1; - $this->_rows[$i][] = $cell; + $cell = $this->_rows[$i]->addCell($width, $style); return $cell; } @@ -131,16 +131,6 @@ class PHPWord_Section_Table return $this->_rows; } - /** - * Get all row heights - * - * @return array - */ - public function getRowHeights() - { - return $this->_rowHeights; - } - /** * Get table style * @@ -150,4 +140,25 @@ class PHPWord_Section_Table { return $this->_style; } + + /** + * Set table width + * + * @var int $width + */ + public function setWidth($width) + { + $this->_width = $width; + } + + /** + * Get table width + * + * @return int + */ + public function getWidth() + { + return $this->_width; + } + } diff --git a/Classes/PHPWord/Section/Table/Row.php b/Classes/PHPWord/Section/Table/Row.php new file mode 100644 index 00000000..c2db614b --- /dev/null +++ b/Classes/PHPWord/Section/Table/Row.php @@ -0,0 +1,141 @@ +_insideOf = $insideOf; + $this->_pCount = $pCount; + $this->_height = $height; + $this->_style = new PHPWord_Style_Row(); + + if (!is_null($style)) { + if (is_array($style)) { + + foreach ($style as $key => $value) { + if (substr($key, 0, 1) != '_') { + $key = '_' . $key; + } + $this->_style->setStyleValue($key, $value); + } + } + } + } + + /** + * Add a cell + * + * @param int $width + * @param mixed $style + * @return PHPWord_Section_Table_Cell + */ + public function addCell($width = null, $style = null) + { + $cell = new PHPWord_Section_Table_Cell($this->_insideOf, $this->_pCount, $width, $style); + $this->_cells[] = $cell; + return $cell; + } + + /** + * Get all cells + * + * @return array + */ + public function getCells() + { + return $this->_cells; + } + + /** + * Get row style + * + * @return PHPWord_Style_Row + */ + public function getStyle() + { + return $this->_style; + } + + /** + * Get row height + * + * @return int + */ + public function getHeight() + { + return $this->_height; + } +} \ No newline at end of file diff --git a/Classes/PHPWord/Style/Font.php b/Classes/PHPWord/Style/Font.php index e273dd35..3363dc66 100755 --- a/Classes/PHPWord/Style/Font.php +++ b/Classes/PHPWord/Style/Font.php @@ -94,8 +94,8 @@ class PHPWord_Style_Font public function __construct($type = 'text', $styleParagraph = null) { $this->_type = $type; - $this->_name = 'Arial'; - $this->_size = 20; + $this->_name = PHPWord::DEFAULT_FONT_NAME; + $this->_size = PHPWord::DEFAULT_FONT_SIZE; $this->_bold = false; $this->_italic = false; $this->_superScript = false; @@ -132,10 +132,10 @@ class PHPWord_Style_Font $this->$key = $value; } - public function setName($pValue = 'Arial') + public function setName($pValue = PHPWord::DEFAULT_FONT_NAME) { if ($pValue == '') { - $pValue = 'Arial'; + $pValue = PHPWord::DEFAULT_FONT_NAME; } $this->_name = $pValue; return $this; @@ -146,10 +146,10 @@ class PHPWord_Style_Font return $this->_size; } - public function setSize($pValue = 20) + public function setSize($pValue = PHPWord::DEFAULT_FONT_SIZE) { if ($pValue == '') { - $pValue = 20; + $pValue = PHPWord::DEFAULT_FONT_SIZE; } $this->_size = ($pValue * 2); return $this; diff --git a/Classes/PHPWord/Style/Paragraph.php b/Classes/PHPWord/Style/Paragraph.php index ab285ebe..3c2639be 100755 --- a/Classes/PHPWord/Style/Paragraph.php +++ b/Classes/PHPWord/Style/Paragraph.php @@ -73,6 +73,12 @@ class PHPWord_Style_Paragraph */ private $_indent; + /** + * Hanging by how much + * + * @var int + */ + private $_hanging; /** * New Paragraph Style @@ -85,6 +91,7 @@ class PHPWord_Style_Paragraph $this->_spacing = null; $this->_tabs = null; $this->_indent = null; + $this->_hanging = null; } /** @@ -96,7 +103,10 @@ class PHPWord_Style_Paragraph public function setStyleValue($key, $value) { if ($key == '_indent') { - $value = (int)$value * 720; // 720 twips per indent + $value = $value * 720; // 720 twips per indent + } + if ($key == '_hanging') { + $value = $value * 720; } if ($key == '_spacing') { $value += 240; // because line height of 1 matches 240 twips @@ -221,6 +231,28 @@ class PHPWord_Style_Paragraph return $this; } + /** + * Set hanging + * + * @param int $pValue + * @return PHPWord_Style_Paragraph + */ + public function setHanging($pValue = null) + { + $this->_hanging = $pValue; + return $this; + } + + /** + * Get hanging + * + * @return int + */ + public function getHanging() + { + return $this->_hanging; + } + /** * Get tabs * diff --git a/Classes/PHPWord/Style/Row.php b/Classes/PHPWord/Style/Row.php new file mode 100644 index 00000000..a0e79b3a --- /dev/null +++ b/Classes/PHPWord/Style/Row.php @@ -0,0 +1,85 @@ +_tblHeader = null; + $this->_cantSplit = null; + } + + /** + * Set style value + */ + public function setStyleValue($key, $value) + { + $this->$key = $value; + } + + public function setTblHeader($pValue = null) + { + $this->_tblHeader = $pValue; + } + + public function getTblHeader() + { + return $this->_tblHeader ? 1 : 0; + } + + public function setCantSplit($pValue = null) + { + $this->_cantSplit = $pValue; + } + + public function getCantSplit() + { + return $this->_cantSplit ? 1 : 0; + } + +} \ No newline at end of file diff --git a/Classes/PHPWord/Writer/ODText/Content.php b/Classes/PHPWord/Writer/ODText/Content.php index d2690aff..84806f48 100755 --- a/Classes/PHPWord/Writer/ODText/Content.php +++ b/Classes/PHPWord/Writer/ODText/Content.php @@ -145,10 +145,10 @@ class PHPWord_Writer_ODText_Content extends PHPWord_Writer_ODText_WriterPart } } } - if (!in_array('Arial', $arrFonts)) { + if (!in_array(PHPWord::DEFAULT_FONT_NAME, $arrFonts)) { $objWriter->startElement('style:font-face'); - $objWriter->writeAttribute('style:name', 'Arial'); - $objWriter->writeAttribute('svg:font-family', 'Arial'); + $objWriter->writeAttribute('style:name', PHPWord::DEFAULT_FONT_NAME); + $objWriter->writeAttribute('svg:font-family', PHPWord::DEFAULT_FONT_NAME); $objWriter->endElement(); } } diff --git a/Classes/PHPWord/Writer/ODText/Styles.php b/Classes/PHPWord/Writer/ODText/Styles.php index 3c485e55..fd56b7fa 100755 --- a/Classes/PHPWord/Writer/ODText/Styles.php +++ b/Classes/PHPWord/Writer/ODText/Styles.php @@ -104,10 +104,10 @@ class PHPWord_Writer_ODText_Styles extends PHPWord_Writer_ODText_WriterPart } } } - if (!in_array('Arial', $arrFonts)) { + if (!in_array(PHPWord::DEFAULT_FONT_NAME, $arrFonts)) { $objWriter->startElement('style:font-face'); - $objWriter->writeAttribute('style:name', 'Arial'); - $objWriter->writeAttribute('svg:font-family', 'Arial'); + $objWriter->writeAttribute('style:name', PHPWord::DEFAULT_FONT_NAME); + $objWriter->writeAttribute('svg:font-family', PHPWord::DEFAULT_FONT_NAME); $objWriter->endElement(); } $objWriter->endElement(); @@ -132,7 +132,7 @@ class PHPWord_Writer_ODText_Styles extends PHPWord_Writer_ODText_WriterPart // style:text-properties $objWriter->startElement('style:text-properties'); $objWriter->writeAttribute('style:use-window-font-color', 'true'); - $objWriter->writeAttribute('style:font-name', 'Arial'); + $objWriter->writeAttribute('style:font-name', PHPWord::DEFAULT_FONT_NAME); $objWriter->writeAttribute('fo:font-size', '10pt'); $objWriter->writeAttribute('fo:language', 'fr'); $objWriter->writeAttribute('fo:country', 'FR'); diff --git a/Classes/PHPWord/Writer/RTF.php b/Classes/PHPWord/Writer/RTF.php index ebaa00da..42b544fb 100755 --- a/Classes/PHPWord/Writer/RTF.php +++ b/Classes/PHPWord/Writer/RTF.php @@ -191,8 +191,8 @@ class PHPWord_Writer_RTF implements PHPWord_Writer_IWriter $pPHPWord = $this->_document; $arrFonts = array(); - // Default font : Arial - $arrFonts[] = 'Arial'; + // Default font : PHPWord::DEFAULT_FONT_NAME + $arrFonts[] = PHPWord::DEFAULT_FONT_NAME; // PHPWord object : $this->_document // Browse styles diff --git a/Classes/PHPWord/Writer/Word2007/Base.php b/Classes/PHPWord/Writer/Word2007/Base.php index a90126d9..d9d2cb09 100755 --- a/Classes/PHPWord/Writer/Word2007/Base.php +++ b/Classes/PHPWord/Writer/Word2007/Base.php @@ -122,6 +122,7 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $spaceAfter = $style->getSpaceAfter(); $spacing = $style->getSpacing(); $indent = $style->getIndent(); + $hanging = $style->getHanging(); $tabs = $style->getTabs(); if (!is_null($align) || !is_null($spacing) || !is_null($spaceBefore) || !is_null($spaceAfter) || !is_null($indent) || !is_null($tabs)) { @@ -135,10 +136,15 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $objWriter->endElement(); } - if (!is_null($indent)) { + if (!is_null($indent) || !is_null($hanging)) { $objWriter->startElement('w:ind'); $objWriter->writeAttribute('w:firstLine', 0); - $objWriter->writeAttribute('w:left', $indent); + if (!is_null($indent)) { + $objWriter->writeAttribute('w:left', $indent); + } + if (!is_null($hanging)) { + $objWriter->writeAttribute('w:hanging', $hanging); + } $objWriter->endElement(); } @@ -322,11 +328,13 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $fgColor = $style->getFgColor(); $striketrough = $style->getStrikethrough(); $underline = $style->getUnderline(); + $superscript = $style->getSuperScript(); + $subscript = $style->getSubScript(); $objWriter->startElement('w:rPr'); // Font - if ($font != 'Arial') { + if ($font != PHPWord::DEFAULT_FONT_NAME) { $objWriter->startElement('w:rFonts'); $objWriter->writeAttribute('w:ascii', $font); $objWriter->writeAttribute('w:hAnsi', $font); @@ -342,7 +350,7 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart } // Size - if ($size != 20) { + if ($size != PHPWord::DEFAULT_FONT_SIZE) { $objWriter->startElement('w:sz'); $objWriter->writeAttribute('w:val', $size); $objWriter->endElement(); @@ -381,6 +389,13 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $objWriter->endElement(); } + // Superscript/subscript + if ($superscript || $subscript) { + $objWriter->startElement('w:vertAlign'); + $objWriter->writeAttribute('w:val', $superscript ? 'superscript' : 'subscript'); + $objWriter->endElement(); + } + $objWriter->endElement(); } @@ -397,6 +412,7 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart if ($_cRows > 0) { $objWriter->startElement('w:tbl'); $tblStyle = $table->getStyle(); + $tblWidth = $table->getWidth(); if ($tblStyle instanceof PHPWord_Style_Table) { $this->_writeTableStyle($objWriter, $tblStyle); } else { @@ -405,26 +421,46 @@ class PHPWord_Writer_Word2007_Base extends PHPWord_Writer_Word2007_WriterPart $objWriter->startElement('w:tblStyle'); $objWriter->writeAttribute('w:val', $tblStyle); $objWriter->endElement(); + if (!is_null($tblWidth)) { + $objWriter->startElement('w:tblW'); + $objWriter->writeAttribute('w:w', $tblWidth); + $objWriter->writeAttribute('w:type', 'pct'); + $objWriter->endElement(); + } $objWriter->endElement(); } } - $_heights = $table->getRowHeights(); for ($i = 0; $i < $_cRows; $i++) { $row = $_rows[$i]; - $height = $_heights[$i]; + $height = $row->getHeight(); + $rowStyle = $row->getStyle(); + $tblHeader = $rowStyle->getTblHeader(); + $cantSplit = $rowStyle->getCantSplit(); $objWriter->startElement('w:tr'); - if (!is_null($height)) { + if (!is_null($height) || !is_null($tblHeader) || !is_null($cantSplit)) { $objWriter->startElement('w:trPr'); - $objWriter->startElement('w:trHeight'); - $objWriter->writeAttribute('w:val', $height); - $objWriter->endElement(); + if (!is_null($height)) { + $objWriter->startElement('w:trHeight'); + $objWriter->writeAttribute('w:val', $height); + $objWriter->endElement(); + } + if (!is_null($tblHeader)) { + $objWriter->startElement('w:tblHeader'); + $objWriter->writeAttribute('w:val', $tblHeader); + $objWriter->endElement(); + } + if (!is_null($cantSplit)) { + $objWriter->startElement('w:cantSplit'); + $objWriter->writeAttribute('w:val', $cantSplit); + $objWriter->endElement(); + } $objWriter->endElement(); } - foreach ($row as $cell) { + foreach ($row->getCells() as $cell) { $objWriter->startElement('w:tc'); $cellStyle = $cell->getStyle(); diff --git a/Classes/PHPWord/Writer/Word2007/Document.php b/Classes/PHPWord/Writer/Word2007/Document.php index 8722e53b..9fc2160a 100755 --- a/Classes/PHPWord/Writer/Word2007/Document.php +++ b/Classes/PHPWord/Writer/Word2007/Document.php @@ -140,6 +140,10 @@ class PHPWord_Writer_Word2007_Document extends PHPWord_Writer_Word2007_Base $borders = $settings->getBorderSize(); + $colsNum = $settings->getColsNum(); + $colsSpace = $settings->getColsSpace(); + $breakType = $settings->getBreakType(); + $objWriter->startElement('w:sectPr'); foreach ($_headers as &$_header) { @@ -155,6 +159,12 @@ class PHPWord_Writer_Word2007_Document extends PHPWord_Writer_Word2007_Base $objWriter->endElement(); } + if (!is_null($breakType)) { + $objWriter->startElement('w:type'); + $objWriter->writeAttribute('w:val', $breakType); + $objWriter->endElement(); + } + if (!is_null($_footer)) { $rId = $_footer->getRelationId(); $objWriter->startElement('w:footerReference'); @@ -236,7 +246,8 @@ class PHPWord_Writer_Word2007_Document extends PHPWord_Writer_Word2007_Base } $objWriter->startElement('w:cols'); - $objWriter->writeAttribute('w:space', '720'); + $objWriter->writeAttribute('w:num', $colsNum); + $objWriter->writeAttribute('w:space', $colsSpace); $objWriter->endElement(); diff --git a/changelog.txt b/changelog.txt index 27ee52bd..1533a052 100755 --- a/changelog.txt +++ b/changelog.txt @@ -23,6 +23,11 @@ ************************************************************************************** Changes in branch for release 0.7.1 : +- Feature: (ivanlanin) - Table row: Repeat as header row & allow row to break across pages +- Feature: (ivanlanin) - Table: Table width in percentage +- Feature: (ivanlanin) - Font: Superscript and subscript +- Feature: (ivanlanin) - Paragraph: Hanging paragraph +- Feature: (ivanlanin) - Section: Multicolumn and section break - Bugfix: (gabrielbull) - Fixed bug with cell styling - Bugfix: (gabrielbull) - Fixed bug list items inside of cells - Feature: (RomanSyroeshko) GH-56 GH-57 - Template : Permit to save a template generated as a file (PHPWord_Template::saveAs()) diff --git a/samples/Sample_04_Textrun.php b/samples/Sample_04_Textrun.php index 80ad2d3c..164afc3c 100644 --- a/samples/Sample_04_Textrun.php +++ b/samples/Sample_04_Textrun.php @@ -30,6 +30,11 @@ $textrun = $section->createTextRun('pStyle'); $textrun->addText('Each textrun can contain native text, link elements or an image.'); $textrun->addText(' No break is placed after adding an element.', 'BoldText'); +$textrun->addText(' Both '); +$textrun->addText('superscript', array('superScript' => true)); +$textrun->addText(' and '); +$textrun->addText('subscript', array('subScript' => true)); +$textrun->addText(' are also available.'); $textrun->addText(' All elements are placed inside a paragraph with the optionally given p-Style.', 'ColoredText'); $textrun->addText(' Sample Link: '); $textrun->addLink('http://www.google.com', null, 'NLink'); diff --git a/samples/Sample_05_Multicolumn.php b/samples/Sample_05_Multicolumn.php new file mode 100644 index 00000000..a7889a85 --- /dev/null +++ b/samples/Sample_05_Multicolumn.php @@ -0,0 +1,66 @@ +'); +} + +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); +$filler = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' . + 'Nulla fermentum, tortor id adipiscing adipiscing, tortor turpis commodo. ' . + 'Donec vulputate iaculis metus, vel luctus dolor hendrerit ac. ' . + 'Suspendisse congue congue leo sed pellentesque.'; + +// Normal +$section = $PHPWord->createSection(); +$section->addText('Normal paragraph. ' . $filler); + +// Two columns +$section = $PHPWord->createSection(array( + 'colsNum' => 2, + 'colsSpace' => 1440, + 'breakType' => 'continuous')); +$section->addText('Three columns, one inch (1440 twips) spacing. ' . $filler); + +// Normal +$section = $PHPWord->createSection(array('breakType' => 'continuous')); +$section->addText('Normal paragraph again. ' . $filler); + +// Three columns +$section = $PHPWord->createSection(array( + 'colsNum' => 3, + 'colsSpace' => 720, + 'breakType' => 'continuous')); +$section->addText('Three columns, half inch (720 twips) spacing. ' . $filler); + +// Normal +$section = $PHPWord->createSection(array('breakType' => 'continuous')); +$section->addText('Normal paragraph again.'); + +// Save File +echo date('H:i:s') , " Write to Word2007 format" , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); +$objWriter->save(str_replace('.php', '.docx', __FILE__)); + +// echo date('H:i:s') , " Write to OpenDocumentText format" , EOL; +// $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); +// $objWriter->save(str_replace('.php', '.odt', __FILE__)); + +// echo date('H:i:s') , " Write to RTF format" , EOL; +// $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); +// $objWriter->save(str_replace('.php', '.rtf', __FILE__)); + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL;