Merge 73df02f8c0989f8c7f7516e85473ae0d5e8205f2 into 1891c0b053d43597aaa4c1d7152e5c7f0b52ce91

This commit is contained in:
Rushleader 2016-06-17 06:18:21 +00:00 committed by GitHub
commit 24de1772cb
10 changed files with 271 additions and 6 deletions

0
src/Spout/Writer/AbstractWriter.php Normal file → Executable file
View File

View File

@ -66,6 +66,10 @@ class Writer extends AbstractWriter
$this->globalFunctionsHelper->fputs($this->filePointer, EncodingHelper::BOM_UTF8);
}
public function registerStyle($style) {
return false;
}
/**
* Adds data to the currently opened writer.
*

View File

@ -61,6 +61,10 @@ class Writer extends AbstractMultiSheetsWriter
return $this->book;
}
public function registerStyle($style) {
return false;
}
/**
* Adds data to the currently opened writer.
* If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination

73
src/Spout/Writer/Style/Style.php Normal file → Executable file
View File

@ -56,11 +56,27 @@ class Style
/** @var bool Whether specific font properties should be applied */
protected $shouldApplyFont = false;
protected $verticalAlignment = 'center';
protected $horizontalAlignment = 'center';
protected $hasVerticalAlignment = false;
protected $hasHorizontalAlignment = false;
protected $shouldApplyVerticalAlignment = false;
protected $shouldApplyHorizontalAlignment = false;
/** @var bool Whether the text should wrap in the cell (useful for long or multi-lines text) */
protected $shouldWrapText = false;
/** @var bool Whether the wrap text property was set */
protected $hasSetWrapText = false;
/** @var string Custom number format */
protected $numberFormat = '';
/** @var boolean Whether specific number format has been set */
protected $hasSetNumberFormat = false;
/** @var integer Holds the number format id */
protected $numberFormatId = 0;
/**
* @return int|null
*/
@ -243,6 +259,63 @@ class Style
return $this->shouldApplyFont;
}
public function setNumberFormat($format)
{
$this->numberFormat = $format;
$this->hasSetNumberFormat = true;
return $this;
}
public function setNumberFormatId($id)
{
$this->numberFormatId = $id;
}
public function shouldApplyNumberFormat()
{
return $this->hasSetNumberFormat;
}
public function getNumberFormatId()
{
return $this->numberFormatId;
}
public function getNumberFormat()
{
return $this->numberFormat;
}
public function setVerticalAlignment($alignment) {
$this->verticalAlignment = $alignment;
$this->hasVerticalAlignment = true;
$this->shouldApplyVerticalAlignment = true;
}
public function setHorizontalAlignment($alignment) {
$this->horizontalAlignment = $alignment;
$this->hasHorizontalAlignment = true;
$this->shouldApplyHorizontalAlignment = true;
}
public function getVerticalAlignment() {
return $this->verticalAlignment;
}
public function getHorizontalAlignment() {
return $this->horizontalAlignment;
}
public function shouldApplyVerticalAlignment() {
return $this->shouldApplyVerticalAlignment;
}
public function shouldApplyHorizontalAlignment() {
return $this->shouldApplyHorizontalAlignment;
}
/**
* Serializes the style for future comparison with other styles.
* The ID is excluded from the comparison, as we only care about

16
src/Spout/Writer/Style/StyleBuilder.php Normal file → Executable file
View File

@ -121,6 +121,22 @@ class StyleBuilder
return $this;
}
public function setNumberFormat($format)
{
$this->style->setNumberFormat($format);
return $this;
}
public function setVerticalAlignment($alignment) {
$this->style->setVerticalAlignment($alignment);
return $this;
}
public function setHorizontalAlignment($alignment) {
$this->style->setHorizontalAlignment($alignment);
return $this;
}
/**
* Returns the configured style. The style is cached and can be reused.
*

47
src/Spout/Writer/XLSX/Helper/StyleHelper.php Normal file → Executable file
View File

@ -25,6 +25,7 @@ class StyleHelper extends AbstractStyleHelper
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
EOD;
$content .= $this->getNumberFormatSectionContent();
$content .= $this->getFontsSectionContent();
$content .= $this->getFillsSectionContent();
$content .= $this->getBordersSectionContent();
@ -39,6 +40,31 @@ EOD;
return $content;
}
protected function getNumberFormatSectionContent() {
$formats = array();
$numberFormatCount = 0;
// This is the limit excel holds for the default number formats
$baseNumberFormatId = 163;
foreach($this->getRegisteredStyles() as $style) {
/* If this evals to false we should skip it since it isnt used */
if ($style->shouldApplyNumberFormat()) {
$numberFormatCount++;
$style->setNumberFormatId($baseNumberFormatId + $numberFormatCount);
$formats[] = '<numFmt numFmtId="'.$style->getNumberFormatId().'" formatCode="'.$style->getNumberFormat().'"/>';
}
}
if ($numberFormatCount == 0){
return '';
}
$content = '<numFmts count="'.$numberFormatCount.'">';
$content .= implode('', $formats);
$content .= '</numFmts>';
return $content;
}
/**
* Returns the content of the "<fonts>" section.
*
@ -139,16 +165,29 @@ EOD;
$content = '<cellXfs count="' . count($registeredStyles) . '">';
foreach ($registeredStyles as $style) {
$content .= '<xf numFmtId="0" fontId="' . $style->getId() . '" fillId="0" borderId="0" xfId="0"';
$content .= '<xf numFmtId="'.$style->getNumberFormatId().'" fontId="' . $style->getId() . '" fillId="0" borderId="0" xfId="0"';
if ($style->shouldApplyNumberFormat()) {
$content .= ' applyNumberFormat="1"';
}
if ($style->shouldApplyFont()) {
$content .= ' applyFont="1"';
}
if ($style->shouldWrapText()) {
if ($style->shouldWrapText() || $style->shouldApplyVerticalAlignment() || $style->shouldApplyHorizontalAlignment()) {
$content .= ' applyAlignment="1">';
$content .= '<alignment wrapText="1"/>';
$content .= '</xf>';
$content .= '<alignment ';
if ($style->shouldWrapText()) {
$content .= 'wrapText="1" ';
}
if ($style->shouldApplyVerticalAlignment()) {
$content .= 'vertical="' . $style->getVerticalAlignment() . '" ';
}
if ($style->shouldApplyHorizontalAlignment()) {
$content .= 'horizontal="' . $style->getHorizontalAlignment() . '" ';
}
$content .= '/></xf>';
} else {
$content .= '/>';
}

View File

@ -58,6 +58,10 @@ class Workbook extends AbstractWorkbook
$this->sharedStringsHelper = new SharedStringsHelper($xlFolder);
}
public function registerStyle($style) {
$this->styleHelper->registerStyle($style);
}
/**
* @return \Box\Spout\Writer\XLSX\Helper\StyleHelper Helper to apply styles to XLSX files
*/

