Files
Chamilo/vendor/sonata-project/exporter/src/Writer/XmlExcelWriter.php
T
Xes 73154ae174
Behat tests 1.11.x 🐞 / PHP 7.4 Test on ubuntu-latest (push) Canceled after 0s
PHP-CS-Fixer / composer_install (7.4) (push) Canceled after 0s
Chamilo 1.11.40 (ZIP oficial v1.11.40)
Fuente: https://github.com/chamilo/chamilo-lms/releases/download/v1.11.40/chamilo-1.11.40.zip
sha256: 1cf4bf2cc7bae1ef1a1eff643235db1d552f78ddf4b6dd1e2d2dac9868679439
Snapshot independiente (rama huerfana); diffable vs 1.11.38. vendor incluido.
2026-08-06 17:59:45 +02:00

143 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
/*
* 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>
*/
final class XmlExcelWriter implements WriterInterface
{
/**
* @var string
*/
private $filename;
/**
* @var resource|null
*/
private $file;
/**
* @var bool
*/
private $showHeaders;
/**
* @var mixed|null
*/
private $columnsType;
/**
* @var int
*/
private $position = 0;
/**
* @var string
*/
private $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>';
private $footer = '</Table></Worksheet></Workbook>';
/**
* @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
*
* @throws \RuntimeException
*/
public function __construct(string $filename, bool $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(): void
{
$this->file = fopen($this->filename, 'w');
fwrite($this->file, $this->header);
}
public function write(array $data): void
{
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(): void
{
fwrite($this->file, $this->footer);
fclose($this->file);
}
/**
* Prepare and return XML string for MS Excel XML from array.
*/
private function getXmlString(array $fields = []): string
{
$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((string) $key, $value);
}
$xmlData[] = '<Cell><Data ss:Type="'.$dataType.'">'.$value.'</Data></Cell>';
}
$xmlData[] = '</Row>';
return implode('', $xmlData);
}
private function getDataType(string $key, string $value): string
{
$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;
}
}