PHPExcel лишний лист

VANHALEN

Новичок
Здравствуйте!
Проблема такая. Хочу сделать прайс лист в екселе, чтобы автоматом из магазина создавался при обращении к нему. Пользуюсь PHPExcel. Товары каждой категории магазина должны быть на своём отдельном листе. в цикле создаю листы в документе и называю их по имени категории. Непонятка немного заключается в индексах листов. В конце получается лишний лист с названием "Worksheet 1" Как то не в доках ни где не нашёл ответа на свой вопрос.
PHP:
<?PHP
require_once('Classes/PHPExcel.php');                                // Подключаем класс для работы с excel
require_once('Classes/PHPExcel/Writer/Excel5.php');        // Подключаем класс для вывода данных в формате excel
$xls = new PHPExcel();   

$content = mysql_query("Вытягиваем категории магазина");       
$list = 0;
while ($row = mysql_fetch_array($content))
    {       
        $category[$row['category_id']] = $row['name_ru-RU'];
       
        $xls->createSheet();
        $xls->setActiveSheetIndex($list);   
        $sheet = $xls->getActiveSheet();
           
        if (strlen($row['name_ru-RU']) > 50)  {$sheet->setTitle(crop_name($row['name_ru-RU'], 28));} else {$sheet->setTitle($row['name_ru-RU']);}
       
        // Здесь создаём на каждом листе колонки, обзываем их, оформляем и т.д.
       
        $list++;
    }
?>
В принципе я задницей чувствую, что ещё до цикла, при $xls = new PHPExcel(); создаётся не только документ, но и первый лист. Но ведт вроде у него и индекс должен быть - ноль. Я же к нему к первому и обращаюсь.
 

VANHALEN

Новичок
Ой.. ступил.. Сам догадался первый раз пропустить и тогда первым заполняется уже готовый лист, созданый в начале
PHP:
if ($list > 0) {$xls->createSheet();}
Вот так всё правильно.
 

VANHALEN

Новичок
Я не знаю, стоит ли специально создавать новую тему, но следующий вопрос такой. Нельзя ли как-то извернуться и прямо внутри этого цикла и заполнить всё. Сейчас получается так, что я сначала создаю листы, потом вытягиваю товары и сопоставляя (присваивая порядковый номер категория = лист) заполняю их. Но хрень в том, что мне ещё ведт нужно отловить на каждом листе на какой строке находится последняя запись, иначе лист может выглядеть так - 2-3 строки с товарами, потом пропуск 5 строк, потом опять строки, поскольку строки то он считает по порядку, когда вставляет. Вот такая вот задачка. Кто сталкивался?
 

AnrDaemon

Продвинутый новичок
Вытащи категории сразу, а заполняй листы, когда будешь обрабатывать данные.
И запоминай для каждой категории положение на листе.
А первый лист вообще можно использовать под обложку с данными магазина и любой другой инфой, тогда отпадёт предыдущая проблема с автоматически созданным первым листом.
 

VANHALEN

Новичок
Вытащи категории сразу, а заполняй листы, когда будешь обрабатывать данные.
Так вот у меня сейчас ка раз именно так. Вытащил категории > создал и подписал листы > вытащил товары > пошёл заполнять листы.
Я то как раз хотел попробовать внутри цикла создания листов. Но уже понял, что был не прав. Допустим я вытащил в массив все товары, так вот этот массив придётся пересмотреть столько раз, сколько листов создано в массиве. так что не правильный подход. Действительно заполнять нужно уже после создания листов.
И запоминай для каждой категории положение на листе.
Ну так в этом то и проблема. Не умею. Буду конечно решать, если никто не подскажет, иначе будут пропущеные строки.
А первый лист вообще можно использовать под обложку с данными магазина и любой другой инфой, тогда отпадёт предыдущая проблема с автоматически созданным первым листом.
Так вопрос то решён уже.. да и сама библиотека столько ресурсов жрёт, что жирно будет её ещё и титульный лист создавать. Даже при таком минимальном оформлении, как на мойм скрине (мой конкретный случай) и 1200 товаров, уже ощутимо тормозит. А я ещё хотел каждое название сделать ссылкой. Понял, что лучше не стоит. Но раз идея подана, то буду знать, что первый лист можно оформить до цикла создания листов.
https://cloclo15.datacloudmail.ru/weblink/view/2645e9dbfc83/excel-price.gif?x-email=undefined
 

scorpion-ds

