getActiveSheet(); $installmentsSheet->setTitle('Parcelas'); $this->createInstallmentsSheet($installmentsSheet); // Criar aba de Instruções $instructionsSheet = $spreadsheet->createSheet(); $instructionsSheet->setTitle('Instrucciones'); $this->createInstructionsSheet($instructionsSheet); // Criar aba de Exemplo $exampleSheet = $spreadsheet->createSheet(); $exampleSheet->setTitle('Ejemplo'); $this->createExampleSheet($exampleSheet); // Voltar para primeira aba $spreadsheet->setActiveSheetIndex(0); return $spreadsheet; } /** * Criar aba de parcelas com cabeçalho e validações */ private function createInstallmentsSheet($sheet): void { // Definir largura das colunas $sheet->getColumnDimension('A')->setWidth(12); // Nº $sheet->getColumnDimension('B')->setWidth(15); // Fecha $sheet->getColumnDimension('C')->setWidth(15); // Cuota $sheet->getColumnDimension('D')->setWidth(15); // Intereses $sheet->getColumnDimension('E')->setWidth(15); // Capital $sheet->getColumnDimension('F')->setWidth(15); // Tasas/Seguros $sheet->getColumnDimension('G')->setWidth(15); // Estado $sheet->getColumnDimension('H')->setWidth(30); // Observaciones // Cabeçalho principal - título $sheet->setCellValue('A1', 'PLANTILLA DE IMPORTACIÓN - CUENTA PASIVO'); $sheet->mergeCells('A1:H1'); $sheet->getStyle('A1')->applyFromArray([ 'font' => ['bold' => true, 'size' => 16, 'color' => ['rgb' => 'FFFFFF']], 'fill' => ['fillType' => Fill::FILL_SOLID, 'color' => ['rgb' => '1E40AF']], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], ]); $sheet->getRowDimension(1)->setRowHeight(30); // Subtítulo $sheet->setCellValue('A2', 'Rellene las columnas con los datos de sus cuotas. Las columnas marcadas con * son obligatorias.'); $sheet->mergeCells('A2:H2'); $sheet->getStyle('A2')->applyFromArray([ 'font' => ['italic' => true, 'size' => 10, 'color' => ['rgb' => '6B7280']], ]); // Cabeçalhos das colunas $headers = [ 'A3' => 'Nº Cuota *', 'B3' => 'Fecha Venc. *', 'C3' => 'Valor Cuota *', 'D3' => 'Intereses', 'E3' => 'Capital', 'F3' => 'Tasas/Seguros', 'G3' => 'Estado', 'H3' => 'Observaciones', ]; foreach ($headers as $cell => $value) { $sheet->setCellValue($cell, $value); } // Estilo do cabeçalho $sheet->getStyle('A3:H3')->applyFromArray([ 'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']], 'fill' => ['fillType' => Fill::FILL_SOLID, 'color' => ['rgb' => '3B82F6']], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], 'borders' => [ 'allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '1E40AF']], ], ]); // Dicas sob o cabeçalho $tips = [ 'A4' => '1, 2, 3...', 'B4' => 'DD/MM/AAAA', 'C4' => '0.00', 'D4' => '0.00', 'E4' => '0.00', 'F4' => '0.00', 'G4' => 'Pendiente/Pagado', 'H4' => 'Texto libre', ]; foreach ($tips as $cell => $value) { $sheet->setCellValue($cell, $value); } $sheet->getStyle('A4:H4')->applyFromArray([ 'font' => ['italic' => true, 'size' => 9, 'color' => ['rgb' => '9CA3AF']], 'fill' => ['fillType' => Fill::FILL_SOLID, 'color' => ['rgb' => 'F3F4F6']], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], ]); // Área de dados (linhas 5-64 para até 60 parcelas) for ($row = 5; $row <= 64; $row++) { // Número da parcela $sheet->setCellValue("A{$row}", $row - 4); // Aplicar formato de número nas colunas de valores $sheet->getStyle("C{$row}:F{$row}")->getNumberFormat() ->setFormatCode(NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1); // Aplicar formato de data na coluna B $sheet->getStyle("B{$row}")->getNumberFormat() ->setFormatCode('DD/MM/YYYY'); // Adicionar validação de lista para Estado $validation = $sheet->getCell("G{$row}")->getDataValidation(); $validation->setType(DataValidation::TYPE_LIST); $validation->setErrorStyle(DataValidation::STYLE_INFORMATION); $validation->setAllowBlank(true); $validation->setShowDropDown(true); $validation->setFormula1('"Pendiente,Pagado,Vencido"'); // Bordas leves $sheet->getStyle("A{$row}:H{$row}")->applyFromArray([ 'borders' => [ 'allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => 'E5E7EB']], ], ]); // Alternar cores das linhas if (($row - 5) % 2 == 1) { $sheet->getStyle("A{$row}:H{$row}")->applyFromArray([ 'fill' => ['fillType' => Fill::FILL_SOLID, 'color' => ['rgb' => 'F9FAFB']], ]); } } // Congelar painel no cabeçalho $sheet->freezePane('A5'); } /** * Criar aba de instruções */ private function createInstructionsSheet($sheet): void { $sheet->getColumnDimension('A')->setWidth(80); $instructions = [ ['INSTRUCCIONES DE USO', true, '1E40AF'], ['', false, 'FFFFFF'], ['1. DATOS OBLIGATORIOS', true, '059669'], [' • Nº Cuota: Número secuencial de la cuota (1, 2, 3...)', false, '000000'], [' • Fecha Venc.: Fecha de vencimiento en formato DD/MM/AAAA', false, '000000'], [' • Valor Cuota: Valor total de la cuota a pagar', false, '000000'], ['', false, 'FFFFFF'], ['2. DATOS OPCIONALES (recomendados)', true, '059669'], [' • Intereses: Parte de la cuota correspondiente a intereses', false, '000000'], [' • Capital: Parte de la cuota correspondiente a amortización', false, '000000'], [' • Tasas/Seguros: Otros cargos incluidos en la cuota', false, '000000'], [' • Estado: Pendiente, Pagado o Vencido', false, '000000'], [' • Observaciones: Notas adicionales', false, '000000'], ['', false, 'FFFFFF'], ['3. TIPOS DE CONTRATOS SOPORTADOS', true, '059669'], [' • Préstamo Personal (Sistema PRICE - cuota fija)', false, '000000'], [' • Financiación de Vehículo', false, '000000'], [' • Financiación Inmobiliaria (Sistema SAC o PRICE)', false, '000000'], [' • Consorcio (cuotas variables)', false, '000000'], [' • Leasing', false, '000000'], ['', false, 'FFFFFF'], ['4. SISTEMA PRICE (Cuota Fija)', true, '059669'], [' En este sistema:', false, '000000'], [' • La cuota es CONSTANTE todos los meses', false, '000000'], [' • Los intereses DISMINUYEN cada mes', false, '000000'], [' • La amortización AUMENTA cada mes', false, '000000'], [' • Cuota = Intereses + Capital + Tasas', false, '000000'], ['', false, 'FFFFFF'], ['5. SISTEMA SAC (Amortización Constante)', true, '059669'], [' En este sistema:', false, '000000'], [' • La amortización es CONSTANTE todos los meses', false, '000000'], [' • Los intereses DISMINUYEN cada mes', false, '000000'], [' • La cuota DISMINUYE cada mes', false, '000000'], ['', false, 'FFFFFF'], ['6. CUOTA DE CARENCIA', true, '059669'], [' Algunos contratos tienen una primera cuota de carencia:', false, '000000'], [' • Solo se pagan intereses (sin amortización de capital)', false, '000000'], [' • El capital amortizado en esta cuota debe ser 0', false, '000000'], ['', false, 'FFFFFF'], ['7. ESTADOS VÁLIDOS', true, '059669'], [' • Pendiente: Cuota aún no pagada', false, '000000'], [' • Pagado: Cuota ya abonada', false, '000000'], [' • Vencido: Cuota no pagada y pasada la fecha de vencimiento', false, '000000'], ]; $row = 1; foreach ($instructions as $item) { $sheet->setCellValue("A{$row}", $item[0]); $style = ['font' => ['color' => ['rgb' => $item[2]]]]; if ($item[1]) { $style['font']['bold'] = true; $style['font']['size'] = 12; } $sheet->getStyle("A{$row}")->applyFromArray($style); $row++; } } /** * Criar aba de exemplo preenchida */ private function createExampleSheet($sheet): void { // Copiar estrutura da aba de parcelas $this->createInstallmentsSheet($sheet); // Dados de exemplo (Empréstimo PRICE típico) $exampleData = [ [1, '05/06/2025', 20.85, 20.85, 0.00, 0.00, 'Pagado', 'Cuota de carencia (solo intereses)'], [2, '05/07/2025', 122.00, 48.33, 73.67, 0.00, 'Pagado', ''], [3, '05/08/2025', 122.00, 47.68, 74.32, 0.00, 'Pagado', ''], [4, '05/09/2025', 122.00, 47.01, 74.99, 0.00, 'Pagado', ''], [5, '05/10/2025', 122.00, 46.35, 75.65, 0.00, 'Pagado', ''], [6, '05/11/2025', 122.00, 45.68, 76.32, 0.00, 'Pagado', ''], [7, '05/12/2025', 122.00, 45.00, 77.00, 0.00, 'Pendiente', ''], [8, '05/01/2026', 122.00, 44.31, 77.69, 0.00, 'Pendiente', ''], [9, '05/02/2026', 122.00, 43.62, 78.38, 0.00, 'Pendiente', ''], [10, '05/03/2026', 122.00, 42.93, 79.07, 0.00, 'Pendiente', ''], ]; $row = 5; foreach ($exampleData as $data) { $sheet->setCellValue("A{$row}", $data[0]); $sheet->setCellValue("B{$row}", $data[1]); $sheet->setCellValue("C{$row}", $data[2]); $sheet->setCellValue("D{$row}", $data[3]); $sheet->setCellValue("E{$row}", $data[4]); $sheet->setCellValue("F{$row}", $data[5]); $sheet->setCellValue("G{$row}", $data[6]); $sheet->setCellValue("H{$row}", $data[7]); $row++; } // Destacar que é exemplo $sheet->setCellValue('A1', 'EJEMPLO - PRÉSTAMO PERSONAL (Sistema PRICE)'); $sheet->getStyle('A1')->applyFromArray([ 'font' => ['bold' => true, 'size' => 16, 'color' => ['rgb' => 'FFFFFF']], 'fill' => ['fillType' => Fill::FILL_SOLID, 'color' => ['rgb' => '059669']], ]); } /** * Salvar template em arquivo */ public function saveTemplate(string $path): void { $spreadsheet = $this->generateTemplate(); $writer = new Xlsx($spreadsheet); $writer->save($path); } /** * Obter caminho do template */ public static function getTemplatePath(): string { return storage_path('app/templates/passivo_template.xlsx'); } }