_iterator = $iterator; $this->_rowCallback = $rowCallback; } /** * Retrieve Excel XML Document Header XML Fragment * Append data header if it is available * * @param string $sheetName * @return string */ protected function _getXmlHeader($sheetName = '') { if (empty($sheetName)) { $sheetName = 'Sheet 1'; } $sheetName = htmlspecialchars($sheetName); $xmlHeader = '<' . '?xml version="1.0"?' . '><' . '?mso-application progid="Excel.Sheet"?' . '>' . '' . '' . '' . '' . '' . ''; if ($this->_dataHeader) { $xmlHeader .= $this->_getXmlRow($this->_dataHeader, false); } return $xmlHeader; } /** * Retrieve Excel XML Document Footer XML Fragment * Append data footer if it is available * * @return string */ protected function _getXmlFooter() { $xmlFooter = ''; if ($this->_dataFooter) { $xmlFooter = $this->_getXmlRow($this->_dataFooter, false); } $xmlFooter .= '
'; return $xmlFooter; } /** * Get a Single XML Row * * @param array $row * @param boolean $useCallback * @return string * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _getXmlRow($row, $useCallback) { if ($useCallback && $this->_rowCallback) { $row = call_user_func($this->_rowCallback, $row); } $xmlData = []; $xmlData[] = ''; foreach ($row as $value) { $value = htmlspecialchars($value); $dataType = is_numeric($value) && $value[0] !== '+' && $value[0] !== '0' ? 'Number' : 'String'; /** * Security enhancement for CSV data processing by Excel-like applications. * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1054702 * * @var $value string|\Magento\Framework\Phrase */ if (!is_string($value)) { $value = (string)$value; } if (isset($value[0]) && in_array($value[0], ['=', '+', '-'])) { $value = ' ' . $value; } $value = str_replace("\r\n", ' ', $value); $value = str_replace("\r", ' ', $value); $value = str_replace("\n", ' ', $value); $xmlData[] = '' . $value . ''; } $xmlData[] = ''; return join('', $xmlData); } /** * Set Data Header * * @param array $data * @return void */ public function setDataHeader($data) { $this->_dataHeader = $data; } /** * Set Data Footer * * @param array $data * @return void */ public function setDataFooter($data) { $this->_dataFooter = $data; } /** * Convert Data to Excel XML Document * * @param string $sheetName * @return string */ public function convert($sheetName = '') { $xml = $this->_getXmlHeader($sheetName); foreach ($this->_iterator as $dataRow) { $xml .= $this->_getXmlRow($dataRow, true); } $xml .= $this->_getXmlFooter(); return $xml; } /** * Write Converted XML Data to Temporary File * * @param WriteInterface $stream * @param string $sheetName * @return void */ public function write(WriteInterface $stream, $sheetName = '') { $stream->write($this->_getXmlHeader($sheetName)); foreach ($this->_iterator as $dataRow) { $stream->write($this->_getXmlRow($dataRow, true)); } $stream->write($this->_getXmlFooter()); } }