3
3
namespace PhpOffice \PhpSpreadsheet \Worksheet ;
4
4
5
5
use ArrayObject ;
6
+ use Generator ;
6
7
use PhpOffice \PhpSpreadsheet \Calculation \Calculation ;
7
8
use PhpOffice \PhpSpreadsheet \Calculation \Functions ;
8
9
use PhpOffice \PhpSpreadsheet \Cell \AddressRange ;
@@ -2800,9 +2801,6 @@ protected function cellToArray(Cell $cell, bool $calculateFormulas, bool $format
2800
2801
return $ returnValue ;
2801
2802
}
2802
2803
2803
- /** @var array<string, bool> */
2804
- private array $ hiddenColumns ;
2805
-
2806
2804
/**
2807
2805
* Create array from a range of cells.
2808
2806
*
@@ -2822,9 +2820,40 @@ public function rangeToArray(
2822
2820
bool $ returnCellRef = false ,
2823
2821
bool $ ignoreHidden = false
2824
2822
): array {
2823
+ $ returnValue = [];
2824
+
2825
+ // Loop through rows
2826
+ foreach ($ this ->rangeToArrayYieldRows ($ range , $ nullValue , $ calculateFormulas , $ formatData , $ returnCellRef , $ ignoreHidden ) as $ rowRef => $ rowArray ) {
2827
+ $ returnValue [$ rowRef ] = $ rowArray ;
2828
+ }
2829
+
2830
+ // Return
2831
+ return $ returnValue ;
2832
+ }
2833
+
2834
+ /**
2835
+ * Create array from a range of cells, yielding each row in turn.
2836
+ *
2837
+ * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
2838
+ * @param bool $calculateFormulas Should formulas be calculated?
2839
+ * @param bool $formatData Should formatting be applied to cell values?
2840
+ * @param bool $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
2841
+ * True - Return rows and columns indexed by their actual row and column IDs
2842
+ * @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden.
2843
+ * True - Don't return values for rows/columns that are defined as hidden.
2844
+ *
2845
+ * @return Generator
2846
+ */
2847
+ public function rangeToArrayYieldRows (
2848
+ string $ range ,
2849
+ mixed $ nullValue = null ,
2850
+ bool $ calculateFormulas = true ,
2851
+ bool $ formatData = true ,
2852
+ bool $ returnCellRef = false ,
2853
+ bool $ ignoreHidden = false
2854
+ ) {
2825
2855
$ range = Validations::validateCellOrCellRange ($ range );
2826
2856
2827
- $ returnValue = [];
2828
2857
// Identify the range that we need to extract from the worksheet
2829
2858
[$ rangeStart , $ rangeEnd ] = Coordinate::rangeBoundaries ($ range );
2830
2859
$ minCol = Coordinate::stringFromColumnIndex ($ rangeStart [0 ]);
@@ -2835,8 +2864,10 @@ public function rangeToArray(
2835
2864
$ maxColInt = $ rangeEnd [0 ];
2836
2865
2837
2866
++$ maxCol ;
2838
- $ nullRow = $ this ->buildNullRow ($ nullValue , $ minCol , $ maxCol , $ returnCellRef , $ ignoreHidden );
2839
- $ hideColumns = !empty ($ this ->hiddenColumns );
2867
+ /** @var array<string, bool> */
2868
+ $ hiddenColumns = [];
2869
+ $ nullRow = $ this ->buildNullRow ($ nullValue , $ minCol , $ maxCol , $ returnCellRef , $ ignoreHidden , $ hiddenColumns );
2870
+ $ hideColumns = !empty ($ hiddenColumns );
2840
2871
2841
2872
$ keys = $ this ->cellCollection ->getSortedCoordinatesInt ();
2842
2873
$ keyIndex = 0 ;
@@ -2847,7 +2878,7 @@ public function rangeToArray(
2847
2878
continue ;
2848
2879
}
2849
2880
$ rowRef = $ returnCellRef ? $ row : ($ row - $ minRow );
2850
- $ returnValue[ $ rowRef ] = $ nullRow ;
2881
+ $ returnValue = $ nullRow ;
2851
2882
2852
2883
$ index = ($ row - 1 ) * AddressRange::MAX_COLUMN_INT + 1 ;
2853
2884
$ indexPlus = $ index + AddressRange::MAX_COLUMN_INT - 1 ;
@@ -2860,24 +2891,22 @@ public function rangeToArray(
2860
2891
$ thisCol = ($ key % AddressRange::MAX_COLUMN_INT ) ?: AddressRange::MAX_COLUMN_INT ;
2861
2892
if ($ thisCol >= $ minColInt && $ thisCol <= $ maxColInt ) {
2862
2893
$ col = Coordinate::stringFromColumnIndex ($ thisCol );
2863
- if ($ hideColumns === false || !isset ($ this -> hiddenColumns [$ col ])) {
2894
+ if ($ hideColumns === false || !isset ($ hiddenColumns [$ col ])) {
2864
2895
$ columnRef = $ returnCellRef ? $ col : ($ thisCol - $ minColInt );
2865
2896
$ cell = $ this ->cellCollection ->get ("{$ col }{$ thisRow }" );
2866
2897
if ($ cell !== null ) {
2867
2898
$ value = $ this ->cellToArray ($ cell , $ calculateFormulas , $ formatData , $ nullValue );
2868
2899
if ($ value !== $ nullValue ) {
2869
- $ returnValue [$ rowRef ][ $ columnRef ] = $ value ;
2900
+ $ returnValue [$ columnRef ] = $ value ;
2870
2901
}
2871
2902
}
2872
2903
}
2873
2904
}
2874
2905
++$ keyIndex ;
2875
2906
}
2876
- }
2877
- unset($ this ->hiddenColumns );
2878
2907
2879
- // Return
2880
- return $ returnValue ;
2908
+ yield $ rowRef => $ returnValue ;
2909
+ }
2881
2910
}
2882
2911
2883
2912
/**
@@ -2890,20 +2919,21 @@ public function rangeToArray(
2890
2919
* True - Return rows and columns indexed by their actual row and column IDs
2891
2920
* @param bool $ignoreHidden False - Return values for rows/columns even if they are defined as hidden.
2892
2921
* True - Don't return values for rows/columns that are defined as hidden.
2922
+ * @param array<string, bool> $hiddenColumns
2893
2923
*/
2894
2924
private function buildNullRow (
2895
2925
mixed $ nullValue ,
2896
2926
string $ minCol ,
2897
2927
string $ maxCol ,
2898
2928
bool $ returnCellRef ,
2899
2929
bool $ ignoreHidden ,
2930
+ array &$ hiddenColumns
2900
2931
): array {
2901
- $ this ->hiddenColumns = [];
2902
2932
$ nullRow = [];
2903
2933
$ c = -1 ;
2904
2934
for ($ col = $ minCol ; $ col !== $ maxCol ; ++$ col ) {
2905
2935
if ($ ignoreHidden === true && $ this ->columnDimensionExists ($ col ) && $ this ->getColumnDimension ($ col )->getVisible () === false ) {
2906
- $ this -> hiddenColumns [$ col ] = true ;
2936
+ $ hiddenColumns [$ col ] = true ;
2907
2937
} else {
2908
2938
$ columnRef = $ returnCellRef ? $ col : ++$ c ;
2909
2939
$ nullRow [$ columnRef ] = $ nullValue ;
0 commit comments