Added support for mergeCells, cell height, shrink to fit
Added support for mergeCells: // mergeCells (B2:G2), you may use CellHelper::getColumnLettersFromColumnIndex() to convert from "B2" to "[1,2]" $writer->mergeCells([1,2], [6, 2]); cell height: $row->setHeight(30); shouldShrinkToFit: $style->setShouldShrinkToFit(); These changes are implemented for XLSX as that's what I need and test spout on.
This commit is contained in:
parent
ab973cab34
commit
488bc371a5
@ -18,6 +18,12 @@ class Row
|
|||||||
*/
|
*/
|
||||||
protected $style;
|
protected $style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Row height (default is 15)
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $height = "15";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Row constructor.
|
* Row constructor.
|
||||||
* @param Cell[] $cells
|
* @param Cell[] $cells
|
||||||
@ -126,4 +132,24 @@ class Row
|
|||||||
return $cell->getValue();
|
return $cell->getValue();
|
||||||
}, $this->cells);
|
}, $this->cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set row height
|
||||||
|
* @param String $height
|
||||||
|
* @return Row
|
||||||
|
*/
|
||||||
|
public function setHeight($height)
|
||||||
|
{
|
||||||
|
$this->height = $height;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns row height
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public function getHeight()
|
||||||
|
{
|
||||||
|
return $this->height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,9 @@ class Style
|
|||||||
/** @var bool Whether the wrap text property was set */
|
/** @var bool Whether the wrap text property was set */
|
||||||
private $hasSetWrapText = false;
|
private $hasSetWrapText = false;
|
||||||
|
|
||||||
|
private $shrinkToFit = false;
|
||||||
|
private $shouldShrinkToFit = false;
|
||||||
|
|
||||||
/** @var Border */
|
/** @var Border */
|
||||||
private $border;
|
private $border;
|
||||||
|
|
||||||
@ -463,4 +466,24 @@ class Style
|
|||||||
{
|
{
|
||||||
return $this->hasSetFormat;
|
return $this->hasSetFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets should shrink to fit
|
||||||
|
* @param bool $shrinkToFit
|
||||||
|
* @return Style
|
||||||
|
*/
|
||||||
|
public function setShouldShrinkToFit($shrinkToFit = true)
|
||||||
|
{
|
||||||
|
$this->shrinkToFit = $shrinkToFit;
|
||||||
|
$this->shouldShrinkToFit = $shrinkToFit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool Whether format should be applied
|
||||||
|
*/
|
||||||
|
public function shouldShrinkToFit()
|
||||||
|
{
|
||||||
|
return $this->shouldShrinkToFit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,21 @@ abstract class OptionsManagerAbstract implements OptionsManagerInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an option to the internal list of options
|
||||||
|
* Used only for mergeCells() for now
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addOption($optionName, $optionValue)
|
||||||
|
{
|
||||||
|
if (\in_array($optionName, $this->supportedOptions)) {
|
||||||
|
if (!isset($this->options[$optionName])) {
|
||||||
|
$this->options[$optionName] = [];
|
||||||
|
}
|
||||||
|
$this->options[$optionName][] = $optionValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $optionName
|
* @param string $optionName
|
||||||
* @return mixed|null The set option or NULL if no option with given name found
|
* @return mixed|null The set option or NULL if no option with given name found
|
||||||
|
@ -183,6 +183,17 @@ class StyleBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set should shrink to fit
|
||||||
|
* @param boolean $shrinkToFit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setShouldShrinkToFit($shrinkToFit = true)
|
||||||
|
{
|
||||||
|
$this->style->setShouldShrinkToFit($shrinkToFit);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configured style. The style is cached and can be reused.
|
* Returns the configured style. The style is cached and can be reused.
|
||||||
*
|
*
|
||||||
|
@ -20,4 +20,10 @@ abstract class Options
|
|||||||
|
|
||||||
// XLSX specific options
|
// XLSX specific options
|
||||||
const SHOULD_USE_INLINE_STRINGS = 'shouldUseInlineStrings';
|
const SHOULD_USE_INLINE_STRINGS = 'shouldUseInlineStrings';
|
||||||
|
|
||||||
|
// XLSX column widths
|
||||||
|
const COLUMN_WIDTHS = 'columnWidths';
|
||||||
|
|
||||||
|
// XLSX merge cells
|
||||||
|
const MERGE_CELLS = 'mergeCells';
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ class Sheet
|
|||||||
/** @var SheetManager Sheet manager */
|
/** @var SheetManager Sheet manager */
|
||||||
private $sheetManager;
|
private $sheetManager;
|
||||||
|
|
||||||
|
/** @var bool Sheet is started */
|
||||||
|
private $isSheetStarted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $sheetIndex Index of the sheet, based on order in the workbook (zero-based)
|
* @param int $sheetIndex Index of the sheet, based on order in the workbook (zero-based)
|
||||||
* @param string $associatedWorkbookId ID of the sheet's associated workbook
|
* @param string $associatedWorkbookId ID of the sheet's associated workbook
|
||||||
@ -108,4 +111,23 @@ class Sheet
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool isSheetStarted Sheet was started
|
||||||
|
*/
|
||||||
|
public function isSheetStarted()
|
||||||
|
{
|
||||||
|
return $this->isSheetStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $isSheetStarted Set if sheet was started
|
||||||
|
* @return Sheet
|
||||||
|
*/
|
||||||
|
public function setIsSheetStarted($isSheetStarted)
|
||||||
|
{
|
||||||
|
$this->isSheetStarted = $isSheetStarted;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,29 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set columns widths as list. If value is null will set column with default width (8.43)
|
||||||
|
* @param array $columnWidths
|
||||||
|
* @return WriterMultiSheetsAbstract
|
||||||
|
*/
|
||||||
|
public function setColumnWidths(array $columnWidths)
|
||||||
|
{
|
||||||
|
$this->optionsManager->setOption(Options::COLUMN_WIDTHS, $columnWidths);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @param array $range
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function mergeCells(array $range1, array $range2)
|
||||||
|
{
|
||||||
|
$this->optionsManager->addOption(Options::MERGE_CELLS, [$range1, $range2]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +39,8 @@ class OptionsManager extends OptionsManagerAbstract
|
|||||||
Options::DEFAULT_ROW_STYLE,
|
Options::DEFAULT_ROW_STYLE,
|
||||||
Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY,
|
Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY,
|
||||||
Options::SHOULD_USE_INLINE_STRINGS,
|
Options::SHOULD_USE_INLINE_STRINGS,
|
||||||
|
Options::COLUMN_WIDTHS,
|
||||||
|
Options::MERGE_CELLS,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,5 +58,7 @@ class OptionsManager extends OptionsManagerAbstract
|
|||||||
$this->setOption(Options::DEFAULT_ROW_STYLE, $defaultRowStyle);
|
$this->setOption(Options::DEFAULT_ROW_STYLE, $defaultRowStyle);
|
||||||
$this->setOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY, true);
|
$this->setOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY, true);
|
||||||
$this->setOption(Options::SHOULD_USE_INLINE_STRINGS, true);
|
$this->setOption(Options::SHOULD_USE_INLINE_STRINGS, true);
|
||||||
|
$this->setOption(Options::COLUMN_WIDTHS, []);
|
||||||
|
$this->setOption(Options::MERGE_CELLS, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,10 @@ EOD;
|
|||||||
if ($style->shouldWrapText()) {
|
if ($style->shouldWrapText()) {
|
||||||
$content .= ' wrapText="1"';
|
$content .= ' wrapText="1"';
|
||||||
}
|
}
|
||||||
|
if ($style->shouldShrinkToFit()) {
|
||||||
|
$content .= ' shrinkToFit="true"';
|
||||||
|
}
|
||||||
|
|
||||||
$content .= '/>';
|
$content .= '/>';
|
||||||
$content .= '</xf>';
|
$content .= '</xf>';
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,6 +37,8 @@ class WorksheetManager implements WorksheetManagerInterface
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
||||||
EOD;
|
EOD;
|
||||||
|
/** @var OptionsManagerInterface */
|
||||||
|
private $optionsManager;
|
||||||
|
|
||||||
/** @var bool Whether inline or shared strings should be used */
|
/** @var bool Whether inline or shared strings should be used */
|
||||||
protected $shouldUseInlineStrings;
|
protected $shouldUseInlineStrings;
|
||||||
@ -84,6 +86,7 @@ EOD;
|
|||||||
StringHelper $stringHelper,
|
StringHelper $stringHelper,
|
||||||
InternalEntityFactory $entityFactory
|
InternalEntityFactory $entityFactory
|
||||||
) {
|
) {
|
||||||
|
$this->optionsManager = $optionsManager;
|
||||||
$this->shouldUseInlineStrings = $optionsManager->getOption(Options::SHOULD_USE_INLINE_STRINGS);
|
$this->shouldUseInlineStrings = $optionsManager->getOption(Options::SHOULD_USE_INLINE_STRINGS);
|
||||||
$this->rowManager = $rowManager;
|
$this->rowManager = $rowManager;
|
||||||
$this->styleManager = $styleManager;
|
$this->styleManager = $styleManager;
|
||||||
@ -113,7 +116,6 @@ EOD;
|
|||||||
$worksheet->setFilePointer($sheetFilePointer);
|
$worksheet->setFilePointer($sheetFilePointer);
|
||||||
|
|
||||||
\fwrite($sheetFilePointer, self::SHEET_XML_FILE_HEADER);
|
\fwrite($sheetFilePointer, self::SHEET_XML_FILE_HEADER);
|
||||||
\fwrite($sheetFilePointer, '<sheetData>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,11 +155,28 @@ EOD;
|
|||||||
*/
|
*/
|
||||||
private function addNonEmptyRow(Worksheet $worksheet, Row $row)
|
private function addNonEmptyRow(Worksheet $worksheet, Row $row)
|
||||||
{
|
{
|
||||||
|
if (!$worksheet->getExternalSheet()->isSheetStarted()) {
|
||||||
|
// create nodes for columns widths
|
||||||
|
if ($this->optionsManager->getOption(Options::COLUMN_WIDTHS)) {
|
||||||
|
$colsString = '<cols>';
|
||||||
|
foreach ($this->optionsManager->getOption(Options::COLUMN_WIDTHS) as $index => $width) {
|
||||||
|
$index++;
|
||||||
|
$colsString.= '<col collapsed="false" customWidth="true" hidden="false" outlineLevel="0" style="0" max="'.$index.'" min="'.$index.'" width="'.$width.'"/>';
|
||||||
|
}
|
||||||
|
$colsString.="</cols>";
|
||||||
|
\fwrite($worksheet->getFilePointer(), $colsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
\fwrite($worksheet->getFilePointer(), '<sheetData>');
|
||||||
|
$worksheet->getExternalSheet()->setIsSheetStarted(true);
|
||||||
|
}
|
||||||
|
|
||||||
$rowStyle = $row->getStyle();
|
$rowStyle = $row->getStyle();
|
||||||
$rowIndexOneBased = $worksheet->getLastWrittenRowIndex() + 1;
|
$rowIndexOneBased = $worksheet->getLastWrittenRowIndex() + 1;
|
||||||
$numCells = $row->getNumCells();
|
$numCells = $row->getNumCells();
|
||||||
|
$rowHeight = $row->getHeight();
|
||||||
|
|
||||||
$rowXML = '<row r="' . $rowIndexOneBased . '" spans="1:' . $numCells . '">';
|
$rowXML = '<row r="' . $rowIndexOneBased . '" spans="1:' . $numCells . '" customHeight="true"' . ' ht="'. $rowHeight . '">';
|
||||||
|
|
||||||
foreach ($row->getCells() as $columnIndexZeroBased => $cell) {
|
foreach ($row->getCells() as $columnIndexZeroBased => $cell) {
|
||||||
$rowXML .= $this->applyStyleAndGetCellXML($cell, $rowStyle, $rowIndexOneBased, $columnIndexZeroBased);
|
$rowXML .= $this->applyStyleAndGetCellXML($cell, $rowStyle, $rowIndexOneBased, $columnIndexZeroBased);
|
||||||
@ -270,7 +289,26 @@ EOD;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$worksheet->getExternalSheet()->isSheetStarted()) {
|
||||||
|
\fwrite($worksheetFilePointer, '<sheetData>');
|
||||||
|
$worksheet->getExternalSheet()->setIsSheetStarted(true);
|
||||||
|
}
|
||||||
|
|
||||||
\fwrite($worksheetFilePointer, '</sheetData>');
|
\fwrite($worksheetFilePointer, '</sheetData>');
|
||||||
|
|
||||||
|
// create nodes for merge cells
|
||||||
|
if ($this->optionsManager->getOption(Options::MERGE_CELLS)) {
|
||||||
|
$mergeCellString = '<mergeCells count="'.count($this->optionsManager->getOption(Options::MERGE_CELLS)).'">';
|
||||||
|
foreach ($this->optionsManager->getOption(Options::MERGE_CELLS) as $values) {
|
||||||
|
$output = array_map(function($value){
|
||||||
|
return CellHelper::getColumnLettersFromColumnIndex($value[0]) . $value[1];
|
||||||
|
}, $values);
|
||||||
|
$mergeCellString.= '<mergeCell ref="'.implode(':', $output).'"/>';
|
||||||
|
}
|
||||||
|
$mergeCellString.= '</mergeCells>';
|
||||||
|
\fwrite($worksheet->getFilePointer(), $mergeCellString);
|
||||||
|
}
|
||||||
|
|
||||||
\fwrite($worksheetFilePointer, '</worksheet>');
|
\fwrite($worksheetFilePointer, '</worksheet>');
|
||||||
\fclose($worksheetFilePointer);
|
\fclose($worksheetFilePointer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user