@@ -759,6 +759,77 @@ public function cloneRow($search, $numberOfClones): void
759
759
$ this ->tempDocumentMainPart = $ result ;
760
760
}
761
761
762
+ /**
763
+ * Delete a table row in a template document.
764
+ *
765
+ * @param string $search
766
+ *
767
+ * @return void
768
+ *
769
+ * @throws \PhpOffice\PhpWord\Exception\Exception
770
+ */
771
+ public function deleteRow ($ search )
772
+ {
773
+ if ('${ ' !== substr ($ search , 0 , 2 ) && '} ' !== substr ($ search , -1 )) {
774
+ $ search = '${ ' . $ search . '} ' ;
775
+ }
776
+
777
+ $ tagPos = strpos ($ this ->tempDocumentMainPart , $ search );
778
+ if (!$ tagPos ) {
779
+ throw new Exception (sprintf ("Can not delete row %s, template variable not found or variable contains markup. " , $ search ));
780
+ }
781
+
782
+ $ tableStart = $ this ->findTableStart ($ tagPos );
783
+ $ tableEnd = $ this ->findTableEnd ($ tagPos );
784
+ $ xmlTable = $ this ->getSlice ($ tableStart , $ tableEnd );
785
+
786
+ if (substr_count ($ xmlTable , '<w:tr ' ) === 1 ) {
787
+ $ this ->tempDocumentMainPart = $ this ->getSlice (0 , $ tableStart ) . $ this ->getSlice ($ tableEnd );
788
+
789
+ return ;
790
+ }
791
+
792
+ $ rowStart = $ this ->findRowStart ($ tagPos );
793
+ $ rowEnd = $ this ->findRowEnd ($ tagPos );
794
+ $ xmlRow = $ this ->getSlice ($ rowStart , $ rowEnd );
795
+
796
+ $ this ->tempDocumentMainPart = $ this ->getSlice (0 , $ rowStart ) . $ this ->getSlice ($ rowEnd );
797
+
798
+ // Check if there's a cell spanning multiple rows.
799
+ if (preg_match ('#<w:vMerge w:val="restart"/># ' , $ xmlRow )) {
800
+ // $extraRowStart = $rowEnd;
801
+ $ extraRowStart = $ rowStart ;
802
+ while (true ) {
803
+ $ extraRowStart = $ this ->findRowStart ($ extraRowStart + 1 );
804
+ $ extraRowEnd = $ this ->findRowEnd ($ extraRowStart + 1 );
805
+
806
+ // If extraRowEnd is lower then 7, there was no next row found.
807
+ if ($ extraRowEnd < 7 ) {
808
+ break ;
809
+ }
810
+
811
+ // If tmpXmlRow doesn't contain continue, this row is no longer part of the spanned row.
812
+ $ tmpXmlRow = $ this ->getSlice ($ extraRowStart , $ extraRowEnd );
813
+ if (!preg_match ('#<w:vMerge/># ' , $ tmpXmlRow ) &&
814
+ !preg_match ('#<w:vMerge w:val="continue" /># ' , $ tmpXmlRow )
815
+ ) {
816
+ break ;
817
+ }
818
+
819
+ $ tableStart = $ this ->findTableStart ($ extraRowEnd + 1 );
820
+ $ tableEnd = $ this ->findTableEnd ($ extraRowEnd + 1 );
821
+ $ xmlTable = $ this ->getSlice ($ tableStart , $ tableEnd );
822
+ if (substr_count ($ xmlTable , '<w:tr ' ) === 1 ) {
823
+ $ this ->tempDocumentMainPart = $ this ->getSlice (0 , $ tableStart ) . $ this ->getSlice ($ tableEnd );
824
+
825
+ return ;
826
+ }
827
+
828
+ $ this ->tempDocumentMainPart = $ this ->getSlice (0 , $ extraRowStart ) . $ this ->getSlice ($ extraRowEnd );
829
+ }
830
+ }
831
+ }
832
+
762
833
/**
763
834
* Clones a table row and populates it's values from a two-dimensional array in a template document.
764
835
*
@@ -1079,6 +1150,43 @@ protected function getDocumentContentTypesName()
1079
1150
return '[Content_Types].xml ' ;
1080
1151
}
1081
1152
1153
+ /**
1154
+ * Find the start position of the nearest table before $offset.
1155
+ *
1156
+ * @param integer $offset
1157
+ *
1158
+ * @return integer
1159
+ *
1160
+ * @throws \PhpOffice\PhpWord\Exception\Exception
1161
+ */
1162
+ protected function findTableStart ($ offset )
1163
+ {
1164
+ $ rowStart = strrpos ($ this ->tempDocumentMainPart , '<w:tbl ' ,
1165
+ ((strlen ($ this ->tempDocumentMainPart ) - $ offset ) * -1 ));
1166
+
1167
+ if (!$ rowStart ) {
1168
+ $ rowStart = strrpos ($ this ->tempDocumentMainPart , '<w:tbl> ' ,
1169
+ ((strlen ($ this ->tempDocumentMainPart ) - $ offset ) * -1 ));
1170
+ }
1171
+ if (!$ rowStart ) {
1172
+ throw new Exception ('Can not find the start position of the table. ' );
1173
+ }
1174
+
1175
+ return $ rowStart ;
1176
+ }
1177
+
1178
+ /**
1179
+ * Find the end position of the nearest table row after $offset.
1180
+ *
1181
+ * @param integer $offset
1182
+ *
1183
+ * @return integer
1184
+ */
1185
+ protected function findTableEnd ($ offset )
1186
+ {
1187
+ return strpos ($ this ->tempDocumentMainPart , '</w:tbl> ' , $ offset ) + 7 ;
1188
+ }
1189
+
1082
1190
/**
1083
1191
* Find the start position of the nearest table row before $offset.
1084
1192
*
0 commit comments