and the ExportExcel.view.php
<?php
use koolreport\excel\PieChart;
use koolreport\excel\Table;
use koolreport\excel\BarChart;
use koolreport\excel\AreaChart;
use koolreport\excel\LineChart;
use koolreport\excel\DonutChart;
//dump($this->page, $this->right, $this->colorScheme, $this->format, $this->currency, $this->elements);exit;
$page = $this->document;
$elements = $this->elements;
foreach ($elements as $key => $value) {
if($value['type'] == 'VisualQuery'){
unset($elements[$key]);
}
if($value['type'] == 'data_tables'){
if(array_key_exists('paging', $value['params']['options'])){
unset($elements[$key]['params']['options']['paging']);
}
}
}
$styleArray = [
'font' => [
'name' => 'Calibri', //'Verdana', 'Arial'
'size' => 30,
'bold' => false,
'italic' => FALSE,
'underline' => 'none', //'double', 'doubleAccounting', 'single', 'singleAccounting'
'strikethrough' => FALSE,
'superscript' => false,
'subscript' => false,
'color' => [
'rgb' => '000000',
'argb' => 'FF000000',
]
],
'alignment' => [
'horizontal' => 'general',//left, right, center, centerContinuous, justify, fill, distributed
'vertical' => 'bottom',//top, center, justify, distributed
'textRotation' => 0,
'wrapText' => false,
'shrinkToFit' => false,
'indent' => 0,
'readOrder' => 0,
],
'borders' => [
'top' => [
'borderStyle' => 'none', //dashDot, dashDotDot, dashed, dotted, double, hair, medium, mediumDashDot, mediumDashDotDot, mediumDashed, slantDashDot, thick, thin
'color' => [
'rgb' => '808080',
'argb' => 'FF808080',
]
],
//left, right, bottom, diagonal, allBorders, outline, inside, vertical, horizontal
],
'fill' => [
'fillType' => 'none', //'solid', 'linear', 'path', 'darkDown', 'darkGray', 'darkGrid', 'darkHorizontal', 'darkTrellis', 'darkUp', 'darkVertical', 'gray0625', 'gray125', 'lightDown', 'lightGray', 'lightGrid', 'lightHorizontal', 'lightTrellis', 'lightUp', 'lightVertical', 'mediumGray'
'rotation' => 90,
'color' => [
'rgb' => '000000',
'argb' => 'FF000000',
],
'startColor' => [
'rgb' => '000000',
'argb' => 'FF000000',
],
'endColor' => [
'argb' => 'FFFFFF',
'argb' => 'FFFFFFFF',
],
],
];
//Tableau contenant les lettres de l'alphabet pour définir les cellules des éléments
$letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
?>
<!-- Boucle sur l'objet page pour créer et positionner les objets-->
<?php foreach($page['pages'] as $pageId => $pageContent): ?>
<!-- Défini un sheet et son nom -->
<div sheet-name="Page <?= $pageId + 1?>">
<!-- Défini les élément composant les cellules de début et de fin (lettre + nombre)-->
<?php $startRangeLetter = 'A'; $startRangeIndex = 1; $endRangeLetter = ''; $endRangeIndex = 1?>
<!-- Boucle sur les lignes de la page-->
<?php foreach($pageContent['body']['element'] as $rowId => $rowContent): ?>
<!-- Boucle sur les colonnes d'une ligne -->
<?php foreach($rowContent['element'] as $colId => $colContent): ?>
<?php foreach($colContent['element'] as $subRowId => $subRowContent): ?>
<?php
//défini les variables de dimension pour calculer la plage de chaque élément
// 80 et 20 son les dimensions par défaut d'une céllule excel
$tempWidth = (int) round($colContent['style']['width'] / 80);
$tempHeight = (int) round($subRowContent['style']['height'] / 21);
//on assigne $letters à $tempLetters car dans le cas ou il y a plusieurs élément sur une même ligne il faut modifier le tableau
$tempLetters = $letters;
//$count correspond à l'index de la lettre à utiliser en cas de cellule à plus d'une lettre
//exemple : AA
$count = 0;
$firstLoop = true;
foreach($elements as $key => $elementParams){
if($elementParams['id'] == $subRowContent['element']){
$element = $elementParams;
}
}
//Si l'élément est un tableau, on récupère le nombre de lignes du tableau plutot que ça dimension
if($element['type'] == 'data_tables'){
//on ajoute deux au nombre de ligne pour faire commencer l'élément suivant à la fin du tableau
//car la première ligne de la feuille excel est occuppé par les labels et il faut faire commencer une ligne après la fin
$endRangeIndex = $this->dataStore(strval($element['datastore']['id']))->count() + 2;
}else{
//récupère l'index pour la cellule de fin en fonction de la taille de l'élément
$endRangeIndex = ($startRangeIndex - 1) + $tempHeight;
}
//si il y a plusieurs éléments sur une ligne
if($colId != 0){
//si la cellule est composé de plus d'une lettre (AA)
if(strlen($startRangeLetter) > 1){
//récupère le dernier charactère de la string
$lastChar = substr($startRangeLetter, -1);
//on "coupe" $tempLetters pour le faire commencer à la lettre de la cellule de fin de l'élément précédent
$tempLetters = array_slice($tempLetters, array_search($lastChar, $tempLetters));
//récupère l'index de la première lettre de la cellule
$count = array_search(substr($startRangeLetter, 0, 1), $letters);
//permet de ne pas passer dans la condition du premier tour de boucle
$firstLoop = false;
}else{
//on "coupe" $tempLetters pour le faire commencer à la lettre de la cellule de fin de l'élément précédent
$tempLetters = array_slice($tempLetters, array_search($startRangeLetter, $tempLetters));
}
}
//donne à $endRangeLetter la valeur de la lettre de la céllule de fin en fonction de la largeur calculé de l'élément
for($i = 0; $i <= $tempWidth; $i++){
//si $i - le nombre total de lettre vaut 0
if($i - (count($tempLetters)) == 0){
//si c'est le premier tour de boucle
if($firstLoop == true){
$firstLoop = false;
}else{
$count += 1;
}
}
//si i = un index présent dans le tableau (de 0 à 25)
if($i <= count($tempLetters) - 1){
//si une première lettre est déja présente
if($firstLoop == false){
$endRangeLetter = $letters[$count].$letters[$i];
}else{
//$endRangeLetter prend la valeur de la lettre correspondante
$endRangeLetter = $tempLetters[$i];
}
}else{
//$endRangeLetter prend la valeur de la lettre correspondant à l'index de count + la lettre correspondant à l'index de $i
$endRangeLetter = $letters[$count].$letters[abs($i - count($tempLetters))];
}
}
?>
<!-- Si l'élément à rendre est un tableau alors on lui indique seulement ça cellule de départ -->
<?php if($element['type'] == 'data_tables'):?>
<div cell='<?=$startRangeLetter.$startRangeIndex?>'>
<?php else:?>
<!-- Sinon on indique une plage (cellule du haut à gauche : cellule du bas à droite) -->
<div range='<?=$startRangeLetter.$startRangeIndex?>:<?=$endRangeLetter.$endRangeIndex?>'>
<?php endif?>
<?php
//correspond à lélement à rendre pour la colonne
// $element = $elements[$colContent['id_element']];
//tableau au bon format pour être interprété par la fonction create
$params = [
"dataSource"=>$this->dataStore(strval($element['datastore']['id'])),
// "colorScheme"=>$this->colorScheme['colorScheme'],
"excelStyle" => $styleArray
];
//récupère les params de l'élement et les places dans le tableau $params
foreach ($element['params'] as $key => $value) {
$params[$key] = $value;
}
//appel la bonne class en fonction du type de l'élément à rendre
switch($element['type']){
case 'data_tables':
Table::create($params);
break;
case 'pie_chart':
PieChart::create($params);
break;
case 'column_chart':
BarChart::create($params);
break;
case 'donut_chart':
DonutChart::create($parms);
break;
case 'area_chart':
AreaChart::create($parms);
break;
case 'line_chart':
LineChart::create($parms);
break;
}
?>
</div>
<?php
//Si la ligne possède plusieurs colonnes alors $startRangeLetter prend la velaur de $endRangeLetter pour pouvoir rendre les
//éléments les un à coté des autres
// dump($rowContent);exit;
if(count($rowContent['element']) > 1){
$startRangeLetter = $endRangeLetter;
}
?>
<?php endforeach ?>
<?php endforeach ?>
<!-- On assigne les valeurs de $startRangeLetter et $startRangeIndex pour faire commencer la nouvelle ligne à la suite de la précédante -->
<?php $startRangeIndex = $endRangeIndex; $startRangeLetter = 'A';?>
<?php endforeach ?>
</div>
<?php endforeach ?>