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
|
|
f6e54131
Mihail
fixed keys and he...
|
12
13
|
use common\components\CustomVarDamp;
|
8e128526
Mihail
add xlsx parser
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
abstract class TableParser extends Parser {
/**
* @var array - текущий отпарсенный ряд
*/
protected $row = [];
/** @var int - первая строка с которой начинать парсить */
public $first_line = 0;
/** @var int - последняя строка до которой парсить
* если не указана, то парсинг происходит до конца файла*/
public $last_line = 0;
/** @var int - первая колонка файла с которой начнется парсинг */
public $first_column = 0;
/** @var bool
нужно ли искать автоматически первоую значисмую строку (не пустая строка)
* иначе первая строка будет взята из аттрибута $first_line */
public $auto_detect_first_line = false;
/** @var int - количество значимых колонок, что бы определить первую значимую строку
* используется при автоопределении первой строки*/
public $min_column_quantity = 5;
/** @var int - количество пустых строк, что бы определить конец файла,
такое количеество подряд пустых строк считается концом файла*/
public $empty_lines_quantity = 3;
/** @var int - номер текущей строки парсера */
protected $current_row_number = 0;
protected abstract function isEmptyRow();
protected abstract function isEmptyColumn($column_value);
protected abstract function readRow();
|
d1fac7a9
Mihail
add parsing sheet...
|
56
57
|
protected abstract function setResult();
|
8e128526
Mihail
add xlsx parser
|
58
59
60
61
62
63
64
65
66
67
68
69
70
|
public function read()
{
if ($this->auto_detect_first_line) {
$this->shiftToFirstValuableLine();
}
// будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим
$empty_lines = 0;
while ( $empty_lines < $this->empty_lines_quantity ) {
// прочтем строку из файла
$this->readRow();
|
8e128526
Mihail
add xlsx parser
|
71
72
|
if ( $this->isEmptyRow() ) {
//счетчик пустых строк
|
d1fac7a9
Mihail
add parsing sheet...
|
73
|
//CustomVarDamp::dump($this->current_row_number);
|
8e128526
Mihail
add xlsx parser
|
74
75
76
77
|
$empty_lines++;
continue;
}
|
58f734e6
Mihail
fixed issue with ...
|
78
79
80
|
// уберем пустые колонки из ряда
$this->filterRow();
|
8e128526
Mihail
add xlsx parser
|
81
82
83
84
85
86
|
$this->adjustRowToSettings( );
// строка не пустая, имеем прочитанный массив значений
$this->current_row_number++;
// для первой строки утановим ключи из заголовка
|
d1fac7a9
Mihail
add parsing sheet...
|
87
88
89
90
|
if ( !$this->setKeysFromHeader() ) {
$this->setResult();
}
|
8e128526
Mihail
add xlsx parser
|
91
92
93
94
95
96
97
98
|
// если у нас установлен лимит, при его достижении прекращаем парсинг
if ( $this->isLastLine() )
break;
// обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
$empty_lines = 0;
|
8e128526
Mihail
add xlsx parser
|
99
100
|
}
|
8e128526
Mihail
add xlsx parser
|
101
102
103
104
105
106
107
108
109
110
111
|
}
/**
* определяет первую значимую строку,
* считывается файл пока в нем не встретится строка с непустыми колонками
* в количестве указанном в атрибуте min_column_quantity
* в результате выполнения $current_row_number будет находится на последней незначимой строке
*/
protected function shiftToFirstValuableLine()
{
do {
|
f6e54131
Mihail
fixed keys and he...
|
112
|
$this->current_row_number++;
|
8e128526
Mihail
add xlsx parser
|
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
$this->readRow();
} while( $this->isEmptyRow() );
// @todo - сделать опционально
// код для того что бы парсить первую строку, закомментировано как предполагается что первая значимая строка это заголовок
// $this->current_row_number --;
// $this->file->seek( $this->current_row_number );
}
/**
* @return array - одномерный массив результата парсинга строки
*/
protected function adjustRowToSettings( )
{
// если есть заголовок, то перед конвертацией его нужно назначить
if ( $this->keys !== NULL ) {
if (count($this->keys) !== count($this->row)) {
|
cd8b9f70
Mihail
add cleanUp metho...
|
133
134
|
throw new \Exception("Ошибка парсинга файла в строке # {$this->current_row_number}.
Не соответсвие числа ключевых колонок (заголовка) - числу колонок с данными");
|
8e128526
Mihail
add xlsx parser
|
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
}
$this->row = array_combine($this->keys, $this->row);
}
// попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений
$this->row = $this->convert($this->row);
// обрежем массив к первой значимой колонке
if ( $this->first_column ) {
$this->row = array_slice($this->row, $this->first_column);
}
}
protected function setKeysFromHeader(){
if ( $this->has_header_row ) {
// в файле есть заголовок, но он еще не назначен - назначим
if ($this->keys === NULL) {
$this->keys = array_values( $this->row );
|
d1fac7a9
Mihail
add parsing sheet...
|
157
|
return true;
|
8e128526
Mihail
add xlsx parser
|
158
159
|
}
}
|
d1fac7a9
Mihail
add parsing sheet...
|
160
|
return false;
|
8e128526
Mihail
add xlsx parser
|
161
162
163
|
}
protected function filterRow(){
|
cd8b9f70
Mihail
add cleanUp metho...
|
164
|
// если есть заголовок - все значения нужны, не фильтруем
|
221da14e
Mihail
change SplFileObj...
|
165
|
if ( $this->has_header_row || !is_array( $this->row ) ) {
|
d1fac7a9
Mihail
add parsing sheet...
|
166
167
|
return;
}
|
8e128526
Mihail
add xlsx parser
|
168
169
170
|
$this->row = array_filter( $this->row, function($val){
return !$this->isEmptyColumn($val);
});
|
8e128526
Mihail
add xlsx parser
|
171
172
173
174
175
176
177
178
179
180
181
|
}
protected function isLastLine(){
if ( ( $this->last_line ) && ( $this->current_row_number > $this->last_line ) ) {
return true;
}
return false;
}
}
|