View File

@ -133,10 +133,18 @@ EOD;
$rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">';
foreach($dataRow as $cellValue) {
foreach($dataRow as $cell) {
if (is_array($cell)) {
$cellValue = $cell[0];
$cellStyle = $cell[1];
} else {
$cellValue = $cell;
$cellStyle = $style;
}
$columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber);
$cellXML = '<c r="' . $columnIndex . $rowIndex . '"';
$cellXML .= ' s="' . $style->getId() . '"';
$cellXML .= ' s="' . $cellStyle->getId() . '"';
if (CellHelper::isNonEmptyString($cellValue)) {
if ($this->shouldUseInlineStrings) {

View File

@ -64,6 +64,10 @@ class Writer extends AbstractMultiSheetsWriter
return $this;
}
public function registerStyle($style) {
$this->book->registerStyle($style);
}
/**
* Configures the write and sets the current sheet pointer to a new sheet.
*

113
test.php Normal file
View File

@ -0,0 +1,113 @@
<?php
include_once 'src/Spout/Autoloader/autoload.php';
use Box\Spout\Common\Type;
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Writer\Style\StyleBuilder;
# UNIX_DATE = (EXCEL_DATE - 25569) * 86400 : Excel -> unix
# EXCEL_DATE = 25569 + (UNIX_DATE / 86400) : Unix -> excel
$test = function ($name, $sheets, $rows, $cols, $groupedRows = FALSE) {
$start = microtime(TRUE);
$writer = WriterFactory::create(Type::XLSX); // for XLSX files
$writer->openToFile('__'.$name.'.xlsx');
$styleDef = (new StyleBuilder())->setNumberFormat('0.00000')->build();
$styleRed = (new StyleBuilder())->setNumberFormat('[Red]0.00000')->build();
$styleDate = (new StyleBuilder())->setNumberFormat('d-mmm-YY HH:mm:ss')->build();
$writer->registerStyle($styleDef);
$writer->registerStyle($styleRed);
$writer->registerStyle($styleDate);
for ($sheetNum = 0; $sheetNum < $sheets; $sheetNum++) {
if ($sheetNum != 0) {
$sheet = $writer->addNewSheetAndMakeItCurrent();
} else {
$sheet = $writer->getCurrentSheet();
}
$sheet->setName('data'.$sheetNum);
$rowsArr = array();
for ($rowNum = 0; $rowNum < $rows; $rowNum++) {
$row = array();
for ($colNum = 0; $colNum < $cols; $colNum++) {
switch ($colNum % 6) {
default:
$row[] = $colNum;
break;
case 1:
case 3:
$row[] = array($colNum, $styleDef);
break;
case 2:
case 4:
$row[] = array($colNum, $styleRed);
break;
case 5:
$row[] = array(25569 + (time() / 86400), $styleDate);
break;
}
}
$rowsArr[] = $row;
if (!is_int($groupedRows)) {
$writer->addRow($row);
$rowsArr = array();
} else if (count($rowsArr) >= $groupedRows) {
$writer->addRows($rowsArr);
$rowsArr = array();
}
}
if (count($rowsArr)) {
$writer->addRows($rowsArr);
}
}
$writer->close();
$duration = number_format(microtime(TRUE) - $start, 2);
$str = sprintf(' %s took %s seconds to run (%d r/%d c in %d sheets)', $name, $duration, $rows, $cols, $sheets);
echo $str . PHP_EOL;
};
/**
* Bottleneck ATM: Disk usage
*/
$start_mem = memory_get_usage(TRUE);
echo PHP_EOL."Memory Consumption is ";
echo round($start_mem/1048576,2).''.' MB'.PHP_EOL;
$test('1_mini_grouped_00000', 1, 50, 25, FALSE);
exit (0);
$cur_mem = memory_get_usage(TRUE);
echo " Current Consumption is ";
echo round($cur_mem/1048576,2).''.' MB'.PHP_EOL;
$test('2_small_grouped_00000', 10, 7500, 50, FALSE);
$cur_mem = memory_get_usage(TRUE);
echo " Current Consumption is ";
echo round($cur_mem/1048576,2).''.' MB'.PHP_EOL;
$test('3_medium_grouped_00000', 10, 7500, 500, FALSE);
$cur_mem = memory_get_usage(TRUE);
echo " Current Consumption is ";
echo round($cur_mem/1048576,2).''.' MB'.PHP_EOL;
$test('4_large_grouped_00000', 10, 150000, 10000, FALSE);
$cur_mem = memory_get_usage(TRUE);
echo " Current Consumption is ";
echo round($cur_mem/1048576,2).''.' MB'.PHP_EOL;
echo " Peak Consumption is ";
echo round(memory_get_peak_usage(TRUE)/1048576,2).''.' MB'.PHP_EOL;
exit(0);