/** * Adds data to the worksheet. * * @param array $dataRow Array containing data to be written. Cannot be empty. * Example $dataRow = ['data1', 1234, null, '', 'data5']; * @param \Box\Spout\Writer\Style\Style $style Style to be applied to the row. NULL means use default style. * @return void * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported */ public function addRow($dataRow, $style) { $cellNumber = 0; $rowIndex = $this->lastWrittenRowIndex + 1; $numCells = count($dataRow); $rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">'; foreach ($dataRow as $cellValue) { $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $cellXML = '<c r="' . $columnIndex . $rowIndex . '"'; $cellXML .= ' s="' . $style->getId() . '"'; if (CellHelper::isNonEmptyString($cellValue)) { // CFDB EDIT BEGIN: Special case added to handle HYPERLINK functions // this IF wrapping exiting code in ELSE $matches = array(); if (preg_match('/=HYPERLINK\\("(.*)","(.*)"\\)/', $cellValue, $matches)) { // Create a Formula $url = $this->stringsEscaper->escape($matches[1]); $text = $this->stringsEscaper->escape($matches[2]); $formula = sprintf('HYPERLINK("%s","%s")', $url, $text); $cellXML = sprintf('<c r="%s%s" t="str"><f>%s</f><v>%s</v></c>', $columnIndex, $rowIndex, $formula, $text); } else { // CFDB EDIT END if ($this->shouldUseInlineStrings) { $cellXML .= ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>'; } else { $sharedStringId = $this->sharedStringsHelper->writeString($cellValue); $cellXML .= ' t="s"><v>' . $sharedStringId . '</v></c>'; } } // CFDB EDIT this line } else { if (CellHelper::isBoolean($cellValue)) { $cellXML .= ' t="b"><v>' . $cellValue . '</v></c>'; } else { if (CellHelper::isNumeric($cellValue)) { $cellXML .= '><v>' . $cellValue . '</v></c>'; } else { if (empty($cellValue)) { // don't write empty cells (not appending to $cellXML is the right behavior!) $cellXML = ''; } else { throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cellValue)); } } } } $rowXML .= $cellXML; $cellNumber++; } $rowXML .= '</row>'; $wasWriteSuccessful = fwrite($this->sheetFilePointer, $rowXML); if ($wasWriteSuccessful === false) { throw new IOException("Unable to write data in {$this->worksheetFilePath}"); } // only update the count if the write worked $this->lastWrittenRowIndex++; }
/** * Returns the cell XML content, given its value. * * @param mixed $cellValue The value to be written * @param int $styleIndex Index of the used style * @param int $numTimesValueRepeated Number of times the value is consecutively repeated * @return string The cell XML content * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported */ protected function getCellContent($cellValue, $styleIndex, $numTimesValueRepeated) { $data = '<table:table-cell table:style-name="ce' . $styleIndex . '"'; if ($numTimesValueRepeated !== 1) { $data .= ' table:number-columns-repeated="' . $numTimesValueRepeated . '"'; } if (CellHelper::isNonEmptyString($cellValue)) { $data .= ' office:value-type="string" calcext:value-type="string">'; $cellValueLines = explode("\n", $cellValue); foreach ($cellValueLines as $cellValueLine) { $data .= '<text:p>' . $this->stringsEscaper->escape($cellValueLine) . '</text:p>'; } $data .= '</table:table-cell>'; } else { if (CellHelper::isBoolean($cellValue)) { $data .= ' office:value-type="boolean" calcext:value-type="boolean" office:boolean-value="' . $cellValue . '">'; $data .= '<text:p>' . $cellValue . '</text:p>'; $data .= '</table:table-cell>'; } else { if (CellHelper::isNumeric($cellValue)) { $data .= ' office:value-type="float" calcext:value-type="float" office:value="' . $cellValue . '">'; $data .= '<text:p>' . $cellValue . '</text:p>'; $data .= '</table:table-cell>'; } else { if (empty($cellValue)) { $data .= '/>'; } else { throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cellValue)); } } } } return $data; }
/** * Build and return xml for a single cell. * * @param int $rowIndex * @param int $cellNumber * @param mixed $cellValue * @param int $styleId * @return string * @throws InvalidArgumentException */ private function getCellXML($rowIndex, $cellNumber, $cellValue, $styleId) { $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $cellXML = '<c r="' . $columnIndex . $rowIndex . '"'; $cellXML .= ' s="' . $styleId . '"'; if (CellHelper::isNonEmptyString($cellValue)) { if ($this->shouldUseInlineStrings) { $cellXML .= ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>'; } else { $sharedStringId = $this->sharedStringsHelper->writeString($cellValue); $cellXML .= ' t="s"><v>' . $sharedStringId . '</v></c>'; } } else { if (CellHelper::isBoolean($cellValue)) { $cellXML .= ' t="b"><v>' . intval($cellValue) . '</v></c>'; } else { if (CellHelper::isNumeric($cellValue)) { $cellXML .= '><v>' . $cellValue . '</v></c>'; } else { if (empty($cellValue)) { if ($this->styleHelper->shouldApplyStyleOnEmptyCell($styleId)) { $cellXML .= '/>'; } else { // don't write empty cells that do no need styling // NOTE: not appending to $cellXML is the right behavior!! $cellXML = ''; } } else { throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cellValue)); } } } } return $cellXML; }
/** * Adds data to the worksheet. * * @param array $dataRow Array containing data to be written. Cannot be empty. * Example $dataRow = ['data1', 1234, null, '', 'data5']; * @param \Box\Spout\Writer\Style\Style $style Style to be applied to the row. NULL means use default style. * @return void * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported */ public function addRow($dataRow, $style) { $cellNumber = 0; $rowIndex = $this->lastWrittenRowIndex + 1; $numCells = count($dataRow); $rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">'; foreach ($dataRow as $cellValue) { $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $cellXML = '<c r="' . $columnIndex . $rowIndex . '"'; $cellXML .= ' s="' . $style->getId() . '"'; if (CellHelper::isNonEmptyString($cellValue)) { if ($this->shouldUseInlineStrings) { $cellXML .= ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>'; } else { $sharedStringId = $this->sharedStringsHelper->writeString($cellValue); $cellXML .= ' t="s"><v>' . $sharedStringId . '</v></c>'; } } else { if (CellHelper::isBoolean($cellValue)) { $cellXML .= ' t="b"><v>' . intval($cellValue) . '</v></c>'; } else { if (CellHelper::isNumeric($cellValue)) { $cellXML .= '><v>' . $cellValue . '</v></c>'; } else { if (empty($cellValue)) { // don't write empty cells (not appending to $cellXML is the right behavior!) $cellXML = ''; } else { throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cellValue)); } } } } $rowXML .= $cellXML; $cellNumber++; } $rowXML .= '</row>'; $wasWriteSuccessful = fwrite($this->sheetFilePointer, $rowXML); if ($wasWriteSuccessful === false) { throw new IOException("Unable to write data in {$this->worksheetFilePath}"); } // only update the count if the write worked $this->lastWrittenRowIndex++; }
/** * Build and return xml for a single cell. * * @param int $rowIndex * @param int $cellNumber * @param mixed $cellValue * @param int $styleId * @return string * @throws InvalidArgumentException */ private function getCellXML($rowIndex, $cellNumber, $cellValue, $styleId) { $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $cellXML = '<c r="' . $columnIndex . $rowIndex . '"'; $cellXML .= ' s="' . $styleId . '"'; if (CellHelper::isNonEmptyString($cellValue)) { // CFDB EDIT BEGIN: Special case added to handle HYPERLINK functions // this IF wrapping exiting code in ELSE $matches = array(); if (preg_match('/=HYPERLINK\\("(.*)","(.*)"\\)/', $cellValue, $matches)) { // Create a Formula $url = $this->stringsEscaper->escape($matches[1]); $text = $this->stringsEscaper->escape($matches[2]); $formula = sprintf('HYPERLINK("%s","%s")', $url, $text); $cellXML = sprintf('<c r="%s%s" t="str"><f>%s</f><v>%s</v></c>', $columnIndex, $rowIndex, $formula, $text); } else { // CFDB EDIT END if ($this->shouldUseInlineStrings) { $cellXML .= ' t="inlineStr"><is><t>' . $this->stringsEscaper->escape($cellValue) . '</t></is></c>'; } else { $sharedStringId = $this->sharedStringsHelper->writeString($cellValue); $cellXML .= ' t="s"><v>' . $sharedStringId . '</v></c>'; } } // CFDB EDIT this line } else { if (CellHelper::isBoolean($cellValue)) { $cellXML .= ' t="b"><v>' . intval($cellValue) . '</v></c>'; } else { if (CellHelper::isNumeric($cellValue)) { $cellXML .= '><v>' . $cellValue . '</v></c>'; } else { if (empty($cellValue)) { if ($this->styleHelper->shouldApplyStyleOnEmptyCell($styleId)) { $cellXML .= '/>'; } else { // don't write empty cells that do no need styling // NOTE: not appending to $cellXML is the right behavior!! $cellXML = ''; } } else { throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cellValue)); } } } } return $cellXML; }