Новичок
Допустим я вытащил в массив все товары, так вот этот массив придётся пересмотреть столько раз, сколько листов создано в массиве. так что не правильный подход.
Удаляй товар из массива когда он уже добавлен в Excel, так хоть массив уменьшаться будет.
Но вообще я делал немного по другому, у меня был массив категорий, а в нем массив с ID товаров в этой категории, потому я всегда знал какие товары есть в категории.

И вопрос уже в тебе, возможно ты уже столкнулся с проблемой нехватки памяти, к примеру мне для формирования Excel в 2000-3000 строк, иногда требовалось не менее 256 Метров, что не всегда доступно на хостинге, я решал данную проблему, просто выбором более серьезного хостинга, но может есть другое решение.
 

WMix

герр M:)ller
Партнер клуба
джойни категории и продукты, сортируй сначала по категории, а после как нужно. отлавливай изменение категории для создания нового листа, ну и необходимых заголовков
 

С.

Продвинутый новичок
А простая сортировка по категории слишком низменно для гигантов мысли?
 

VANHALEN

Новичок
сортируй сначала по категории, а после как нужно. отлавливай изменение категории для создания нового листа, ну и необходимых заголовков
Да да.. У меня эта мысль ещё вчера возникла, как самая очевидная - просто заполнять по очереди каждый лист, вместо того чотбы скакать туда - сюда. Я просто изначально полагал, что отследить последнюю позицию на листе и вбить туда не проблема, но раз такое дело, тогда даже пробовать не буду отслеживать последнюю позицию.
Удаляй товар из массива когда он уже добавлен в Excel, так хоть массив уменьшаться будет.
Спасибо! Реально понравилась идея. Действительно, самый большой массив - массив именно с товарами и если массив с категориями нужен всегда для сортировки, то после вставки товара, элемент массива действительно больше ни к чему.
к примеру мне для формирования Excel в 2000-3000 строк, иногда требовалось не менее 256 Метров
Это что, уже после того, когда злементы массива начал удалять после вставки? Если да, то ситуация плачевная. Не все клиенты захотят доплатить 200 деревянных, только ради того, чтобы прайс лист скачать.
 

WMix

герр M:)ller
Партнер клуба
VANHALEN, определись для начала, можешь позволить себе считать данные заранее или нет. ексель каким бы он нибыл будет тоже в памяти.
удаление из масива - экономия на спичках. построчное считывание имеет смысл только если сразу форматировать и отдавать документ типа csv.
 

scorpion-ds

Новичок
Это что, уже после того, когда злементы массива начал удалять после вставки? Если да, то ситуация плачевная. Не все клиенты захотят доплатить 200 деревянных, только ради того, чтобы прайс лист скачать.
Нет, это проблема самой библиотеки PHPExcel, она потребляет слишком много памяти, каждая строка, колонка и ячейка это объект, когда их накапливается много, то расход памяти ощутимо возрастает.
 

VANHALEN

Новичок
построчное считывание имеет смысл только если сразу форматировать и отдавать документ типа csv.
Как раз мой случай. Только не csv, а xls. И именно выдаю файл готовый. А сохранять на сервере вроде как и ни к чему.
определись для начала, можешь позволить себе считать данные заранее или нет
Тоесть? Хватит ли у меня памяти? Ну допустим магазин разросся, памяти не хватает. И что оно мне сделает? Просто выдаст ошибку. В таком случае просто удаляешь к херам папку и не поьзуешься (у меня просто папка кладётся со скриптом, подхватывает настройки магазина и генерит прайс). Какие тут ещё могут быть варианты? Если только извернуться и записывать файл в кеш, или на диск, потом открывать его ещё раз, смотреть где остановился и дописывать ещё 100 позиций и так до тех пор, пока весь каталог там не окажется. Но это вроде уже про дургое история.
 

scorpion-ds

Новичок
Какие тут ещё могут быть варианты? Если только извернуться и записывать файл в кеш, или на диск, потом открывать его ещё раз, смотреть где остановился и дописывать ещё 100 позиций и так до тех пор, пока весь каталог там не окажется. Но это вроде уже про дургое история.
Думаю в случае с PHPExcel "допись" в файл не решит проблему, при открытии файла в режиме записи, он все равно весь поместится в память ...
 

VANHALEN

Новичок
Вобщем проверил сейчас на реальном хостинге для интереса. Хостер nic.ru 260 рублей в месяц. PHP 5.3, можно выбрать другой. Всё настраивается, память под процессы тоже. Сейчас правда выставлено 128 мегов. 7 листов, 1266 товаров - даже не тормозит. Правда не раскидывал по страницам, но зато оформление (выравнивание в ячейках + пара ячеек в начале стилизованы). Так, что проблема вроде как не самая серьёзная.
 
Сверху