Laravel 8: Excel (xlsx) reader

C++ JAVA
Правила на форума
Моля, маркирайте отговора на потребитeля, който най-много ви е помогнал за решаването на проблема/въпроса Ви!
Повече за системата за оценяване може да прочетете тук: viewtopic.php?f=28&t=130265
Аватар

Revelation
Web-tourist
Web-tourist
Reactions: 8
Мнения: 984
Регистриран на: Нед Мар 24, 2013 1:23 pm
Support: 68
8

Re: Laravel 8: Excel (xlsx) reader

Мнение от Revelation »

dakata__92 написа: Чет Ное 11, 2021 10:40 am
Revelation написа: Чет Ное 11, 2021 9:00 am Учудвам се, че библиотеката не предлага ни итератори, ни генератори, ни стриймове...

Колко големи файлове имаш? Гигабайти?
Искам да извъртам поне 100 000 реда от sheet. Това значи, че доста ще се натовари системата. Гледам, че има някакви chunk филтри, но не сработват, когато се налага да чета от няколко sheet-а. Тъпото от цялата работа е, че дори нямам филтър за skip на празни редове. Реално ако Имам на ред 1 някакъв текст по колоните, то ако сложа чак на ред 5 някакъв текст, реално $worksheet->toArray(); ще ми върне масив от ред 1 до 5, като 2, 3 и 4 ще са празни... Като взема масива $documentRows за вторична валидация ще итерирам не два реда с резултат а 5.
Потърси библиотека, която може да работи със стриймове от данни. С тази ще имаш проблеми понеже се опитва да зарежда всичко в паметта.

Според мен тази https://opensource.box.com/spout/docs/ би ти свършила доста по-добра работа. И като гледам имаш опция дали да задържаш празни редове или не.
Не съм и чел кода, но според описанието изглежда, че са я написали като хората и не се опитват да ти заредят огромен файл в паметта.
Аватар

Topic author
dakata__92
Web-tourist
Web-tourist
Reactions: 2
Мнения: 3410
Регистриран на: Вто Авг 02, 2011 7:24 pm
Support: 128
10

Re: Laravel 8: Excel (xlsx) reader

Мнение от dakata__92 »

Revelation написа: Чет Ное 11, 2021 5:21 pm
dakata__92 написа: Чет Ное 11, 2021 10:40 am
Revelation написа: Чет Ное 11, 2021 9:00 am Учудвам се, че библиотеката не предлага ни итератори, ни генератори, ни стриймове...

Колко големи файлове имаш? Гигабайти?
Искам да извъртам поне 100 000 реда от sheet. Това значи, че доста ще се натовари системата. Гледам, че има някакви chunk филтри, но не сработват, когато се налага да чета от няколко sheet-а. Тъпото от цялата работа е, че дори нямам филтър за skip на празни редове. Реално ако Имам на ред 1 някакъв текст по колоните, то ако сложа чак на ред 5 някакъв текст, реално $worksheet->toArray(); ще ми върне масив от ред 1 до 5, като 2, 3 и 4 ще са празни... Като взема масива $documentRows за вторична валидация ще итерирам не два реда с резултат а 5.
Потърси библиотека, която може да работи със стриймове от данни. С тази ще имаш проблеми понеже се опитва да зарежда всичко в паметта.

Според мен тази https://opensource.box.com/spout/docs/ би ти свършила доста по-добра работа. И като гледам имаш опция дали да задържаш празни редове или не.
Не съм и чел кода, но според описанието изглежда, че са я написали като хората и не се опитват да ти заредят огромен файл в паметта.
Принципно, накрая се двоумех между тази, която ти предлагаш и https://packagist.org/packages/phpoffice/phpspreadsheet. Избрах втората, защото е наследник на PHPExcel, която не бе толкова зле. Реално цялата обработка на файловете съм я изнесъл на schedule задача и сметнах, че ще е добре да използвам масов продукт с добра поддръжка. Обработката при мен става офлайн, така че за момента файлове от рода на 200 000 реда се зареждат в пълна готовност за вторична обработка, за 14 секунди. Реално мисля да забраня файлове над 3 MB, но тук още не съм се интересувал горе долу на колко реда от шаблона на системата се равнява това (само ще предположа че са около 500 000 итерации).

Понеже няма филтър за пропускане на празни редове, си създадох мой и ще го споделя за колегите, които мислят, че ще им е полезно.

Код за потвърждение: Избери целия код

switch ($extension) {
	case 'xls':
	case 'xlsx':
		try {
			$reader = IOFactory::createReaderForFile($documentPath);
			$reader->setReadDataOnly(true);
			$spreadsheet = $reader->load($documentPath);
			$sheets = $spreadsheet->getAllSheets();
			foreach ($sheets as $sheet) {
				$sheetRows = self::removeEmptyRowsFromTwoDimensionArray($sheet->toArray());
				$documentRows[] = $sheetRows;
			}
		} catch (\Throwable $e) {
			$documentRows = [];
		}
		break;
}

