format('d.m.Y')}"; $informe = new PhpSpreadsheet\Spreadsheet(); $informe->getProperties() ->setCompany('Incoviba') ->setCreator('admin@incoviba.cl') ->setTitle($title) ->setSubject($title) ->setCreated($fecha->getTimestamp()); $styles = [ 'font' => [ 'name' => 'Gill Sans MT', 'size' => 12 ] ]; $informe->getDefaultStyle()->applyFromArray($styles); $sheet = $informe->getActiveSheet(); $sheet->setTitle($title); $sheet->getColumnDimension('A')->setWidth('5.43'); $this->fillTitle($sheet, $fecha); $this->fillFechas($sheet, $fecha); $this->fillMonedas($sheet, $fecha); $finalRow = $this->fillEmpresas($sheet, $data); $finalRow = $this->fillCaja($sheet, $data, $finalRow + 2); foreach (range('B', 'V') as $columnIndex) { $sheet->getColumnDimension($columnIndex)->setAutoSize(true); } $this->setPageSetup($sheet, $finalRow); return $informe; } public function save(DateTimeInterface $fecha, PhpSpreadsheet\Spreadsheet $informe, string $type = 'Xlsx', ?string $filename = null): void { if ($filename === null) { $ext = strtolower($type); $filename = implode(DIRECTORY_SEPARATOR, [$this->folder, "{$informe->getActiveSheet()->getTitle()}.{$ext}"]); } $writer = PhpSpreadsheet\IOFactory::createWriter($informe, $type); if (str_starts_with($filename, 'php://')) { $downloadFilename = "Informe de Tesorería {$fecha->format('d.m.Y')}.xlsx"; // ZipStream, used by PhpSpreadsheet when saving, sends headers header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header("Content-Disposition: attachment;filename=\"{$downloadFilename}\""); header('Cache-Control: max-age=0'); } $writer->save($filename); } protected function getAnterior(DateTimeInterface $fecha): DateTimeInterface { if (!isset($this->anterior)) { $this->anterior = $fecha->sub(new DateInterval('P1D')); if ($this->anterior->format('N') === '7') { $this->anterior = $fecha->sub(new DateInterval('P3D')); } } return $this->anterior; } protected function fillTitle(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void { $intl = new IntlDateFormatter('es-CL'); $intl->setPattern('dd MMM yyyy'); $sheet->getCell('B2')->setValue('CONTROL DIARIO CAJA EMPRESAS'); $sheet->mergeCells('B2:V2'); $styles = [ 'font' => [ 'bold' => true, 'size' => 18 ], 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => [ 'argb' => 'FFFFC000' ] ], 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER ], 'borders' => [ 'outline' => [ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN ] ] ]; $sheet->getStyle('B2:V2')->applyFromArray($styles); $sheet->getCell('B3')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha)); $styles = [ 'font' => [ 'size' => 18 ], 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER ], 'numberFormat' => [ 'formatCode' => 'DD MMMM YYYY' ] ]; $sheet->getCell('B3')->getStyle()->applyFromArray($styles); $sheet->mergeCells('B3:V3'); } protected function fillFechas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void { $anterior = $this->getAnterior($fecha); $sheet->getCell('B4')->setValue('Informe anterior'); $sheet->getCell('B5')->setValue('Informe actual'); $sheet->getCell('C4')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($anterior)); $sheet->getCell('C5')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha)); $sheet->getStyle('C4:C5')->getNumberFormat()->setFormatCode(PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY); $sheet->getStyle('B4:C5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); } protected function fillMonedas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void { $sheet->getCell('E4')->setValue('Valor UF'); $sheet->getCell('E5')->setValue('Valor Dólar'); $sheet->getCell('F4')->setValue($this->ufService->get($fecha)); $sheet->getCell('F5')->setValue($this->usdService->get($fecha)); $sheet->getStyle('F4:F5')->getNumberFormat()->setFormatCode("$ #,##0.00"); $sheet->getStyle('E4:F5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); } protected function fillEmpresas(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, int $startRow = 7): int { $columns = ['EMPRESA', 'Banco', 'Cuenta', 'Saldo anterior', 'Saldo actual', 'Diferencia', 'FFMM', 'DAP', 'Saldo empresa', 'Total Cuentas', 'Total FFMM', 'Total DAP', 'Caja Total']; $styles = [ 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER ], 'borders' => [ 'outline' => [ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN ] ], 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'color' => [ 'argb' => 'FF333F4F' ] ], 'font' => [ 'color' => [ 'argb' => PhpSpreadsheet\Style\Color::COLOR_WHITE ] ] ]; $this->fillColumns($sheet, $columns, $styles, $startRow); $rowIndex = $startRow + 1; foreach ($data['inmobiliarias'] as $dataInmobiliaria) { $rowIndex += $this->fillInmobiliaria($sheet, $dataInmobiliaria, $rowIndex); } $finalRow = $rowIndex; $sheet->getStyle("B7:N{$finalRow}")->getBorders()->getAllBorders() ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN) ->getColor()->setARGB('FFD9D9D9'); $sheet->getStyle("C8:D{$finalRow}")->getAlignment() ->setHorizontal(PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $this->fillTotals($sheet, 7, $finalRow ++); $sheet->getStyle("E8:N{$finalRow}")->getNumberFormat() ->setFormatCode(self::CURRENCY_CODE); return $finalRow; } protected function fillCaja(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, $startRow): int { $sheet->getCell("B{$startRow}")->setValue('CUADRATURA CAJA DÍA ANTERIOR'); $sheet->mergeCells("B{$startRow}:V{$startRow}"); $sheet->getStyle("B{$startRow}:V{$startRow}")->applyFromArray([ 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER ], 'borders' => [ 'outline' => [ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN ] ], 'font' => [ 'bold' => true ], 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'color' => [ 'argb' => 'FFFFC000' ] ] ]); $rowIndex = $startRow; $columns = ['EMPRESA', 'INGRESOS', 'EGRESOS', 'FECHA', 'BANCO', 'DESCRIPCIÓN', '', 'CATEGORIA', '', 'CC', 'DETALLE', '', 'N° DOC.', 'RUT', 'NOMBRES', '', '', '', '', '', '']; $styles = [ 'borders' => [ 'allBorders' => [ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN ] ], 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => [ 'argb' => 'FFD9D9D9' ] ] ]; $this->fillColumns($sheet, $columns, $styles, ++ $rowIndex); $sheet->mergeCells("G{$rowIndex}:H{$rowIndex}") ->mergeCells("I{$rowIndex}:J{$rowIndex}") ->mergeCells("L{$rowIndex}:M{$rowIndex}") ->mergeCells("P{$rowIndex}:R{$rowIndex}") ->mergeCells("S{$rowIndex}:V{$rowIndex}"); $rowIndex += 2; $sheet->getCell("T{$rowIndex}") ->setValue("Saldo Consolidado al") ->getStyle()->applyFromArray([ 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT ], 'font' => [ 'bold' => true ] ]); $sheet->getCell("U{$rowIndex}")->setValue("=C5") ->getStyle()->applyFromArray([ 'font' => [ 'bold' => true ], 'numberFormat' => [ 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY ] ]); $sheet->getCell("V{$rowIndex}")->setValue(0)->getStyle()->applyFromArray([ 'font' => [ 'bold' => true ], 'numberFormat' => [ 'formatCode' => self::CURRENCY_CODE ] ]); $rowIndex ++; $styles = [ 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => [ 'argb' => 'FFD9E1F2' ] ], 'font' => [ 'bold' => true ] ]; foreach ($data['movimientos'] as $tipo => $movimientos) { if ($tipo === 'capital dap') { $sheet->getCell("B{$rowIndex}")->setValue('CAPITAL DAP'); $sheet->getCell("T{$rowIndex}")->setValue('SUMA DAP'); $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles); $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); $totalRow = $rowIndex; $rowIndex ++; if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0) { $sheet->getCell("V{$totalRow}")->setValue(0); continue; } $start = $rowIndex; foreach ($movimientos as $ms) { foreach ($ms as $movimiento) { $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon); $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono); $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo); $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha)); $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre); $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa); $rowIndex ++; } } $end = $rowIndex; $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})"); $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); continue; } $sheet->getCell("B{$rowIndex}")->setValue(strtoupper($tipo)); $sheet->getCell("T{$rowIndex}")->setValue('SUMA '.strtoupper($tipo)); $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles); $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat() ->setFormatCode(self::CURRENCY_CODE); $totalRow = $rowIndex; $rowIndex ++; if (count($movimientos) === 0) { $sheet->getCell("V{$totalRow}")->setValue(0); continue; } $start = $rowIndex; foreach ($movimientos as $movimiento) { $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon); $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono); $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo); $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha)); $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre); $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa); $rowIndex ++; } $end = $rowIndex; $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})"); $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat() ->setFormatCode(self::CURRENCY_CODE); } $end = $rowIndex; $rowIndex ++; $sheet->getCell("B{$rowIndex}")->setValue('TOTAL'); $sheet->getCell("C{$rowIndex}")->setValue("=SUM(C{$startRow}:C{$end})"); $sheet->getCell("D{$rowIndex}")->setValue("=SUM(D{$startRow}:D{$end})"); $sheet->getCell("T{$rowIndex}")->setValue('Saldo final al') ->getStyle()->applyFromArray([ 'alignment' => [ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT ], 'font' => [ 'bold' => true ] ]); $sheet->getCell("U{$rowIndex}")->setValue('=C5') ->getStyle()->applyFromArray([ 'font' => [ 'bold' => true ], 'numberFormat' => [ 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY ] ]); $sheet->getCell("V{$rowIndex}")->setValue(0)->getStyle()->applyFromArray([ 'font' => [ 'bold' => true ], 'numberFormat' => [ 'formatCode' => self::CURRENCY_CODE ] ]); $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray([ 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => [ 'argb' => 'FFD9D9D9' ] ], 'font' => [ 'bold' => true ] ]); $sheet->getStyle("C{$startRow}:D{$rowIndex}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); $columnRanges = [ ['B', 'B'], ['C', 'C'], ['D', 'D'], ['E', 'E'], ['F', 'F'], ['G', 'H'], ['I', 'J'], ['K', 'K'], ['L', 'M'], ['N', 'N'], ['O', 'O'], ['P', 'R'], ['S', 'V'] ]; foreach ($columnRanges as $range) { $sheet->getStyle("{$range[0]}{$startRow}:{$range[1]}{$rowIndex}")->getBorders()->getOutline() ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); } return $rowIndex; } protected function fillColumns(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $columns, array $styles, $rowIndex): void { $columnIndex = 2; foreach ($columns as $index => $column) { $columnIndex = 2 + $index; $sheet->getCell([$columnIndex, $rowIndex])->setValue($column); } $sheet->getStyle([2, $rowIndex, $columnIndex, $rowIndex])->applyFromArray($styles); } protected function fillInmobiliaria(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $dataInmobiliaria, int $baseRowIndex): int { $rowIndex = $baseRowIndex; $sheet->getCell("B{$rowIndex}")->setValue($dataInmobiliaria->inmobiliaria->razon); foreach ($dataInmobiliaria->cuentas as $cuentaRowIndex => $cuenta) { $this->fillCuenta($sheet, $cuenta, 3, $baseRowIndex + $cuentaRowIndex); } $sheet->getCell("K{$rowIndex}")->setValue($dataInmobiliaria->total()); $sheet->getCell("L{$rowIndex}")->setValue($dataInmobiliaria->ffmm()); $sheet->getCell("M{$rowIndex}")->setValue($dataInmobiliaria->deposito()); $sheet->getCell("N{$rowIndex}")->setValue($dataInmobiliaria->caja()); if (count($dataInmobiliaria->cuentas) > 1) { $finalRow = $rowIndex + count($dataInmobiliaria->cuentas) - 1; $sheet->mergeCells("B{$rowIndex}:B{$finalRow}"); $sheet->mergeCells("K{$rowIndex}:K{$finalRow}"); $sheet->mergeCells("L{$rowIndex}:L{$finalRow}"); $sheet->mergeCells("M{$rowIndex}:M{$finalRow}"); $sheet->mergeCells("N{$rowIndex}:N{$finalRow}"); } return count($dataInmobiliaria->cuentas); } protected function fillCuenta(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $cuenta, int $startColumnIndex, int $rowIndex): void { $columnIndex = $startColumnIndex; $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->banco); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->numero); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->anterior); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->actual); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue("=F{$rowIndex}-E{$rowIndex}"); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->ffmm); $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->deposito); $sheet->getCell([$columnIndex, $rowIndex])->setValue("=SUM(F{$rowIndex},H{$rowIndex}:I{$rowIndex})"); } protected function fillTotals(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $startRow, int $finalRow): void { $rowIndex = $finalRow + 1; $sheet->getCell("B{$rowIndex}")->setValue('TOTAL'); foreach (range('E', 'N') as $columnIndex) { $sheet->getCell("{$columnIndex}{$rowIndex}")->setValue("=SUBTOTAL(109,{$columnIndex}{$startRow}:{$columnIndex}{$finalRow})"); } $styles = [ 'font' => [ 'bold' => true ], 'fill' => [ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => [ 'argb' => 'FFD9D9D9' ] ], 'borders' => [ 'outline' => [ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => [ 'argb' => PhpSpreadsheet\Style\Color::COLOR_BLACK ] ] ] ]; $sheet->getStyle("B{$rowIndex}:N{$rowIndex}")->applyFromArray($styles); } protected function setPageSetup(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $finalRow): void { $sheet->getPageSetup() ->setPrintArea("B2:V{$finalRow}") ->setFitToWidth(1) ->setPaperSize(PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_LEGAL) ->setOrientation(PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE); $sheet->setShowGridlines(false); $sheet->getSheetView() ->setView(PhpSpreadsheet\Worksheet\SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW) ->setZoomScale(70); } }