Дайте этому попытку, это обошлось без задания, имеющего необходимость измениться/добавить много существующего кода.
>>> class foo(object):
... _var = 5
... def getvar(cls):
... return cls._var
... getvar = classmethod(getvar)
... def setvar(cls, value):
... cls._var = value
... setvar = classmethod(setvar)
... var = property(lambda self: self.getvar(), lambda self, val: self.setvar(val))
...
>>> f = foo()
>>> f.var
5
>>> f.var = 3
>>> f.var
3
property
для функции нужно два callable
аргументы. дайте им обертки лямбды (который это передает экземпляр как свой первый аргумент), и все хорошо.
Заполняет ли лист? или сохранение? что вы считаете слишком медленным?
Как вы заполняете электронную таблицу данными?
fromArray()
более эффективно, чем заполнение каждой отдельной ячейки, особенно если вы используете Advanced Value Binder для автоматической установки типов данных ячеек. Если вы устанавливаете значения для каждой отдельной ячейки на листе, используя
$objPHPExcel->getActiveSheet()->setCellValue('A1',$x);
$objPHPExcel->getActiveSheet()->setCellValue('B1',$y);
, используйте
$sheet = $objPHPExcel->getActiveSheet();
$sheet->setCellValue('A1',$x);
$sheet->setCellValue('B1',$y);
, чтобы получить доступ только к getActiveSheet()
метод один раз; или воспользуйтесь преимуществами свободного интерфейса для установки нескольких ячеек с помощью одного вызова $objPHPExcel->getActiveSheet()
$objPHPExcel->getActiveSheet()->setCellValue('A1',$x)
->setCellValue('B1',$y);
Вы прокомментировали применение стилей к диапазонам ячеек:
applyFromArray()
для установки всего набора настроек стиля за один раз. Если вы используете формулы в своей книге, при сохранении:
Используйте
$objWriter->setPreCalculateFormulas(false)
для отключения вычисления формул внутри самого PHPExcel.
Это всего лишь несколько советов, которые помогут повысить производительность, и в темах форума предлагается множество других. Все они не обязательно помогут, слишком многое зависит от вашей конкретной рабочей тетради, чтобы дать какие-то абсолюты, но вы должны быть в состоянии улучшить эту медленную скорость. Даже небольшой блокнот, который я использую для разработки, может написать файл Excel 2007 с 3 рабочими листами, 20 столбцов и 2000 строк быстрее, чем ваш рабочий сервер.
РЕДАКТИРОВАТЬ
Если бы можно было просто улучшить скорость самого PHPExcel, я бы сделал это очень давно. Я постоянно тестирую производительность, чтобы увидеть, как можно улучшить ее скорость. Если вам нужны более высокие скорости, чем может дать сам PHPExcel, то здесь есть список альтернативных библиотек .
Я тоже столкнулся с этой проблемой. Думаю, я бы добавил два цента, так как этот вопрос получил так много просмотров.
Вместо установки значения для каждой ячейки отдельно, используйте метод fromArray()
. Взято и изменено из вики .
$arrayData = array(
array(NULL, 2010, 2011, 2012),
array('Q1', 12, 15, 21),
array('Q2', 56, 73, 86),
array('Q3', 52, 61, 69),
array('Q4', 30, 32, 0),
);
$as = $objPHPExcel->getActiveSheet();
$as->fromArray(
$arrayData, // The data to set
NULL, // Array values with this value will not be set
'C3' // Top left coordinate of the worksheet range where
// we want to set these values (default is A1)
);
Static
Также быстрее применять стили для диапазона, чем устанавливать стиль для каждой ячейки индивидуально (замечая шаблон ??).
$default_style = array(
'font' => array(
'name' => 'Verdana',
'color' => array('rgb' => '000000'),
'size' => 11
),
'alignment' => array(
'horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER
),
'borders' => array(
'allborders' => array(
'style' => \PHPExcel_Style_Border::BORDER_THIN,
'color' => array('rgb' => 'AAAAAA')
)
)
);
// Apply default style to whole sheet
$as->getDefaultStyle()->applyFromArray($default_style);
$titles = array(
'Name',
'Number',
'Address',
'Telephone'
);
$title_style = array(
'font' => array(
'bold' => true
),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array('rgb' => '5CACEE')
),
'alignment' => array(
'wrap' => true
)
);
$as->fromArray($titles, null, 'A1'); // Add titles
$last_col = $as->getHighestColumn(); // Get last column, as a letter
// Apply title style to titles
$as->getStyle('A1:'.$last_col.'1')->applyFromArray($title_style);
Динамически
Я использую PHPExcel для проверки данных, приведенных в электронной таблице, с текущими данными в базе данных. Поскольку каждая ячейка проверяется индивидуально, я помещаю стили в массив (null для стиля нет) и использую цикл ниже, чтобы получить диапазон ячеек, к которым будет применен стиль.
/*
* $row is previously set in a loop iterating through each
* row from the DB, which is equal to a spreadsheet row.
* $styles = array(0 => 'error', 1 => 'error', 2 => null, 3 => 'changed', ...);
*/
$start = $end = $style = null;
foreach ($styles as $col => $s) {
if (!$style && !$s) continue;
if ($style === $s) {
$end = $col;
} else {
if ($style) {
$array = null;
switch ($style) {
case 'changed':
$array = $this->changed_style;
break;
case 'error':
$array = $this->error_style;
break;
case 'ignored':
$array = $this->ignored_style;
break;
}
if ($array) {
$start = \PHPExcel_Cell::stringFromColumnIndex($start);
$end = \PHPExcel_Cell::stringFromColumnIndex($end);
$as->getStyle($start.$row.':'.$end.$row)->applyFromArray($array);
}
}
$start = $end = $col;
$style = $s;
}
}
Я столкнулся с той же проблемой - у меня было около 450 строк с 11 столбцами данных, которые я пытался записать, и я продолжал работать с 30-секундным таймаутом. Мне удалось сократить время выполнения до 2 секунд или менее, добавив все мои новые строки в объеме, а затем пройдя и установив содержимое ячейки после факта. Другими словами, я вставляю 450 строк в одном вызове insertNewRowBefore (), а затем перебираю и устанавливаю содержимое в этих строках позже.
Вроде так:
$num_rows = count($output_rows);
$last_row = $sheet->getHighestRow();
$row = $last_row + 1;
$sheet->insertNewRowBefore($row, $num_rows);
// Now add all of the rows to the spreadsheet
foreach($output_rows as $line) {
$i = 0;
foreach($line as $val) {
// Do your setCellValue() or setCellValueByColumnAndRow() here
$i++;
}
$row++;
}
Я ни в коем случае не эксперт в использовании PHPExcel, но формат OfficeOpenXML (формат файлов * .xlsx) сам по себе является группой файлов XML, упакованных в ZIP-архив с расширением * .xlsx . Если вы цените свою производительность и знаете, какие данные вы будете передавать, может быть, лучше построить собственный генератор XLSX , ограниченный до наиболее важных функций, возможно, сделав некоторые вычисления на уровне базы данных и т. Д. вместо анализа всего документа.
Чтобы сделать это, вы можете начать с анализа файлов, созданных с использованием небольших наборов данных (изменив расширение с * .xlsx на * .zip, распаковав его и просмотрев содержимое отдельных файлов). Таким образом, вы можете определить, что вам действительно нужно, и сгенерировать его самостоятельно (создав соответствующие XML-файлы и упаковав их в ZIP-архив, а затем переименовав в расширение * .xlsx).
Существует также спецификация OfficeOpenXML , которая является большой (несколько тысяч страниц), поэтому я не предлагаю читать ее, если вы действительно этого не хотите. Достаточно создать файлы, которые будут сгенерированы PHPExcel.
Решение, упомянутое выше, не включает никаких советов, связанных с PHPExcel, потому что я не эксперт в этом. Однако ранее я интересовался процессом стандартизации OOXML и был бы рад, если бы знание этого стандарта помогло вам решить вашу проблему.
У меня была точно такая же проблема. Получил файл CSV с 5000 строками и 32 столбцами, который обрабатывался вечно. Оказывается, почти все время, потраченное на «обработку», на самом деле является кодировкой символов, которая по умолчанию настроена на кодирование всего в UTF8. Поэтому, если вы зайдете в свой файл config \ excel.php и прокрутите вниз до кодировки, просто установите его следующим образом:
/*
|--------------------------------------------------------------------------
| Import encoding
|--------------------------------------------------------------------------
*/
'encoding' => array(
'input' => '',
'output' => ''
),
С этим одним - вышеупомянутому файлу требуется около 8 секунд для обработки. Возможно, вы захотите предупредить вашего клиента, чтобы правильно сохранить CSV.
В моем случае я повысил производительность, изменив метод хранения в кэш-памяти gzip cache_in_memory_gzip
$cm = \PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
\PHPExcel_Settings::setCacheStorageMethod($cm);
Для экспорта в XLSX со столбцами a - amj (~ 800) и только ~ 50 строк я также столкнулся с 30-секундной границей. Чтобы протестировать свою программу, я ограничил количество обрабатываемых строк до 7, которые работали за 25 секунд.
Переход от отдельного $ objPHPExcel-> getActiveSheet () к $ sheet (первый совет) фактически увеличил время на ограниченном количестве строк с 25 секунд до 26 секунд.
Что действительно помогло мне, так это замена всех моих getHighestDataColumn () на простую переменную $ column_nr, которая увеличивается в PHP, я пошел с 26 секунд до 7 секунд.
После этого мне удалось обработать все 50 строк за 11 секунд.