Files
Chamilo/vendor/sonata-project/exporter/src/Writer/XmlExcelWriter.php
2025-08-14 22:41:49 +02:00

156 lines
4.6 KiB
PHP

<?php
/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sonata\Exporter\Writer;
/**
* Generate a Xml Excel file.
*
* @author Vincent Touzet <vincent.touzet@gmail.com>
*/
class XmlExcelWriter implements WriterInterface
{
/**
* @var string|null
*/
protected $filename = null;
/**
* @var resource|null
*/
protected $file = null;
/**
* @var bool
*/
protected $showHeaders;
/**
* @var mixed|null
*/
protected $columnsType = null;
/**
* @var int
*/
protected $position = 0;
/**
* @var string
*/
protected $header = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet"><OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"></OfficeDocumentSettings><ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"></ExcelWorkbook><Worksheet ss:Name="Sheet 1"><Table>';
protected $footer = '</Table></Worksheet></Workbook>';
/**
* @param string $filename
* @param bool $showHeaders
* @param mixed $columnsType Define cells type to use
* If string: force all cells to the given type. e.g: 'Number'
* If array: force only given cells. e.g: array('ean'=>'String', 'price'=>'Number')
* If null: will guess the type. 'Number' if value is numeric, 'String' otherwise
*/
public function __construct($filename, $showHeaders = true, $columnsType = null)
{
$this->filename = $filename;
$this->showHeaders = $showHeaders;
$this->columnsType = $columnsType;
if (is_file($filename)) {
throw new \RuntimeException(sprintf('The file %s already exist', $filename));
}
}
public function open()
{
$this->file = fopen($this->filename, 'w');
fwrite($this->file, $this->header);
}
/**
* @param array $data
*/
public function write(array $data)
{
if (0 == $this->position && $this->showHeaders) {
$header = array_keys($data);
fwrite($this->file, $this->getXmlString($header));
++$this->position;
}
fwrite($this->file, $this->getXmlString($data));
++$this->position;
}
public function close()
{
fwrite($this->file, $this->footer);
fclose($this->file);
}
/**
* Prepare and return XML string for MS Excel XML from array.
*
* @param array $fields
*
* @return string
*/
private function getXmlString(array $fields = [])
{
$xmlData = [];
$xmlData[] = '<Row>';
foreach ($fields as $key => $value) {
$value = htmlspecialchars($value);
$value = str_replace(["\r\n", "\r", "\n"], '&#10;', $value);
$dataType = 'String';
if (0 != $this->position || !$this->showHeaders) {
$dataType = $this->getDataType($key, $value);
}
$xmlData[] = '<Cell><Data ss:Type="'.$dataType.'">'.$value.'</Data></Cell>';
}
$xmlData[] = '</Row>';
return implode('', $xmlData);
}
/**
* @param string $key
* @param string $value
*
* @return string
*/
private function getDataType($key, $value)
{
$dataType = null;
if (null !== $this->columnsType) {
if (\is_string($this->columnsType)) {
$dataType = $this->columnsType;
} elseif (\is_array($this->columnsType)) {
if (\array_key_exists($key, $this->columnsType)) {
$dataType = $this->columnsType[$key];
}
}
}
if (null === $dataType) {
// guess the type
if (is_numeric($value)) {
$dataType = 'Number';
} else {
$dataType = 'String';
}
}
return $dataType;
}
}
class_exists(\Exporter\Writer\XmlExcelWriter::class);