TabellaXls::printBodyXls()   B
last analyzed

Complexity

Conditions 10
Paths 27

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 10.0056

Importance

Changes 0
Metric Value
cc 10
eloc 26
nc 27
nop 3
dl 0
loc 37
ccs 25
cts 26
cp 0.9615
crap 10.0056
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Cdf\BiCoreBundle\Utils\Export;
4
5
use PhpOffice\PhpSpreadsheet\Spreadsheet;
6
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
7
use PhpOffice\PhpSpreadsheet\Writer\Xls;
8
use PhpOffice\PhpSpreadsheet\Cell\DataType;
9
use Cdf\BiCoreBundle\Utils\Entity\DoctrineFieldReader;
10
11
class TabellaXls
12
{
13
14
    private string $tableprefix;
15
16 3
    public function __construct(string $tableprefix)
17
    {
18 3
        $this->tableprefix = $tableprefix;
19
    }
20
21
    /**
22
     *
23
     * @param array<mixed> $parametri
24
     * @return string
25
     */
26 3
    public function esportaexcel($parametri = array())
27
    {
28 3
        set_time_limit(960);
29 3
        ini_set('memory_limit', '2048M');
30
31
        //Creare un nuovo file
32 3
        $spreadsheet = new Spreadsheet();
33 3
        $objPHPExcel = new Xls($spreadsheet);
34 3
        $spreadsheet->setActiveSheetIndex(0);
35
36
        // Set properties
37 3
        $spreadsheet->getProperties()->setCreator('Comune di Firenze');
38 3
        $spreadsheet->getProperties()->setLastModifiedBy('Comune di Firenze');
39
40 3
        $header = $parametri['parametritabella'];
41 3
        $rows = $parametri['recordstabella'];
42
        //Scrittura su file
43 3
        $sheet = $spreadsheet->getActiveSheet();
44 3
        $titolosheet = 'Esportazione ' . $parametri['nomecontroller'];
45 3
        $sheet->setTitle(substr($titolosheet, 0, 30));
46 3
        $sheet->getParent()->getDefaultStyle()->getFont()->setName('Verdana');
47
48 3
        $this->printHeaderXls($header, $sheet);
49
50 3
        $this->printBodyXls($header, $rows, $sheet);
51
52
        //Si crea un oggetto
53 3
        $todaydate = date('d-m-y');
54
55 3
        $filename = 'Exportazione';
56 3
        $filename = $filename . '-' . $todaydate . '-' . strtoupper(md5(uniqid((string) rand(), true)));
57 3
        $filename = $filename . '.xls';
58 3
        $filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filename;
59
60 3
        if (file_exists($filename)) {
61
            unlink($filename);
62
        }
63
64 3
        $objPHPExcel->save($filename);
65
66 3
        return $filename;
67
    }
68
69
    /**
70
     *
71
     * @param array<mixed> $testata
72
     * @param Worksheet $worksheet
73
     */
74 3
    private function printHeaderXls(array $testata, Worksheet $worksheet): void
75
    {
76 3
        $indicecolonnaheader = 1;
77 3
        $letteracolonna = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $letteracolonna is dead and can be removed.
Loading history...
78 3
        foreach ($testata as $modellocolonna) {
79 3
            if (false === $modellocolonna['escluso']) {
80
                //Si imposta la larghezza delle colonne
81 3
                $letteracolonna = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($indicecolonnaheader);
82 3
                $width = (int) $modellocolonna['larghezza'] / 7;
83 3
                $indicecolonnaheadertitle = $modellocolonna['etichetta'];
84 3
                $coltitle = strtoupper($indicecolonnaheadertitle);
85 3
                $worksheet->setCellValueByColumnAndRow($indicecolonnaheader, 1, $coltitle);
0 ignored issues
show
Deprecated Code introduced by
The function PhpOffice\PhpSpreadsheet...llValueByColumnAndRow() has been deprecated: 1.23.0 Use the setCellValue() method with a cell address such as 'C5' instead;, or passing in an array of [$columnIndex, $row] (e.g. [3, 5]), or a CellAddress object. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

85
                /** @scrutinizer ignore-deprecated */ $worksheet->setCellValueByColumnAndRow($indicecolonnaheader, 1, $coltitle);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
86 3
                $worksheet->getColumnDimension($letteracolonna)->setWidth($width);
87
88 3
                ++$indicecolonnaheader;
89
            }
90
        }
91
92
        //Imposta lo stile per l'intestazione un po più decente
93 3
        $this->setHeaderStyle($worksheet, $indicecolonnaheader - 1);
94
95 3
        $worksheet->getRowDimension(1)->setRowHeight(20);
96
    }
97
98
    /**
99
     *
100
     * @param array<mixed> $header
101
     * @param array<mixed> $rows
102
     * @param Worksheet $worksheet
103
     */
104 3
    private function printBodyXls($header, $rows, Worksheet $worksheet): void
105
    {
106 3
        $row = 2;
107 3
        foreach ($rows as $riga) {
108 3
            $col = 1;
109 3
            foreach ($header as $colonnatestata => $valorecolonnatestata) {
110 3
                if (false === $valorecolonnatestata['escluso']) {
111 3
                    $dfr = new DoctrineFieldReader($this->tableprefix);
112
113 3
                    $decodiche = isset($valorecolonnatestata['decodifiche']) ? $valorecolonnatestata['decodifiche'] : null;
114 3
                    $oggetto = $dfr->getField2Object($colonnatestata, $riga, $decodiche);
115 3
                    $valorecampo = $dfr->object2view($oggetto, $valorecolonnatestata['tipocampo']);
116 3
                    if ('' === $valorecampo || null === $valorecampo) {
117 3
                        $col = $col + 1;
118 3
                        continue;
119
                    }
120
                    //Fix https://github.com/ComuneFI/BiCoreBundle/issues/9
121 3
                    $xlsvalue = $this->getValueCell($valorecolonnatestata['tipocampo'], $valorecampo);
122 3
                    if (substr($xlsvalue, 0, 1) == '=') {
0 ignored issues
show
Bug introduced by
It seems like $xlsvalue can also be of type null; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
                    if (substr(/** @scrutinizer ignore-type */ $xlsvalue, 0, 1) == '=') {
Loading history...
123
                        $worksheet->setCellValueExplicitByColumnAndRow($col, $row, $xlsvalue, DataType::TYPE_STRING2);
0 ignored issues
show
Deprecated Code introduced by
The function PhpOffice\PhpSpreadsheet...xplicitByColumnAndRow() has been deprecated: 1.23.0 Use the setCellValueExplicit() method with a cell address such as 'C5' instead;, or passing in an array of [$columnIndex, $row] (e.g. [3, 5]), or a CellAddress object. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

123
                        /** @scrutinizer ignore-deprecated */ $worksheet->setCellValueExplicitByColumnAndRow($col, $row, $xlsvalue, DataType::TYPE_STRING2);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
124
                    } else {
125 3
                        $worksheet->setCellValueByColumnAndRow($col, $row, $xlsvalue);
0 ignored issues
show
Deprecated Code introduced by
The function PhpOffice\PhpSpreadsheet...llValueByColumnAndRow() has been deprecated: 1.23.0 Use the setCellValue() method with a cell address such as 'C5' instead;, or passing in an array of [$columnIndex, $row] (e.g. [3, 5]), or a CellAddress object. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

125
                        /** @scrutinizer ignore-deprecated */ $worksheet->setCellValueByColumnAndRow($col, $row, $xlsvalue);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
126
                    }
127 3
                    $col = $col + 1;
128
                }
129
            }
130 3
            $worksheet->getRowDimension($row)->setRowHeight(18);
131 3
            ++$row;
132
        }
133
134 3
        $col = 1;
135
        //Si impostano i formati cella in base al tipo di dato contenuto
136 3
        foreach ($header as $colonnatestata => $valorecolonnatestata) {
137 3
            if (false === $valorecolonnatestata['escluso']) {
138 3
                $this->setCellColumnFormat($worksheet, $col, $row - 1, $valorecolonnatestata['tipocampo']);
139 3
                $this->setColumnAutowidth($worksheet, $col);
140 3
                $col = $col + 1;
141
            }
142
        }
143
    }
144
145
    /**
146
     *
147
     * @param int $indiceultimacolonna
148
     * @param Worksheet $worksheet
149
     */
150 3
    private function setHeaderStyle(Worksheet $worksheet, int $indiceultimacolonna): void
151
    {
152 3
        $letteraultimacolonna = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($indiceultimacolonna);
153 3
        $styleArray = [
154 3
            'font' => [
155 3
                'bold' => true,
156 3
            ],
157 3
            'alignment' => [
158 3
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
159 3
            ],
160 3
            'borders' => [
161 3
                'allBorders' => [
162 3
                    'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
163 3
                ],
164 3
            ],
165 3
            'fill' => [
166 3
                'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
167 3
                'startColor' => [
168 3
                    'argb' => 'e5e5e5e5',
169 3
                ],
170 3
            ],
171 3
        ];
172
173 3
        $worksheet->getStyle('A1:' . $letteraultimacolonna . '1')->applyFromArray($styleArray);
174
    }
175
176
    /**
177
     *
178
     * @param string $tipocampo
179
     * @param mixed $valorecella
180
     * @return mixed|null
181
     */
182 3
    private function getValueCell(string $tipocampo, $valorecella)
183
    {
184 3
        $valore = null;
185
        switch ($tipocampo) {
186 3
            case 'date':
187 1
                $d = (int) substr($valorecella, 0, 2);
188 1
                $m = (int) substr($valorecella, 3, 2);
189 1
                $y = (int) substr($valorecella, 6, 4);
190 1
                $t_date = \PhpOffice\PhpSpreadsheet\Shared\Date::formattedPHPToExcel($y, $m, $d);
191 1
                $valore = $t_date;
192 1
                break;
193 3
            case 'datetime':
194 2
                $d = (int) substr($valorecella, 0, 2);
195 2
                $m = (int) substr($valorecella, 3, 2);
196 2
                $y = (int) substr($valorecella, 6, 4);
197 2
                $h = (int) substr($valorecella, 11, 2);
198 2
                $i = (int) substr($valorecella, 14, 2);
199 2
                $t_date = \PhpOffice\PhpSpreadsheet\Shared\Date::formattedPHPToExcel($y, $m, $d, $h, $i, 0);
200 2
                $valore = $t_date;
201 2
                break;
202
            default:
203 3
                $valore = $valorecella;
204 3
                break;
205
        }
206
207 3
        return $valore;
208
    }
209
210 3
    private function setCellColumnFormat(Worksheet $worksheet, int $indicecolonna, int $lastrow, string $tipocampo): void
211
    {
212 3
        $letteracolonna = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($indicecolonna);
213
        switch ($tipocampo) {
214 3
            case 'text':
215 1
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
216 1
                        ->getNumberFormat()
217 1
                        ->setFormatCode('@');
218 1
                break;
219 3
            case 'string':
220 3
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
221 3
                        ->getNumberFormat()
222 3
                        ->setFormatCode('@');
223 3
                break;
224 3
            case 'integer':
225 3
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
226 3
                        ->getNumberFormat()
227 3
                        ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER);
228 3
                break;
229 3
            case 'float':
230
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
231
                        ->getNumberFormat()
232
                        ->setFormatCode('#,##0.00');
233
                break;
234 3
            case 'decimal':
235 1
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
236 1
                        ->getNumberFormat()
237 1
                        ->setFormatCode('#,##0.00');
238 1
                break;
239 3
            case 'number':
240
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
241
                        ->getNumberFormat()
242
                        ->setFormatCode('#,##0.00');
243
                break;
244 3
            case 'datetime':
245
                //\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYYSLASH
246 2
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
247 2
                        ->getNumberFormat()
248 2
                        ->setFormatCode('dd/mm/yyyy hh:mm:ss');
249 2
                break;
250 3
            case 'date':
251 1
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
252 1
                        ->getNumberFormat()
253 1
                        ->setFormatCode('dd/mm/yyyy');
254 1
                break;
255
            default:
256 3
                $worksheet->getStyle($letteracolonna . '2:' . $letteracolonna . $lastrow)
257 3
                        ->getNumberFormat()
258 3
                        ->setFormatCode('@');
259 3
                break;
260
        }
261
    }
262
263 3
    private function setColumnAutowidth(Worksheet $worksheet, int $indicecolonna) : void
264
    {
265 3
        $letteracolonna = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($indicecolonna);
266 3
        $worksheet->getColumnDimension($letteracolonna)->setAutoSize(true);
267
    }
268
}
269