How to delete row from table in phpword tamplate?
I have a table in my *.docx tamplate. I clonerow it. But how can i delete some clonerowed row? Fore example, how can i delete clonerowed row with mark ${names17}? It is very important fore my.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
I join a question
HI, i add this function in Template.php
`public function removeTableRow($search){ if (substr($search, 0, 2) !== "${" && substr($search, -1) !== "}") { $search = "${" . $search . "}"; }
$tagPos = strpos($this->documentXML, $search);
if (!$tagPos) {
throw new Exception("Can not remove row, template variable not found or variable contains markup.");
}
$rowStart = $this->findRowStart($tagPos);
$rowEnd = $this->findRowEnd($tagPos);
$xmlRow = $this->getSlice($rowStart, $rowEnd);
$this->documentXML = str_replace($xmlRow, "", $this->documentXML);
return TRUE;
}`
@lahirwisada need replace $this->documentXML (is not found in TemplateProcessor) to $this->tempDocumentMainPart
public function deleteRow($search) { if ('${' !== substr($search, 0, 2) && '}' !== substr($search, -1)) { $search = '${' . $search . '}'; }
$tagPos = strpos($this->tempDocumentMainPart, $search);
if (!$tagPos) {
throw new Exception("Can not remove row, template variable not found or variable contains markup. ". $search);
}
$rowStart = $this->findRowStart($tagPos);
$rowEnd = $this->findRowEnd($tagPos);
$xmlRow = $this->getSlice($rowStart, $rowEnd);
$this->tempDocumentMainPart = str_replace($xmlRow, "", $this->tempDocumentMainPart);
return true;
}
i got a case inside the row there is an nest table , and will got issues. so i change the code a bit . in the template , if added "${/keyword}" , then will check the row end from here instead of from "${keywords}"
` public function deleteRow($search) {
if ('${' !== substr($search, 0, 2) && '}' !== substr($search, -1)) {
$search_start = '${' . $search . '}';
}
$tagPos = strpos($this->tempDocumentMainPart, $search_start);
if (!$tagPos) {
// throw new Exception("Can not remove row, template variable not found or variable contains markup.");
return FALSE;
}
$search_end = '${/' . $search . '}';
$tagPos_end = strpos($this->tempDocumentMainPart, $search_end);
if (!$tagPos_end) {
$tagPos_end = $tagPos;
// error_log($search_end . 'not found');
}
$rowStart = $this->findRowStart($tagPos);
$rowEnd = $this->findRowEnd($tagPos_end);
$xmlRow = $this->getSlice($rowStart, $rowEnd);
$this->tempDocumentMainPart = str_replace($xmlRow, "", $this->tempDocumentMainPart);
return TRUE;
}`
This is the solution that I came up with based on the ideas above:
/**
* Deletes all rows matching the provided search tag.
* Inspired by <https://github.com/PHPOffice/PHPWord/issues/762>
*
* @param $search - string to query
* @return int - number of rows removed.
*/
public function deleteRow(string $search): int
{
if ('${' !== substr($search, 0, 2) && '}' !== substr($search, -1)) {
$search = '${' . $search . '}';
}
$count = 0;
while (($tagPos = strpos($this->tempDocumentMainPart, $search))) {
$count++;
$rowStart = $this->findRowStart($tagPos);
$rowEnd = $this->findRowEnd($tagPos);
$xmlRow = $this->getSlice($rowStart, $rowEnd);
$this->tempDocumentMainPart = str_replace($xmlRow, "", $this->tempDocumentMainPart);
}
return $count;
}
Append the function to vendor/phpoffice/phpword/src/PhpWord/TemplateProcessor.php in your project.
Hope this helps future devs. 🙂
Edit: A more elegant solution would be to subclass TemplateProcessor with this method overridden.
Thanks a lot, that helps!!! Why sould this not be added to the next release version?
Pity, the decision for this problem is not in the prodaction.
A simple task to delete one row from a table cannot be accomplished. And I certainly will not be editing vendor files for this.
+1 for MR the solution
Hey, you can try this:
$templateProcessor->cloneRow($fieldName, 0);
also:
$templateProcessor->cloneRowAndSetValues($fieldName, []);
It work for me
Hey, you can try this:
$templateProcessor->cloneRow($fieldName, 0);also:$templateProcessor->cloneRowAndSetValues($fieldName, []);It work for me
Thanks for this solution, worked exactly as I needed !