public static function removeEmptyRowsFromTwoDimensionArray(array $data): array
{
	return array_filter($data, function($value) {
		if (is_array($value) && empty(array_diff($value, [null]))) {
			return false;
		}
		return true;
	});
}


Иска ми се да намаля времето за зареждане на файла, за да не тормозя сървърите излишно. Принципно сме на собствени машини и няма проблем, но пък ако има вариант да спестя ресурси от тези операции, ще е добре.
Аватар

Revelation
Web-tourist
Web-tourist
Reactions: 8
Мнения: 984
Регистриран на: Нед Мар 24, 2013 1:23 pm
Support: 68
8

Re: Laravel 8: Excel (xlsx) reader

Мнение от Revelation »

И двете, които споменаваш куцат, когато става въпрос за големи файлове.
Аватар

djman
Гуру
Гуру
Reactions: 0
Мнения: 2842
Регистриран на: Съб Сеп 12, 2009 8:07 am
Support: 112
12

Re: Laravel 8: Excel (xlsx) reader

Мнение от djman »

Дака, наистина няма как да минеш без стриминг или нещо от сорта за големи файлове. Право казва Revelation...
Аватар

Topic author
dakata__92
Web-tourist
Web-tourist
Reactions: 2
Мнения: 3410
Регистриран на: Вто Авг 02, 2011 7:24 pm
Support: 128
10

Re: Laravel 8: Excel (xlsx) reader

Мнение от dakata__92 »

Момчета, не ме отчайвайте. Тази библиотека (phpoffice/phpspreadsheet), която съм избрал, няма ли възможност да чете файла на порции, без да го зарежда накуп? В частност видях, че има възможност да се използват филтри, но никъде няма пример за комбиниране на филтри и sheet-ове. Така или иначе файловете, които ще чете библиотеката, реално са вече качени на машината и започва да ги обработва и валидира.
Аватар

Revelation
Web-tourist
Web-tourist
Reactions: 8
Мнения: 984
Регистриран на: Нед Мар 24, 2013 1:23 pm
Support: 68
8

Re: Laravel 8: Excel (xlsx) reader

Мнение от Revelation »

Като цяло не разбрах какъв е проблема с библиотеката, която предложих.

Не казвам, че трябва да я ползваш, но ако я тестваш и ти върши работата, която трябва да ти свърши, не виждам защо трябва да се мъчиш с тази, с която не можеш да намериш решение на проблемите си.

Не винаги броя сваляния на дадена библиотека означава, че тя е най-добрата, особено когато не върши това, което ти искаш.

Като цяло в момента очакваш някой да ти даде решение на твоя проблем, който вероятно можеш да решиш по различен начин, с по-малко мъки.

Ти гледай, че не съм тръгнал да ти давам решения на Go. :D
Аватар

Topic author
dakata__92
Web-tourist
Web-tourist
Reactions: 2
Мнения: 3410
Регистриран на: Вто Авг 02, 2011 7:24 pm
Support: 128
10

Re: Laravel 8: Excel (xlsx) reader

Мнение от dakata__92 »

Revelation написа: Пет Ное 12, 2021 5:22 pm Като цяло не разбрах какъв е проблема с библиотеката, която предложих.

Не казвам, че трябва да я ползваш, но ако я тестваш и ти върши работата, която трябва да ти свърши, не виждам защо трябва да се мъчиш с тази, с която не можеш да намериш решение на проблемите си.

Не винаги броя сваляния на дадена библиотека означава, че тя е най-добрата, особено когато не върши това, което ти искаш.

Като цяло в момента очакваш някой да ти даде решение на твоя проблем, който вероятно можеш да решиш по различен начин, с по-малко мъки.

Ти гледай, че не съм тръгнал да ти давам решения на Go. :D
Не ме плаши с GO, че съм си качил Swoole. 😁

Аз питам за оптимизация. Тук има хора, които са ползвали библиотеката много преди мен. Реално погледнато, дори да я оставя в сегашният и вид, няма да бутна системата, а тази библиотека ми дава и други благинки, които ще използвам, за това не се отказвам от нея.
1
Аватар

Topic author
dakata__92
Web-tourist
Web-tourist
Reactions: 2
Мнения: 3410
Регистриран на: Вто Авг 02, 2011 7:24 pm
Support: 128
10

Re: Laravel 8: Excel (xlsx) reader

Мнение от dakata__92 »

Някой опитвал ли се е да кешира съдържанието с вградената кешираща система на Laravel? Открих един опит в нета, но нещо май не е сполучил.
I am not sure this is the best way to acquire a Simple Cache interface from Laravel, but PhpSpreadsheet seemed to be interacting with our Redis cache. However, 197K round trips over the network was going to take far too long. I gave up after waiting 5 minutes.

Код за потвърждение: Избери целия код

$cache = new Cache();
$cacheStore = $cache::getStore();
$cacheInterface = new Repository($cacheStore);
Settings::setCache($cacheInterface);

$spreadsheet = new Spreadsheet();
Това казва документацията на библиотеката:
https://phpspreadsheet.readthedocs.io/e ... ry_saving/
Публикувай отговор