8e128526
Mihail
add xlsx parser
|
1
2
3
4
5
6
7
8
|
<?php
/**
* Created by PhpStorm.
* User: Tsurkanov
* Date: 21.10.2015
* Time: 15:44
*/
|
d0261fd1
Mihail
fixed namespace i...
|
9
|
namespace yii\multiparser;
|
f6e54131
Mihail
fixed keys and he...
|
10
|
|
735c416d
Mihail
add compatibility...
|
11
|
use common\components\CustomVarDamp;
|
8e128526
Mihail
add xlsx parser
|
12
|
|
8e128526
Mihail
add xlsx parser
|
13
|
|
8e128526
Mihail
add xlsx parser
|
14
15
|
/**
* Class XlsxParser
|
d0261fd1
Mihail
fixed namespace i...
|
16
|
* @package yii\multiparser
|
8e128526
Mihail
add xlsx parser
|
17
|
*/
|
f6e54131
Mihail
fixed keys and he...
|
18
19
|
class XlsxParser extends TableParser
{
|
8e128526
Mihail
add xlsx parser
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
/**
* @var string - путь куда будут распаковываться файлы, если не указанно - во временный каталог сервера
*/
public $path_for_extract_files = '';
/**
* @var int - если указано то считывание будет производиться с этого листа, иначе со всех листов
* при чтении со всех листов - выходной массив будет иметь номера листов первыми элементами
*/
public $active_sheet = 0;
protected $strings_arr = [];
protected $sheets_arr = [];
protected $current_node;
protected $current_sheet;
public function setup()
{
parent::setup();
|
f6e54131
Mihail
fixed keys and he...
|
44
|
if ($this->path_for_extract_files == '') {
|
8e128526
Mihail
add xlsx parser
|
45
46
47
48
49
50
51
|
$this->path_for_extract_files = sys_get_temp_dir();
}
}
public function read()
{
|
f6e54131
Mihail
fixed keys and he...
|
52
|
$this->extractFiles();
|
8e128526
Mihail
add xlsx parser
|
53
54
|
$this->readSheets();
$this->readStrings();
|
f6e54131
Mihail
fixed keys and he...
|
55
|
foreach ($this->sheets_arr as $sheet) {
|
8e128526
Mihail
add xlsx parser
|
56
|
//проходим по всем файлам из директории /xl/worksheets/
|
0c6fd004
Mihail
fixed issue with ...
|
57
|
$this->current_sheet = $sheet;
|
8e128526
Mihail
add xlsx parser
|
58
|
$sheet_path = $this->path_for_extract_files . '/xl/worksheets/' . $sheet . '.xml';
|
f6e54131
Mihail
fixed keys and he...
|
59
60
|
if (file_exists($sheet_path) && is_readable($sheet_path)) {
$xml = simplexml_load_file($sheet_path, "SimpleXMLIterator");
|
8e128526
Mihail
add xlsx parser
|
61
62
|
$this->current_node = $xml->sheetData->row;
$this->current_node->rewind();
|
f6e54131
Mihail
fixed keys and he...
|
63
|
if ($this->current_node->valid()) {
|
0c6fd004
Mihail
fixed issue with ...
|
64
|
parent::read();
|
0c6fd004
Mihail
fixed issue with ...
|
65
|
}
|
8e128526
Mihail
add xlsx parser
|
66
|
}
|
8e128526
Mihail
add xlsx parser
|
67
|
}
|
0c6fd004
Mihail
fixed issue with ...
|
68
|
|
cd8b9f70
Mihail
add cleanUp metho...
|
69
|
$this->cleanUp();
|
735c416d
Mihail
add compatibility...
|
70
|
|
f6e54131
Mihail
fixed keys and he...
|
71
|
if ($this->active_sheet) {
|
735c416d
Mihail
add compatibility...
|
72
|
// в настройках указан конкретный лист с которого будем производить чтение, поэтому и возвращаем подмассив
|
f6e54131
Mihail
fixed keys and he...
|
73
74
|
return $this->result[$this->current_sheet];
} else {
|
0c6fd004
Mihail
fixed issue with ...
|
75
76
77
|
return $this->result;
}
|
8e128526
Mihail
add xlsx parser
|
78
79
|
}
|
f6e54131
Mihail
fixed keys and he...
|
80
|
protected function extractFiles()
|
8e128526
Mihail
add xlsx parser
|
81
|
{
|
0c6fd004
Mihail
fixed issue with ...
|
82
|
$this->path_for_extract_files = $this->path_for_extract_files . session_id();
|
f6e54131
Mihail
fixed keys and he...
|
83
84
85
|
if (!file_exists($this->path_for_extract_files)) {
if (!mkdir($this->path_for_extract_files)) {
throw new \Exception('Ошибка создания временного каталога - ' . $this->path_for_extract_files);
|
0c6fd004
Mihail
fixed issue with ...
|
86
|
}
|
735c416d
Mihail
add compatibility...
|
87
|
}
|
0c6fd004
Mihail
fixed issue with ...
|
88
|
|
8e128526
Mihail
add xlsx parser
|
89
|
$zip = new \ZipArchive;
|
f6e54131
Mihail
fixed keys and he...
|
90
91
|
if ($zip->open($this->file_path) === TRUE) {
$zip->extractTo($this->path_for_extract_files . '/');
|
8e128526
Mihail
add xlsx parser
|
92
93
|
$zip->close();
} else {
|
735c416d
Mihail
add compatibility...
|
94
|
|
f6e54131
Mihail
fixed keys and he...
|
95
|
throw new \Exception('Ошибка чтения xlsx файла');
|
8e128526
Mihail
add xlsx parser
|
96
|
}
|
221da14e
Mihail
change SplFileObj...
|
97
|
unset($zip);
|
8e128526
Mihail
add xlsx parser
|
98
99
|
}
|
f6e54131
Mihail
fixed keys and he...
|
100
|
protected function readSheets()
|
8e128526
Mihail
add xlsx parser
|
101
|
{
|
f6e54131
Mihail
fixed keys and he...
|
102
103
|
if ($this->active_sheet) {
$this->sheets_arr[] = 'sheet' . $this->active_sheet;
|
8e128526
Mihail
add xlsx parser
|
104
105
106
|
return;
}
|
f6e54131
Mihail
fixed keys and he...
|
107
108
|
$xml = simplexml_load_file($this->path_for_extract_files . '/xl/workbook.xml');
foreach ($xml->sheets->children() as $sheet) {
|
8e128526
Mihail
add xlsx parser
|
109
110
111
|
$sheet_name = '';
$sheet_id = 0;
$attr = $sheet->attributes();
|
f6e54131
Mihail
fixed keys and he...
|
112
|
foreach ($attr as $name => $value) {
|
8e128526
Mihail
add xlsx parser
|
113
114
115
116
117
118
119
|
if ($name == 'name')
$sheet_name = (string)$value;
if ($name == 'sheetId')
$sheet_id = $value;
}
|
f6e54131
Mihail
fixed keys and he...
|
120
|
if ($sheet_name && $sheet_id) {
|
8e128526
Mihail
add xlsx parser
|
121
122
123
124
125
126
|
$this->sheets_arr[$sheet_name] = 'Sheet' . $sheet_id;
}
//
}
}
|
f6e54131
Mihail
fixed keys and he...
|
127
|
protected function readStrings()
|
8e128526
Mihail
add xlsx parser
|
128
|
{
|
f6e54131
Mihail
fixed keys and he...
|
129
130
|
$xml = simplexml_load_file($this->path_for_extract_files . '/xl/sharedStrings.xml');
foreach ($xml->children() as $item) {
|
8e128526
Mihail
add xlsx parser
|
131
132
133
134
135
|
$this->strings_arr[] = (string)$item->t;
}
}
|
f6e54131
Mihail
fixed keys and he...
|
136
|
protected function readRow()
|
8e128526
Mihail
add xlsx parser
|
137
|
{
|
0c6fd004
Mihail
fixed issue with ...
|
138
|
$this->row = [];
|
8e128526
Mihail
add xlsx parser
|
139
|
$node = $this->current_node->getChildren();
|
0c6fd004
Mihail
fixed issue with ...
|
140
141
142
|
if ($node === NULL) {
return;
}
|
f6e54131
Mihail
fixed keys and he...
|
143
144
|
for ($node->rewind(), $i = 0; $node->valid(); $node->next(), $i++) {
|
0c6fd004
Mihail
fixed issue with ...
|
145
|
$child = $node->current();
|
8e128526
Mihail
add xlsx parser
|
146
147
|
$attr = $child->attributes();
|
f6e54131
Mihail
fixed keys and he...
|
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
// define the index of result array
// $attr['r'] - contain the address of cells - A1, B1 ...
if (isset($attr['r'])) {
// override index
$i = $this->convertCellToIndex( $attr['r'] );
if ( $this->keys !== Null ){
if( isset( $this->keys[$i] ) ){
//$i = $this->keys[$i];
} else {
// we have a keys, but this one we didn't find, so skip it
continue;
}
}
}
// define the value of result array
if (isset($child->v)) {
|
8e128526
Mihail
add xlsx parser
|
165
|
$value = (string)$child->v;
|
f6e54131
Mihail
fixed keys and he...
|
166
167
168
169
170
171
|
if ( isset($attr['t']) )
// it's not a value it's a string, so fetch it from string array
$value = $this->strings_arr[$value];
} else {
|
8e128526
Mihail
add xlsx parser
|
172
173
|
$value = '';
}
|
f6e54131
Mihail
fixed keys and he...
|
174
175
176
|
// set
$this->row[$i] = $value;
|
8e128526
Mihail
add xlsx parser
|
177
178
|
}
|
f6e54131
Mihail
fixed keys and he...
|
179
180
181
182
183
184
185
186
187
188
189
190
|
// // fill the row by empty values for keys that we are missed in previous step
// only for 'has_header_row = true' mode
if ( $this->has_header_row && $this->keys !== Null ) {
$extra_column = count( $this->keys ) - count( $this->row );
if ( $extra_column ) {
foreach ( $this->keys as $key => $key ) {
if ( isset( $this->row[$key] ) ) {
continue;
}
$this->row[$key] = '';
}
|
0c6fd004
Mihail
fixed issue with ...
|
191
|
}
|
f6e54131
Mihail
fixed keys and he...
|
192
|
|
0c6fd004
Mihail
fixed issue with ...
|
193
|
}
|
f6e54131
Mihail
fixed keys and he...
|
194
|
ksort( $this->row );
|
8e128526
Mihail
add xlsx parser
|
195
|
$this->current_node->next();
|
8e128526
Mihail
add xlsx parser
|
196
197
|
}
|
f6e54131
Mihail
fixed keys and he...
|
198
199
|
protected function isEmptyRow()
{
|
8e128526
Mihail
add xlsx parser
|
200
201
|
$is_empty = false;
|
8e128526
Mihail
add xlsx parser
|
202
|
|
f6e54131
Mihail
fixed keys and he...
|
203
|
if (!count($this->row) || !$this->current_node->valid()) {
|
8e128526
Mihail
add xlsx parser
|
204
205
206
207
|
return true;
}
$j = 0;
|
f6e54131
Mihail
fixed keys and he...
|
208
|
for ($i = 1; $i <= count($this->row); $i++) {
|
8e128526
Mihail
add xlsx parser
|
209
|
|
f6e54131
Mihail
fixed keys and he...
|
210
|
if (isset($this->row[$i - 1]) && $this->isEmptyColumn($this->row[$i - 1])) {
|
8e128526
Mihail
add xlsx parser
|
211
212
213
|
$j++;
}
|
f6e54131
Mihail
fixed keys and he...
|
214
|
if ($j >= $this->min_column_quantity) {
|
8e128526
Mihail
add xlsx parser
|
215
216
217
218
219
220
221
222
|
$is_empty = true;
break;
}
}
return $is_empty;
}
|
f6e54131
Mihail
fixed keys and he...
|
223
224
|
protected function isEmptyColumn($val)
{
|
8e128526
Mihail
add xlsx parser
|
225
226
|
return $val == '';
}
|
0c6fd004
Mihail
fixed issue with ...
|
227
|
|
f6e54131
Mihail
fixed keys and he...
|
228
229
230
|
protected function setResult()
{
$this->result[$this->current_sheet][] = $this->row;
|
0c6fd004
Mihail
fixed issue with ...
|
231
232
|
}
|
f6e54131
Mihail
fixed keys and he...
|
233
|
protected function deleteExtractFiles()
|
0c6fd004
Mihail
fixed issue with ...
|
234
|
{
|
f6e54131
Mihail
fixed keys and he...
|
235
|
$this->removeDir($this->path_for_extract_files);
|
0c6fd004
Mihail
fixed issue with ...
|
236
237
238
|
}
|
f6e54131
Mihail
fixed keys and he...
|
239
240
|
protected function removeDir($dir)
{
|
0c6fd004
Mihail
fixed issue with ...
|
241
242
243
244
|
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
|
f6e54131
Mihail
fixed keys and he...
|
245
246
|
if (filetype($dir . "/" . $object) == "dir")
$this->removeDir($dir . "/" . $object);
|
0c6fd004
Mihail
fixed issue with ...
|
247
|
else
|
f6e54131
Mihail
fixed keys and he...
|
248
|
unlink($dir . "/" . $object);
|
0c6fd004
Mihail
fixed issue with ...
|
249
250
251
252
253
254
255
|
}
}
reset($objects);
rmdir($dir);
}
}
|
cd8b9f70
Mihail
add cleanUp metho...
|
256
|
|
f6e54131
Mihail
fixed keys and he...
|
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
/**
* @param $cell_address - string with address like A1, B1 ...
* @return int - integer index
* this method has a constraint - 'Z' - it's a last column to convert,
* column with 'AA..' address and bigger - return index = 0
*/
protected function convertCellToIndex($cell_address)
{
$index = 0;
$address_letter = substr($cell_address, 0, 1);
$address_arr = range('A', 'Z');
if ( $search_value = array_search( $address_letter, $address_arr ) )
$index = $search_value;
return $index;
}
// @todo - переписать родительский метод в универсальной манере а не переопределять его
protected function setKeysFromHeader(){
if ( $this->has_header_row ) {
if ($this->keys === NULL) {
$this->keys = $this->row;
return true;
}
}
return false;
}
|
cd8b9f70
Mihail
add cleanUp metho...
|
287
|
protected function cleanUp()
|
0c6fd004
Mihail
fixed issue with ...
|
288
|
{
|
cd8b9f70
Mihail
add cleanUp metho...
|
289
290
291
292
293
|
parent::cleanUp();
unset($this->strings_arr);
unset($this->sheets_arr);
unset($this->current_node);
|
cd8b9f70
Mihail
add cleanUp metho...
|
294
|
|
0c6fd004
Mihail
fixed issue with ...
|
295
296
|
}
|
f6e54131
Mihail
fixed keys and he...
|
297
298
299
300
301
|
function __destruct()
{
$this->deleteExtractFiles();
}
|
0c6fd004
Mihail
fixed issue with ...
|
302
|
|
8e128526
Mihail
add xlsx parser
|
303
|
}
|