Commit 61323a646e6e68b44d6d9342a197d2aaedb1ac82
1 parent
d8aa85f3
redid read method for more flexible way to determine first row
Showing
3 changed files
with
31 additions
and
29 deletions
Show diff stats
examples/UploadFileParsingForm.php
@@ -58,7 +58,7 @@ JS; | @@ -58,7 +58,7 @@ JS; | ||
58 | $data = Yii::$app->multiparser->parse( $this->file_path, $options ); | 58 | $data = Yii::$app->multiparser->parse( $this->file_path, $options ); |
59 | 59 | ||
60 | if( !is_array( $data ) || count($data) == 0 ){ | 60 | if( !is_array( $data ) || count($data) == 0 ){ |
61 | - throw new ErrorException("Reading error from file - {$this->file_path}"); | 61 | + throw new ErrorException("Parser return empty array. Check file and configuration settings (config.php)"); |
62 | } | 62 | } |
63 | 63 | ||
64 | if( !$this->file_path && file_exists( $this->file_path ) ) | 64 | if( !$this->file_path && file_exists( $this->file_path ) ) |
examples/config.php
@@ -86,10 +86,12 @@ return [ | @@ -86,10 +86,12 @@ return [ | ||
86 | ], | 86 | ], |
87 | 'template' => | 87 | 'template' => |
88 | ['class' => 'yii\multiparser\XlsxParser', | 88 | ['class' => 'yii\multiparser\XlsxParser', |
89 | + 'min_column_quantity' => 2, | ||
90 | + 'active_sheet' => 1, | ||
89 | 'path_for_extract_files' => $_SERVER["DOCUMENT_ROOT"] . '/tests/_data/xlsx_tmp/', | 91 | 'path_for_extract_files' => $_SERVER["DOCUMENT_ROOT"] . '/tests/_data/xlsx_tmp/', |
90 | 'keys' => [ | 92 | 'keys' => [ |
91 | - 0 => 'Original', | ||
92 | - 1 => 'Replacement', | 93 | + 1 => 'Original', |
94 | + 2 => 'Replacement', | ||
93 | ], | 95 | ], |
94 | ], | 96 | ], |
95 | 'basic_column' => [ | 97 | 'basic_column' => [ |
@@ -107,6 +109,7 @@ return [ | @@ -107,6 +109,7 @@ return [ | ||
107 | ], | 109 | ], |
108 | 'template' => | 110 | 'template' => |
109 | ['class' => 'yii\multiparser\XlsParser', | 111 | ['class' => 'yii\multiparser\XlsParser', |
112 | + 'empty_lines_quantity' => 4, | ||
110 | 'converter_conf' => [ | 113 | 'converter_conf' => [ |
111 | 'class' => ' yii\multiparser\Converter', | 114 | 'class' => ' yii\multiparser\Converter', |
112 | 'configuration' => ["encode" => [], | 115 | 'configuration' => ["encode" => [], |
@@ -128,6 +131,7 @@ return [ | @@ -128,6 +131,7 @@ return [ | ||
128 | ['custom' => | 131 | ['custom' => |
129 | ['class' => 'yii\multiparser\CsvParser', | 132 | ['class' => 'yii\multiparser\CsvParser', |
130 | 'delimiter' => "\t", | 133 | 'delimiter' => "\t", |
134 | + 'min_column_quantity' => 3, | ||
131 | 'converter_conf' => [ | 135 | 'converter_conf' => [ |
132 | 'class' => 'yii\multiparser\Converter', | 136 | 'class' => 'yii\multiparser\Converter', |
133 | 'configuration' => ["encode" => []], | 137 | 'configuration' => ["encode" => []], |
@@ -135,16 +139,17 @@ return [ | @@ -135,16 +139,17 @@ return [ | ||
135 | ], | 139 | ], |
136 | 'template' => | 140 | 'template' => |
137 | ['class' => 'yii\multiparser\CsvParser', | 141 | ['class' => 'yii\multiparser\CsvParser', |
142 | + 'min_column_quantity' => 3, | ||
138 | 'delimiter' => "\t", | 143 | 'delimiter' => "\t", |
139 | 'keys' => [ | 144 | 'keys' => [ |
140 | 0 => 'Brand', | 145 | 0 => 'Brand', |
141 | - 1 => 'Article', | 146 | + 1 => 'Description', |
142 | 2 => 'Price', | 147 | 2 => 'Price', |
143 | 4 => 'Count', | 148 | 4 => 'Count', |
144 | ], | 149 | ], |
145 | 'converter_conf' => [ | 150 | 'converter_conf' => [ |
146 | 'class' => 'yii\multiparser\Converter', | 151 | 'class' => 'yii\multiparser\Converter', |
147 | - 'configuration' => ["encode" => 'Brand', | 152 | + 'configuration' => ["encode" => [], |
148 | "float" => 'Price', | 153 | "float" => 'Price', |
149 | "integer" => 'Count' | 154 | "integer" => 'Count' |
150 | ] | 155 | ] |
lib/TableParser.php
@@ -64,42 +64,41 @@ abstract class TableParser extends Parser | @@ -64,42 +64,41 @@ abstract class TableParser extends Parser | ||
64 | 64 | ||
65 | public function read() | 65 | public function read() |
66 | { | 66 | { |
67 | - // получим первую значимую строку | ||
68 | - $this->shiftToFirstValuableLine(); | ||
69 | - | ||
70 | - // первый проход, строка прочитана в shiftToFirstValuableLine | 67 | + // первый проход |
71 | $first_circle = true; | 68 | $first_circle = true; |
69 | + $this->current_row_number = 1; | ||
72 | 70 | ||
73 | // будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим | 71 | // будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим |
74 | $empty_lines = 0; | 72 | $empty_lines = 0; |
75 | while ($empty_lines < $this->empty_lines_quantity) { | 73 | while ($empty_lines < $this->empty_lines_quantity) { |
76 | 74 | ||
77 | - // прочтем строку из файла, если это не первый проход | ||
78 | - if (!$first_circle){ | ||
79 | - $this->readRow(); | ||
80 | - } | ||
81 | - | ||
82 | - $first_circle = false; | 75 | + $this->readRow(); |
76 | + $this->current_row_number++; | ||
83 | 77 | ||
84 | // уберем пустые колонки из ряда | 78 | // уберем пустые колонки из ряда |
85 | - if ($this->keys === NULL) { | 79 | + if ( $this->keys === NULL ) { |
86 | $this->filterRow(); | 80 | $this->filterRow(); |
87 | } | 81 | } |
88 | 82 | ||
89 | - if ($this->isEmptyRow()) { | 83 | + if ( $this->isEmptyRow() ) { |
90 | //счетчик пустых строк | 84 | //счетчик пустых строк |
91 | $empty_lines++; | 85 | $empty_lines++; |
92 | - $this->current_row_number++; | ||
93 | continue; | 86 | continue; |
94 | } | 87 | } |
95 | 88 | ||
89 | + if ( $first_circle ) { | ||
90 | + // при первом проходе нужно учесть настройки поп поиску первой строки | ||
91 | + // такие как first_line и has_header_row | ||
92 | + $this->shiftToFirstValuableLine(); | ||
93 | + } | ||
94 | + | ||
95 | + $first_circle = false; | ||
96 | + | ||
96 | // запустим конвертирование | 97 | // запустим конвертирование |
97 | $this->adjustRowToSettings(); | 98 | $this->adjustRowToSettings(); |
98 | 99 | ||
99 | // установим отпарсенную строку в итоговый массив результата | 100 | // установим отпарсенную строку в итоговый массив результата |
100 | $this->setResult(); | 101 | $this->setResult(); |
101 | - // строка не пустая, имеем прочитанный массив значений | ||
102 | - $this->current_row_number++; | ||
103 | 102 | ||
104 | // если у нас установлен лимит, при его достижении прекращаем парсинг | 103 | // если у нас установлен лимит, при его достижении прекращаем парсинг |
105 | if ($this->isLastLine()) | 104 | if ($this->isLastLine()) |
@@ -111,23 +110,21 @@ abstract class TableParser extends Parser | @@ -111,23 +110,21 @@ abstract class TableParser extends Parser | ||
111 | } | 110 | } |
112 | 111 | ||
113 | /** | 112 | /** |
114 | - * определяет первую значимую строку, | ||
115 | - * считывается файл пока в нем не встретится строка с непустыми колонками | ||
116 | - * или пока не дойдет до first_line | 113 | + * определяет первую значимую строку согласно first_line и has_header_row, |
114 | + * считывается пока не дойдет до first_line | ||
117 | * пропускает заголовок если он указан | 115 | * пропускает заголовок если он указан |
118 | */ | 116 | */ |
119 | protected function shiftToFirstValuableLine() | 117 | protected function shiftToFirstValuableLine() |
120 | { | 118 | { |
121 | - // читаем пока не встретим значимую строку, или пока не дойдем до first_line | ||
122 | - do { | ||
123 | - $this->current_row_number++; | 119 | + // читаем пока не дойдем до first_line |
120 | + while ( $this->first_line > $this->current_row_number ) { | ||
124 | $this->readRow(); | 121 | $this->readRow(); |
125 | - } while ( $this->isEmptyRow() && ( $this->first_line < $this->current_row_number ) ); | ||
126 | - | 122 | + $this->current_row_number++; |
123 | + } | ||
127 | // если указан заголовок, то его мы тоже пропускаем (читаем далее) | 124 | // если указан заголовок, то его мы тоже пропускаем (читаем далее) |
128 | if( $this->has_header_row ) { | 125 | if( $this->has_header_row ) { |
129 | - $this->current_row_number++; | ||
130 | $this->readRow(); | 126 | $this->readRow(); |
127 | + $this->current_row_number++; | ||
131 | } | 128 | } |
132 | } | 129 | } |
133 | 130 |