Skip to content

Commit

Permalink
fix #37
Browse files Browse the repository at this point in the history
  • Loading branch information
aVadim483 committed Oct 4, 2023
1 parent 0b991ed commit 5c774d6
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 81 deletions.
176 changes: 107 additions & 69 deletions src/FastExcelWriter/Sheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Sheet
public array $colFormulas = [];
public array $colStyles = [];

protected array $colSettings = [];
protected array $colAttributes = [];

// minimal with of columns
protected array $colMinWidths = [];
Expand Down Expand Up @@ -691,7 +691,7 @@ public function setColVisible($col, bool $val): Sheet
$colIndexes = Excel::colIndexRange($col);
foreach($colIndexes as $colIdx) {
if ($colIdx >= 0) {
$this->colSettings[$colIdx]['hidden'] = (int)$val;
$this->colAttributes[$colIdx]['hidden'] = (int)$val;
}
}

Expand Down Expand Up @@ -731,12 +731,12 @@ public function setColWidth($col, $width, ?bool $min = false): Sheet
if (is_numeric($width)) {
if ($min) {
$this->colMinWidths[$colIdx] = $width;
if (!isset($this->colSettings[$colIdx]['width']) || $this->colSettings[$colIdx]['width'] < $width) {
$this->colSettings[$colIdx]['width'] = $width;
if (!isset($this->colAttributes[$colIdx]['width']) || $this->colAttributes[$colIdx]['width'] < $width) {
$this->colAttributes[$colIdx]['width'] = $width;
}
}
elseif (empty($this->colMinWidths[$colIdx]) || $this->colMinWidths[$colIdx] <= $width) {
$this->colSettings[$colIdx]['width'] = $width;
$this->colAttributes[$colIdx]['width'] = $width;
}
}
}
Expand Down Expand Up @@ -819,20 +819,23 @@ public function setColMinWidths(array $widths): Sheet
/**
* @return array
*/
public function getColSettings(): array
public function getColAttributes(): array
{
$result = [];
if ($this->colSettings) {
foreach ($this->colSettings as $colIdx => $settings) {
$result[$colIdx] = [
'min' => $colIdx + 1,
'max' => $colIdx + 1,
];
if (isset($settings['width'])) {
$result[$colIdx]['width'] = number_format($settings['width'], 6, '.', '');
if ($this->colAttributes) {
foreach ($this->colAttributes as $colIdx => $attributes) {
$result[$colIdx] = $attributes;
if (!isset($attributes)) {
$result[$colIdx]['min'] = $colIdx + 1;
}
if (!isset($attributes)) {
$result[$colIdx]['max'] = $colIdx + 1;
}
if (isset($attributes['width'])) {
$result[$colIdx]['width'] = number_format($attributes['width'], 6, '.', '');
$result[$colIdx]['customWidth'] = '1';
}
if (isset($settings['hidden'])) {
if (isset($attributes['hidden'])) {
$result[$colIdx]['hidden'] = '1';
}
}
Expand All @@ -842,6 +845,17 @@ public function getColSettings(): array
return $result;
}

/**
* @param int $colIdx
* @param array $settings
*
* @return void
*/
public function _setColAttributes(int $colIdx, array $settings)
{
$this->colAttributes[$colIdx] = $settings;
}

/**
* Set style of single or multiple column(s)
*
Expand Down Expand Up @@ -1217,67 +1231,74 @@ protected function _writeRow(?Writer $writer, array $row = [], array $rowOptions
$styleStack = [$baseStyle];
}

if (!empty($this->rowStyles[$rowIdx])) {
$styleStack[] = $this->rowStyles[$rowIdx];
}
if (!empty($this->cells['styles'][$rowIdx][$colIdx])) {
$styleStack[] = $this->cells['styles'][$rowIdx][$colIdx];
}
if ($rowOptions) {
$styleStack[] = $rowOptions;
}
if (!empty($cellsOptions[$colIdx])) {
$styleStack[] = $cellsOptions[$colIdx];
}
if (count($styleStack) > 1) {
$cellStyle = Style::mergeStyles($styleStack);
if (isset($cellsOptions[$colIdx]['_xf_id'])) {
$cellStyleIdx = $cellsOptions[$colIdx]['_xf_id'];
$numberFormatType = 'n_auto';
}
else {
$cellStyle = $styleStack ? $styleStack[0] : [];
}
if (!empty($cellStyle['format']['format-pattern']) && !empty($this->excel->style->defaultFormatStyles[$cellStyle['format']['format-pattern']])) {
$cellStyle = Style::mergeStyles([$this->excel->style->defaultFormatStyles[$cellStyle['format']['format-pattern']], $cellStyle]);
}
// Define cell style index and number format
if (!empty($this->rowStyles[$rowIdx])) {
$styleStack[] = $this->rowStyles[$rowIdx];
}
if (!empty($this->cells['styles'][$rowIdx][$colIdx])) {
$styleStack[] = $this->cells['styles'][$rowIdx][$colIdx];
}
if ($rowOptions) {
$styleStack[] = $rowOptions;
}
if (!empty($cellsOptions[$colIdx])) {
$styleStack[] = $cellsOptions[$colIdx];
}
if (count($styleStack) > 1) {
$cellStyle = Style::mergeStyles($styleStack);
}
else {
$cellStyle = $styleStack ? $styleStack[0] : [];
}
if (!empty($cellStyle['format']['format-pattern']) && !empty($this->excel->style->defaultFormatStyles[$cellStyle['format']['format-pattern']])) {
$cellStyle = Style::mergeStyles([$this->excel->style->defaultFormatStyles[$cellStyle['format']['format-pattern']], $cellStyle]);
}

if (isset($cellStyle['hyperlink'])) {
if (!empty($cellStyle['hyperlink'])) {
if (is_string($cellStyle['hyperlink'])) {
$link = $cellStyle['hyperlink'];
}
else {
$link = $cellValue;
}
$cellValue = [
'shared_value' => $cellValue,
'shared_index' => $this->excel->addSharedString($cellValue),
];
$this->_addExternalLink(Excel::cellAddress($rowIdx + 1, $colIdx + 1), $link);
if (!empty($this->excel->style->hyperlinkStyle)) {
$cellStyle = Style::mergeStyles([$this->excel->style->hyperlinkStyle, $cellStyle]);
if (isset($cellStyle['hyperlink'])) {
if (!empty($cellStyle['hyperlink'])) {
if (is_string($cellStyle['hyperlink'])) {
$link = $cellStyle['hyperlink'];
}
else {
$link = $cellValue;
}
$cellValue = [
'shared_value' => $cellValue,
'shared_index' => $this->excel->addSharedString($cellValue),
];
$this->_addExternalLink(Excel::cellAddress($rowIdx + 1, $colIdx + 1), $link);
if (!empty($this->excel->style->hyperlinkStyle)) {
$cellStyle = Style::mergeStyles([$this->excel->style->hyperlinkStyle, $cellStyle]);
}
}
unset($cellStyle['hyperlink']);
}
unset($cellStyle['hyperlink']);
}

$styleHash = json_encode($cellStyle);
if (!isset($_styleCache[$styleHash])) {
$cellStyleIdx = $this->excel->style->addStyle($cellStyle, $resultStyle);
$_styleCache[$styleHash] = ['cell_style' => $cellStyle, 'result_style' => $resultStyle, 'style_idx' => $cellStyleIdx];
}
else {
$resultStyle = $_styleCache[$styleHash]['result_style'];
$cellStyleIdx = $_styleCache[$styleHash]['style_idx'];
}
$styleHash = json_encode($cellStyle);
if (!isset($_styleCache[$styleHash])) {
$cellStyleIdx = $this->excel->style->addStyle($cellStyle, $resultStyle);
$_styleCache[$styleHash] = ['cell_style' => $cellStyle, 'result_style' => $resultStyle, 'style_idx' => $cellStyleIdx];
}
else {
$resultStyle = $_styleCache[$styleHash]['result_style'];
$cellStyleIdx = $_styleCache[$styleHash]['style_idx'];
}

$numberFormat = $resultStyle['number_format'];
$numberFormatType = $resultStyle['number_format_type'];
$numberFormat = $resultStyle['number_format'];
$numberFormatType = $resultStyle['number_format_type'];

if (!empty($cellStyle['options']['width-auto'])) {
$this->_columnWidth($colIdx, $cellValue, $numberFormat, $resultStyle ?? []);
}
if (!empty($cellStyle['options']['width-auto'])) {
$this->_columnWidth($colIdx, $cellValue, $numberFormat, $resultStyle ?? []);
}

if (!$writer) {
$writer = $this->excel->getWriter();
if (!$writer) {
$writer = $this->excel->getWriter();
}
}
if ($cellValue !== null || $cellStyleIdx !== 0 || $numberFormatType !== 'n_auto') {
$writer->_writeCell($this->fileWriter, $rowIdx + 1, $colIdx + 1, $cellValue, $numberFormatType, $cellStyleIdx);
Expand Down Expand Up @@ -1415,8 +1436,8 @@ protected function _columnWidth(int $colIdx, $cellValue, $numberFormat, $style)
}
$cache[$key] = $len;
}
if ((empty($this->colSettings[$colIdx]['width']) || $this->colSettings[$colIdx]['width'] < $len) && (empty($this->colMinWidths[$colIdx]) || $this->colMinWidths[$colIdx] <= $len)) {
$this->colSettings[$colIdx]['width'] = $len;
if ((empty($this->colAttributes[$colIdx]['width']) || $this->colAttributes[$colIdx]['width'] < $len) && (empty($this->colMinWidths[$colIdx]) || $this->colMinWidths[$colIdx] <= $len)) {
$this->colAttributes[$colIdx]['width'] = $len;
}
}
}
Expand Down Expand Up @@ -2313,6 +2334,23 @@ public function setCellStyle(string $cellAddress, $style, ?bool $mergeStyles = f
return $this->setStyle($cellAddress, $style, $mergeStyles);
}

/**
* @param string $cellAddress
* @param int $styleIdx
*
* @return $this
*/
public function _setStyleIdx(string $cellAddress, int $styleIdx): Sheet
{
$dimension = $this->_rangeDimension($cellAddress);
if ($dimension['rowNum1'] <= $this->rowCountWritten) {
throw new Exception('Row number must be greater then written rows');
}
$this->cells['styles'][$dimension['rowIndex']][$dimension['colIndex']]['_xf_id'] = $styleIdx;

return $this;
}

/**
* @param string $cellAddr
* @param array $style
Expand Down
44 changes: 32 additions & 12 deletions src/FastExcelWriter/Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ public function saveToFile(string $fileName, ?bool $overWrite = true, ?array $me
'rel_id' => ['workbook' => 0],
];

$sheets = $this->excel->getSheets();//$this->writeSheetDataBegin($sheet);
$sheets = $this->excel->getSheets();
if (empty($sheets)) {
ExceptionFile::throwNew('No worksheets defined');
}
Expand Down Expand Up @@ -400,19 +400,39 @@ public function saveToFile(string $fileName, ?bool $overWrite = true, ?array $me
$this->writeEntriesToZip('xl/');
$this->writeEntriesToZip('');

/*
if (!$zip->addFile($this->tempFiles[$entry], $entry)) {
ExceptionFile::throwNew('Could not write entry "%s" to zip', $entry);
$this->zip->close();

return true;
}

public function _replaceSheets($inputFile, $outputFile): bool
{
if (!copy($inputFile, $outputFile)) {
ExceptionFile::throwNew('Cannot to write file "%s"', $outputFile);
}
if (isset($struct['-'])) {
foreach ($struct['-'] as $entry) {
if (!$zip->addFile($this->tempFiles[$entry], $entry)) {
ExceptionFile::throwNew('Could not write entry "%s" to zip', $entry);

$this->zip = new \ZipArchive();
if (!$this->zip->open($outputFile)) {
ExceptionFile::throwNew('Unable to open zip "%s"', $outputFile);
}
$entryList = [];
for ($i = 0; $i < $this->zip->numFiles; $i++) {
$entryList[$i] = $this->zip->getNameIndex($i);
}
$sheets = $this->excel->getSheets();
$relationShips = [];
$this->_writeSheetsFiles($sheets, $relationShips);
foreach ($entryList as $index => $name) {
if (strpos($name, 'xl/worksheets/sheet') === 0 && !empty($this->tempFiles['zip'][$name])) {
if (version_compare(PHP_VERSION, '8.3.0') >= 0) {
$this->zip->replaceFile($this->tempFiles['zip'][$name], $index);
}
else {
$this->zip->addFile($this->tempFiles['zip'][$name], $name);
}
}
unset($struct['-']);
}
*/

$this->zip->close();

return true;
Expand Down Expand Up @@ -795,7 +815,7 @@ protected function _writeSheetHead(Sheet $sheet): WriterBuffer

$fileWriter->write('</sheetViews>');

$cols = $sheet->getColSettings();
$cols = $sheet->getColAttributes();
if ($cols) {
$fileWriter->write('<cols>');
foreach ($cols as $colSettings) {
Expand Down Expand Up @@ -969,7 +989,7 @@ protected function _convertFormula($formula, $baseAddress): string
$formula = (string) preg_replace(self::XLWSREGEXP, '_xlws.$1(', $formula);
}

return $formula;
return ($formula[0] === '=') ? mb_substr($formula, 1) : $formula;
}

/**
Expand Down

0 comments on commit 5c774d6

Please sign in to comment.