8e128526
Mihail
add xlsx parser
|
1
2
3
4
5
6
7
8
|
<?php
/**
* Created by PhpStorm.
* User: Tsurkanov
* Date: 22.10.2015
* Time: 15:53
*/
|
d0261fd1
Mihail
fixed namespace i...
|
9
|
namespace yii\multiparser;
|
8e128526
Mihail
add xlsx parser
|
10
11
|
|
ec440fb6
Mihail
add supported ext...
|
12
13
|
use common\components\CustomVarDamp;
|
a684f314
Mihail
add adjustRowToKe...
|
14
15
|
abstract class TableParser extends Parser
{
|
8e128526
Mihail
add xlsx parser
|
16
17
|
/**
* @var array - текущий отпарсенный ряд
|
a3b2aa93
Mihail
change meaning of...
|
18
19
20
|
*если есть ключи, то колонки с пустыми значениями будут пропускаться (из ряда такие значения будут удаляться),
* например если в файле вторая колонка пустая то она будет удалена
* в остальных случаях парсятся все колонки (не проверяется - пустая ли колонка) и попадёт в итоговый массив
|
8e128526
Mihail
add xlsx parser
|
21
22
23
|
*/
protected $row = [];
|
a3b2aa93
Mihail
change meaning of...
|
24
25
26
27
28
|
/** @var int - первая строка с которой начинать парсить
* эта строка будет считаться первой значимой строкой
* если установлен аттрибут $has_header_row,
* тогда следующая строка будет считаться заголовком и будет пропущена
*/
|
8e128526
Mihail
add xlsx parser
|
29
30
31
32
33
34
35
36
37
38
39
|
public $first_line = 0;
/** @var int - последняя строка до которой парсить
* если не указана, то парсинг происходит до конца файла*/
public $last_line = 0;
/** @var int - первая колонка файла с которой начнется парсинг */
public $first_column = 0;
/** @var bool
|
a3b2aa93
Mihail
change meaning of...
|
40
41
42
43
44
|
* имеет ли файл заголовок в первой значимой строке
* true - первая значимая строка будет пропущена
*/
public $has_header_row = true;
|
8e128526
Mihail
add xlsx parser
|
45
46
47
48
49
|
/** @var int - количество значимых колонок, что бы определить первую значимую строку
* используется при автоопределении первой строки*/
public $min_column_quantity = 5;
/** @var int - количество пустых строк, что бы определить конец файла,
|
a684f314
Mihail
add adjustRowToKe...
|
50
|
* такое количеество подряд пустых строк считается концом файла*/
|
8e128526
Mihail
add xlsx parser
|
51
52
53
54
55
56
57
|
public $empty_lines_quantity = 3;
/** @var int - номер текущей строки парсера */
protected $current_row_number = 0;
|
8e128526
Mihail
add xlsx parser
|
58
59
60
61
|
protected abstract function isEmptyColumn($column_value);
protected abstract function readRow();
|
d1fac7a9
Mihail
add parsing sheet...
|
62
63
|
protected abstract function setResult();
|
8e128526
Mihail
add xlsx parser
|
64
65
66
|
public function read()
{
|
61323a64
Mihail
redid read method...
|
67
|
// первый проход
|
a3b2aa93
Mihail
change meaning of...
|
68
|
$first_circle = true;
|
61323a64
Mihail
redid read method...
|
69
|
$this->current_row_number = 1;
|
8e128526
Mihail
add xlsx parser
|
70
71
72
|
// будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим
$empty_lines = 0;
|
a684f314
Mihail
add adjustRowToKe...
|
73
|
while ($empty_lines < $this->empty_lines_quantity) {
|
8e128526
Mihail
add xlsx parser
|
74
|
|
61323a64
Mihail
redid read method...
|
75
76
|
$this->readRow();
$this->current_row_number++;
|
a3b2aa93
Mihail
change meaning of...
|
77
|
|
58f734e6
Mihail
fixed issue with ...
|
78
|
// уберем пустые колонки из ряда
|
61323a64
Mihail
redid read method...
|
79
|
if ( $this->keys === NULL ) {
|
a684f314
Mihail
add adjustRowToKe...
|
80
81
82
|
$this->filterRow();
}
|
61323a64
Mihail
redid read method...
|
83
|
if ( $this->isEmptyRow() ) {
|
a3b2aa93
Mihail
change meaning of...
|
84
85
|
//счетчик пустых строк
$empty_lines++;
|
a3b2aa93
Mihail
change meaning of...
|
86
87
|
continue;
}
|
58f734e6
Mihail
fixed issue with ...
|
88
|
|
61323a64
Mihail
redid read method...
|
89
90
91
92
93
94
95
96
|
if ( $first_circle ) {
// при первом проходе нужно учесть настройки поп поиску первой строки
// такие как first_line и has_header_row
$this->shiftToFirstValuableLine();
}
$first_circle = false;
|
a3b2aa93
Mihail
change meaning of...
|
97
|
// запустим конвертирование
|
a684f314
Mihail
add adjustRowToKe...
|
98
|
$this->adjustRowToSettings();
|
8e128526
Mihail
add xlsx parser
|
99
|
|
a3b2aa93
Mihail
change meaning of...
|
100
101
|
// установим отпарсенную строку в итоговый массив результата
$this->setResult();
|
8e128526
Mihail
add xlsx parser
|
102
|
|
8e128526
Mihail
add xlsx parser
|
103
|
// если у нас установлен лимит, при его достижении прекращаем парсинг
|
a684f314
Mihail
add adjustRowToKe...
|
104
|
if ($this->isLastLine())
|
8e128526
Mihail
add xlsx parser
|
105
106
107
108
|
break;
// обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
$empty_lines = 0;
|
8e128526
Mihail
add xlsx parser
|
109
|
}
|
8e128526
Mihail
add xlsx parser
|
110
|
}
|
a684f314
Mihail
add adjustRowToKe...
|
111
|
|
8e128526
Mihail
add xlsx parser
|
112
|
/**
|
61323a64
Mihail
redid read method...
|
113
114
|
* определяет первую значимую строку согласно first_line и has_header_row,
* считывается пока не дойдет до first_line
|
a3b2aa93
Mihail
change meaning of...
|
115
|
* пропускает заголовок если он указан
|
8e128526
Mihail
add xlsx parser
|
116
117
118
|
*/
protected function shiftToFirstValuableLine()
{
|
61323a64
Mihail
redid read method...
|
119
120
|
// читаем пока не дойдем до first_line
while ( $this->first_line > $this->current_row_number ) {
|
8e128526
Mihail
add xlsx parser
|
121
|
$this->readRow();
|
61323a64
Mihail
redid read method...
|
122
123
|
$this->current_row_number++;
}
|
a3b2aa93
Mihail
change meaning of...
|
124
125
|
// если указан заголовок, то его мы тоже пропускаем (читаем далее)
if( $this->has_header_row ) {
|
a3b2aa93
Mihail
change meaning of...
|
126
|
$this->readRow();
|
61323a64
Mihail
redid read method...
|
127
|
$this->current_row_number++;
|
a3b2aa93
Mihail
change meaning of...
|
128
|
}
|
8e128526
Mihail
add xlsx parser
|
129
130
131
132
133
|
}
/**
* @return array - одномерный массив результата парсинга строки
*/
|
a684f314
Mihail
add adjustRowToKe...
|
134
|
protected function adjustRowToSettings()
|
8e128526
Mihail
add xlsx parser
|
135
|
{
|
a684f314
Mihail
add adjustRowToKe...
|
136
137
138
139
140
141
142
|
// если есть заголовок, то перед конвертацией его нужно назначить
if ($this->keys !== NULL) {
// adjust row to keys
$this->adjustRowToKeys();
// назначим заголовок
$this->row = array_combine($this->keys, $this->row);
}
|
8e128526
Mihail
add xlsx parser
|
143
|
|
a684f314
Mihail
add adjustRowToKe...
|
144
145
|
// попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений
$this->row = $this->convert($this->row);
|
8e128526
Mihail
add xlsx parser
|
146
|
|
a684f314
Mihail
add adjustRowToKe...
|
147
148
|
// обрежем массив к первой значимой колонке
if ($this->first_column) {
|
8e128526
Mihail
add xlsx parser
|
149
|
|
a684f314
Mihail
add adjustRowToKe...
|
150
|
$this->row = array_slice($this->row, $this->first_column);
|
8e128526
Mihail
add xlsx parser
|
151
|
|
a684f314
Mihail
add adjustRowToKe...
|
152
|
}
|
8e128526
Mihail
add xlsx parser
|
153
154
155
|
}
|
a3b2aa93
Mihail
change meaning of...
|
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
protected function isEmptyRow(){
$is_empty = false;
if ( empty( $this->row ) ) {
return true;
}
if ( count( $this->row ) < $this->min_column_quantity ) {
return true;
}
$j = 0;
for ($i = 1; $i <= count( $this->row ); $i++) {
if ( !isset( $this->row[ $i - 1 ] ) ) {
continue;
}
if ( $this->isEmptyColumn( $this->row[$i - 1] ) ) {
$j++;
}
if ( $j >= $this->min_column_quantity ) {
$is_empty = true;
break;
|
8e128526
Mihail
add xlsx parser
|
181
182
|
}
}
|
a3b2aa93
Mihail
change meaning of...
|
183
184
|
return $is_empty;
|
8e128526
Mihail
add xlsx parser
|
185
186
|
}
|
a3b2aa93
Mihail
change meaning of...
|
187
188
|
|
a684f314
Mihail
add adjustRowToKe...
|
189
190
|
protected function filterRow()
{
|
a3b2aa93
Mihail
change meaning of...
|
191
192
|
// нет строки - нет фильтрации
if ( empty( $this->row ) ) {
|
d1fac7a9
Mihail
add parsing sheet...
|
193
194
|
return;
}
|
a684f314
Mihail
add adjustRowToKe...
|
195
|
$this->row = array_filter($this->row, function ($val) {
|
8e128526
Mihail
add xlsx parser
|
196
197
|
return !$this->isEmptyColumn($val);
});
|
8e128526
Mihail
add xlsx parser
|
198
199
|
}
|
a684f314
Mihail
add adjustRowToKe...
|
200
201
|
protected function isLastLine()
{
|
8e128526
Mihail
add xlsx parser
|
202
|
|
a684f314
Mihail
add adjustRowToKe...
|
203
|
if (($this->last_line) && ($this->current_row_number > $this->last_line)) {
|
8e128526
Mihail
add xlsx parser
|
204
205
206
207
208
|
return true;
}
return false;
}
|
a684f314
Mihail
add adjustRowToKe...
|
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
protected function adjustRowToKeys()
{
//уберем из ряда те колонки которых нет в ключах
$this->row = array_intersect_key($this->row, $this->keys);
$keys_count = count($this->keys);
$column_count = count($this->row);
if ($keys_count != $column_count) {
// найдем колонки которых нет в ряде но есть ключах
$arr_diff = array_diff_key($this->keys, $this->row);
foreach ($arr_diff as $key => $value) {
// колонки которых нет в ряде но есть ключах, добавим их с пустым значением
$this->row[$key] = '';
}
}
}
|
8e128526
Mihail
add xlsx parser
|
226
|
}
|