Update cloneRow function to support vertical spanned cells.
This commit is contained in:
parent
21589ffa61
commit
590f08c42b
|
|
@ -121,35 +121,90 @@ class PHPWord_Template
|
||||||
preg_match_all('/\$\{(.*?)}/i', $this->_documentXML, $matches);
|
preg_match_all('/\$\{(.*?)}/i', $this->_documentXML, $matches);
|
||||||
return $matches[1];
|
return $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the start position of the nearest table row before $offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*/
|
||||||
|
private function _findRowStart($offset) {
|
||||||
|
return strrpos($this->_documentXML, "<w:tr ", ((strlen($this->_documentXML) - $offset) * -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the end position of the nearest table row after $offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*/
|
||||||
|
private function _findRowEnd($offset) {
|
||||||
|
return strpos($this->_documentXML, "</w:tr>", $offset) + 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a slice of a string
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*/
|
||||||
|
private function _getSlice($startPosition, $endPosition = 0) {
|
||||||
|
if (!$endPosition) {
|
||||||
|
$endPosition = strlen($this->_documentXML);
|
||||||
|
}
|
||||||
|
return substr($this->_documentXML, $startPosition, ($endPosition - $startPosition));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone a table row in a template document
|
* Clone a table row in a template document
|
||||||
*
|
*
|
||||||
* @param mixed $search
|
* @param mixed $search
|
||||||
* @param mixed $numberOfClones
|
* @param mixed $numberOfClones
|
||||||
*/
|
*/
|
||||||
public function cloneRow($search, $numberOfClones) {
|
public function cloneRow($search, $numberOfClones) {
|
||||||
if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
|
if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
|
||||||
$search = '${'.$search.'}';
|
$search = '${'.$search.'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
$tagPos = strpos($this->_documentXML, $search);
|
$tagPos = strpos($this->_documentXML, $search);
|
||||||
if (!$tagPos) {
|
if (!$tagPos) {
|
||||||
trigger_error("Can not clone row, template variable not found or variable contains markup.");
|
trigger_error("Can not clone row, template variable not found or variable contains markup.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$rowStartPos = strrpos($this->_documentXML, "<w:tr ", ((strlen($this->_documentXML) - $tagPos) * -1));
|
|
||||||
$rowEndPos = strpos($this->_documentXML, "</w:tr>", $tagPos) + 7;
|
$rowStart = $this->_findRowStart($tagPos);
|
||||||
|
$rowEnd = $this->_findRowEnd($tagPos);
|
||||||
$result = substr($this->_documentXML, 0, $rowStartPos);
|
$xmlRow = $this->_getSlice($rowStart, $rowEnd);
|
||||||
$xmlRow = substr($this->_documentXML, $rowStartPos, ($rowEndPos - $rowStartPos));
|
|
||||||
|
// Check if there's a cell spanning multiple rows.
|
||||||
|
if (preg_match('#<w:vMerge w:val="restart"/>#', $xmlRow)) {
|
||||||
|
$extraRowStart = $rowEnd;
|
||||||
|
$extraRowEnd = $rowEnd;
|
||||||
|
while(true) {
|
||||||
|
$extraRowStart = $this->_findRowStart($extraRowEnd + 1);
|
||||||
|
$extraRowEnd = $this->_findRowEnd($extraRowEnd + 1);
|
||||||
|
|
||||||
|
// If extraRowEnd is lower then 7, there was no next row found.
|
||||||
|
if ($extraRowEnd < 7) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If tmpXmlRow doesn't contain continue, this row is no longer part of the spanned row.
|
||||||
|
$tmpXmlRow = $this->_getSlice($extraRowStart, $extraRowEnd);
|
||||||
|
if (!preg_match('#<w:vMerge/>#', $tmpXmlRow) && !preg_match('#<w:vMerge w:val="continue" />#', $tmpXmlRow)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// This row was a spanned row, update $rowEnd and search for the next row.
|
||||||
|
$rowEnd = $extraRowEnd;
|
||||||
|
}
|
||||||
|
$xmlRow = $this->_getSlice($rowStart, $rowEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->_getSlice(0, $rowStart);
|
||||||
for ($i = 1; $i <= $numberOfClones; $i++) {
|
for ($i = 1; $i <= $numberOfClones; $i++) {
|
||||||
$result .= preg_replace('/\$\{(.*?)\}/','\${\\1#'.$i.'}', $xmlRow);
|
$result .= preg_replace('/\$\{(.*?)\}/','\${\\1#'.$i.'}', $xmlRow);
|
||||||
}
|
}
|
||||||
$result .= substr($this->_documentXML, $rowEndPos);
|
$result .= $this->_getSlice($rowEnd);
|
||||||
|
|
||||||
$this->_documentXML = $result;
|
$this->_documentXML = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Template
|
* Save Template
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -5,6 +5,7 @@ $PHPWord = new PHPWord();
|
||||||
|
|
||||||
$document = $PHPWord->loadTemplate('Sample_03_TemplateCloneRow.docx');
|
$document = $PHPWord->loadTemplate('Sample_03_TemplateCloneRow.docx');
|
||||||
|
|
||||||
|
// Simple table
|
||||||
$document->cloneRow('rowValue', 10);
|
$document->cloneRow('rowValue', 10);
|
||||||
|
|
||||||
$document->setValue('rowValue#1', 'Sun');
|
$document->setValue('rowValue#1', 'Sun');
|
||||||
|
|
@ -32,4 +33,22 @@ $document->setValue('rowNumber#10', '10');
|
||||||
$document->setValue('weekday', date('l'));
|
$document->setValue('weekday', date('l'));
|
||||||
$document->setValue('time', date('H:i'));
|
$document->setValue('time', date('H:i'));
|
||||||
|
|
||||||
|
// Table with a spanned cell
|
||||||
|
$document->cloneRow('userId', 3);
|
||||||
|
|
||||||
|
$document->setValue('userId#1', '1');
|
||||||
|
$document->setValue('userFirstName#1', 'James');
|
||||||
|
$document->setValue('userName#1', 'Taylor');
|
||||||
|
$document->setValue('userPhone#1', '+1 428 889 773');
|
||||||
|
|
||||||
|
$document->setValue('userId#2', '2');
|
||||||
|
$document->setValue('userFirstName#2', 'Robert');
|
||||||
|
$document->setValue('userName#2', 'Bell');
|
||||||
|
$document->setValue('userPhone#2', '+1 428 889 774');
|
||||||
|
|
||||||
|
$document->setValue('userId#3', '3');
|
||||||
|
$document->setValue('userFirstName#3', 'Michael');
|
||||||
|
$document->setValue('userName#3', 'Ray');
|
||||||
|
$document->setValue('userPhone#3', '+1 428 889 775');
|
||||||
|
|
||||||
$document->save('Sample_03_TemplateCloneRow_result.docx');
|
$document->save('Sample_03_TemplateCloneRow_result.docx');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue