Merge 73df02f8c0989f8c7f7516e85473ae0d5e8205f2 into 1891c0b053d43597aaa4c1d7152e5c7f0b52ce91
This commit is contained in:
commit
24de1772cb
0
src/Spout/Writer/AbstractWriter.php
Normal file → Executable file
0
src/Spout/Writer/AbstractWriter.php
Normal file → Executable 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.
|
||||
*
|
||||
|
@ -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
73
src/Spout/Writer/Style/Style.php
Normal file → Executable 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
16
src/Spout/Writer/Style/StyleBuilder.php
Normal file → Executable 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
47
src/Spout/Writer/XLSX/Helper/StyleHelper.php
Normal file → Executable 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 .= '/>';
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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) {
|
||||
|
@ -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
113
test.php
Normal 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);
|
Loading…
x
Reference in New Issue
Block a user