KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

Range not fit sheet cell #1971

Open Epitello opened this topic on on Mar 15, 2021 - 5 comments

Epitello commented on Mar 15, 2021

Hello, i export a report to excel file and i set range for each elements, but when i open the excel file i have a space between the end of element and the end of cell. I join you a picture for illustrate. Thanks by advance

Sebastian Morales commented on Mar 16, 2021

Which type of element you used? Please post your excel template and full screenshot so that we have a better idea. Tks,

Epitello commented on Mar 16, 2021

here is the excel template :

<?php

    use koolreport\excel\PieChart;
    use koolreport\excel\Table;
    use koolreport\excel\BarChart;

    //dump($this->page, $this->right, $this->colorScheme, $this->format, $this->currency, $this->elements);exit;
    $page = $this->page;
    $elements = $this->elements;

    foreach ($elements as $key => $value) {
        if($value['type'] == 'VisualQuery'){
            unset($elements[$key]);
        }

        if($value['type'] == 'DataTables'){
            if(array_key_exists('paging', $value['params']['options'])){
                unset($elements[$key]['params']['options']['paging']);
            }
            //dump($elements, $elements[$key]['params']['options']);
        }
        //dump($elements, $value, $key);exit;
    }

    $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']['lines'] as $lineId => $lineContent): ?>
            <!-- Boucle sur les colonnes d'une ligne -->
            <?php foreach($lineContent['columns'] as $colId => $colContent): ?>
                <?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['width'] / 80);
                    $tempHeight = (int) round($colContent['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;

                    //Si l'élément est un tableau, on récupère le nombre de lignes du tableau plutot que ça dimension
                    if($elements[$colContent['id_element']]['type'] == 'DataTables'){
                        //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('assurance')->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($elements[$colContent['id_element']]['type'] == 'DataTables'):?>
                    <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($element['dataStore']),
                            "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 'DataTables':
                                Table::create($params);
                                break;
                            case 'PieChart':
                                PieChart::create($params);
                                break;
                            case 'ColumnChart':
                                BarChart::create($params);
                                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
                    if(count($lineContent['columns']) > 1){
                        $startRangeLetter = $endRangeLetter;
                    }
                ?>
            <?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 ?>

Epitello commented on Mar 16, 2021

here is the full screnshot

Sebastian Morales commented on Mar 17, 2021

Epitello, we have checked and confirmed this is a bug with the Excel's chart widget. It will be fixed in the next release of Excel and KoolReport Pro. Meanwhile you could apply a small fix yourself:

1 . Open the file "koolreport/excel/ChartBuilder.php"

2 . Replace the following line:

        $chart->setBottomRightPosition($range[1]);

with this one:

        $chart->setBottomRightPosition($range[1], 0, 0);

Let us know how it works for you. Tks,

Epitello commented on Mar 17, 2021

It's work perfectly. Thanks

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
help needed
solved

Excel