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 |