/** * Genera un archivo pdf con el listado * @param array $parametros Array con los parámetros de configuración del listado * @param string $aditionalFilter * @return string $archivo El nombre completo (con la ruta) del archivo pdf generado */ public function getPdf($parametros, $aditionalFilter = '') { set_time_limit(0); // Orientación de página, unidad de medida y tipo de papel $orientation = strtoupper(trim($parametros['orientation'])); if ($orientation != 'P' and $orientation != 'L') { $orientation = 'P'; } $unit = strtolower(trim($parametros['unit'])); if ($unit != 'pt' and $unit != 'mm' and $unit != 'cm' and $unit != 'in') { $unit = 'mm'; } $format = strtolower(trim($parametros['format'])); if ($format != 'a4' and $format != 'a3' and $format != 'a5' and $format != 'letter' and $format != 'legal') { $format = 'A4'; } // Márgenes: top,right,bottom,left $margenes = explode(',', trim($parametros['margins'])); if (count($margenes) != 4) { $margenes = array('10', '10', '15', '10'); } // Tipo y tamaño de letra para el cuerpo del listado $bodyFont = explode(',', trim($parametros['body_font'])); if (count($bodyFont) != 3) { $bodyFont = array('Courier', '', '8'); } else { $bodyFont[0] = trim($bodyFont[0]); $bodyFont[1] = trim($bodyFont[1]); $bodyFont[2] = trim($bodyFont[2]); } // Altura de la línea. Por defecto 4 mm. $lineHeight = trim($parametros['line_height']); if ($lineHeight <= 0) { $lineHeight = 4; } // Construir la leyenda del filtro del listado $leyendaFiltro = array(); if (is_array($this->filter['columnsSelected'])) { foreach ($this->filter['columnsSelected'] as $key => $column) { if ($this->filter['valuesSelected'][$key]) { $objeto = new $this->entity(); $objeto->{"set{$column}"}($this->filter['valuesSelected'][$key]); $valor = ""; $valor = trim($objeto->{"get{$column}"}()); if (!$valor) { $valor = $this->filter['valuesSelected'][$key]; } $leyendaFiltro[] = array('Column' => $this->form->getTitleColumn($column), 'Value' => $valor); } } } //$leyendaFiltro[] = array('Column' => 'Orden', 'Value' => $parametros['order_by']); unset($objeto); // CREAR EL DOCUMENTO $pdf = new ListadoPDF($orientation, $unit, $format, array('title' => $parametros['title'], 'titleFont' => $bodyFont, 'columns' => $parametros['columns'], 'leyendaFiltro' => $leyendaFiltro)); $pdf->SetTopMargin($margenes[0]); $pdf->SetRightMargin($margenes[1]); $pdf->SetLeftMargin($margenes[3]); $pdf->SetAuthor("Informatica ALBATRONIC, SL"); $pdf->SetTitle($parametros['title']); $pdf->AliasNbPages(); $pdf->SetFillColor(210); $pdf->AddPage(); $pdf->SetAutoPageBreak(1, $margenes[2]); // CUERPO $pdf->SetFont($bodyFont[0], $bodyFont[1], $bodyFont[2]); // Construyo el array con los datos a listar. // Sustituyo el ORDERBY que hay en el filtro por pantalla // con el que viene de los parametros del listado if ($this->getQuery() == '') { $this->filter['orderBy'] = $parametros['order_by']; $this->makeQuery($aditionalFilter); } $em = new EntityManager($this->form->getConection()); $em->query($this->getQuery()); $rows = $em->fetchResult(); $nRegistros = $em->numRows(); $em->desConecta(); unset($em); $breakField = trim((string) $parametros['break_field']); $breakField = $breakField ? explode(",", $breakField) : array(); $breakPage = strtoupper(trim((string) $parametros['break_page'])) == 'YES'; // ---------------------------------------------- // Cargo la configuracion de la línea del listado $configLinea = array(); $columnsMulticell = array(); $caracteresLinea = 0; foreach ($parametros['columns'] as $key => $value) { $caracteres = (int) $value['length']; $anchoColumna = $pdf->getStringWidth(str_pad(" ", $caracteres)) + 1; //Le sumo 1 para que haya 1 mm de separación entre cada columna $caracteresLinea += $caracteres; $tipo = trim((string) $value['type']); $align = strtoupper(trim((string) $value['align'])); if ($align != 'R' and $align != 'C' and $align != 'L' and $align != 'J') { $align = "L"; } $formato = trim((string) $value['format']); $total = strtoupper(trim((string) $value['total'])) == 'YES'; $params = explode(",", trim($value['params'])); $parametrosMetodo = ""; foreach ($params as $valor) { $parametrosMetodo .= "{$valor},"; } $parametrosMetodo = substr($parametrosMetodo, 0, -1); $configLinea[$value['field']] = array('field' => $value['field'], 'params' => $parametrosMetodo, 'caracteres' => $caracteres, 'ancho' => $anchoColumna, 'align' => $align, 'formato' => $formato, 'type' => $tipo, 'total' => $total); if ($tipo == "text") { $columnsMulticell[] = array('field' => $value['field'], 'width' => $anchoColumna); } } // ----------------- $valorAnterior = ''; $subtotalRegistros = -1; // Itero el array con los datos para generar cada renglón del listado $totales = array(); $subTotales = array(); $objeto = new $this->entity(); foreach ($rows as $row) { $subtotalRegistros++; $objeto->bind($row); // Control (si se ha definido) del campo de ruptura if (count($breakField)) { // Instancio el objeto por el que se hace el break $objetoBreak = $objeto->{"get{$breakField['0']}"}(); $valorActual = is_object($objetoBreak) ? $objetoBreak->__toString() : $objetoBreak; if ($valorAnterior != $valorActual) { if ($valorAnterior != '') { $this->pintaTotales($pdf, $parametros['columns'], $subTotales); $subTotales = array(); // Pinta el subtotal de registos $pdf->Cell(0, 4, 'Subtotal Registos ' . $subtotalRegistros, 0, 1); $subtotalRegistros = 0; // Cambio de página si procede if ($breakPage) { $pdf->AddPage(); } } $pdf->SetFont($bodyFont[0], 'B', $bodyFont[2]); // Pinto el valor del campo de ruptura y los eventuales valores // adicionales que se hayan indicado en el nodo yml <break_field> $texto = $valorActual; for ($i = 1; $i < count($breakField); $i++) { $texto .= " " . $objetoBreak->{"get{$breakField[$i]}"}(); } $pdf->Cell(0, 10, $texto); $pdf->Ln(); $pdf->SetFont($bodyFont[0], $bodyFont[1], $bodyFont[2]); } $valorAnterior = $valorActual; unset($objetoBreak); } $pdf->CheckLinePageBreak($lineHeight, $row, $columnsMulticell); // Coordenadas X e Y del renglón $x0 = $pdf->GetX(); $y0 = $pdf->GetY(); // Para controlar los multicell $y1 = 0; // Recorro las columnas que componen cada renglón foreach ($configLinea as $value) { if ($value['params']) { $texto = trim($objeto->{"get{$value['field']}"}($value['params'])); } else { $texto = trim($objeto->{"get{$value['field']}"}()); } if ($value['formato']) { $texto = sprintf($value['formato'], $texto); } if ($value['type'] == 'text') { // Pinto un multicell sin recortar el texto $x = $pdf->GetX() + $value['ancho']; $pdf->MultiCell($value['ancho'], $lineHeight, $pdf->DecodificaTexto($texto), 0, $value['align']); if ($pdf->GetY() > $y1) { $y1 = $pdf->GetY(); } $pdf->SetXY($x, $y0); } else { // Pinto una celda normal $pdf->Cell($value['ancho'], $lineHeight, $pdf->DecodificaTexto($texto, $value['caracteres']), 0, 0, $value['align']); } // Calcular Eventuales totales y subtotales de cada columna if ($value['total']) { $totales[(string) $value['field']] += (double) $texto; $subTotales[(string) $value['field']] += (double) $texto; } } // Si ha habido algun multicell, cambio la coordenada Y if ($y1 != 0) { $pdf->SetXY($margenes[3], $y1); } else { $pdf->Ln(); } // Si se ha definido interlinea, se imprime a todo lo ancho if ($parametros['print_interline']) { $pdf->Cell(0, $lineHeight, str_repeat($parametros['print_interline'], $caracteresLinea + 5), 0, 1); } } unset($objeto); // Pintar los subtotales y totales si hay if (count($totales)) { if ($breakField) { $this->pintaTotales($pdf, $parametros['columns'], $subTotales); } $pdf->Ln(); $this->pintaTotales($pdf, $parametros['columns'], $totales); } elseif ($breakField) { // Pinta el subtotal de registos $subtotalRegistros++; $pdf->Cell(0, 4, 'Subtotal Registos ' . $subtotalRegistros, 0, 1); } // Total de registros impresos $pdf->Ln(); $pdf->SetFont('Arial', 'B', '8'); $pdf->Cell(0, 4, "Total Registros: " . $nRegistros); // Leyenda a pie de la última página if ($parametros['legend_text']) { $pdf->SetY(-25); $pdf->Write(4, $parametros['legend_text']); } $archivo = Archivo::getTemporalFileName(); if ($archivo) { $pdf->Output($archivo, 'F'); } unset($objeto); unset($pdf); return $archivo; }
/** * Genera un archivo pdf con el listado * @param array $parametros Array con los parámetros de configuración del listado * @param string $aditionalFilter * @return string $archivo El nombre completo (con la ruta) del archivo pdf generado */ public function getPdf($parametros, $aditionalFilter = '') { set_time_limit(0); // Orientación de página, unidad de medida y tipo de papel $orientation = strtoupper(trim($parametros['orientation'])); if ($orientation != 'P' and $orientation != 'L') { $orientation = 'P'; } $unit = strtolower(trim($parametros['unit'])); if ($unit != 'pt' and $unit != 'mm' and $unit != 'cm' and $unit != 'in') { $unit = 'mm'; } $format = strtolower(trim($parametros['format'])); if ($format != 'a4' and $format != 'a3' and $format != 'a5' and $format != 'letter' and $format != 'legal') { $format = 'A4'; } // Márgenes: top,right,bottom,left $margenes = explode(',', trim($parametros['margins'])); if (count($margenes) != 4) { $margenes = array('10', '10', '15', '10'); } // Tipo y tamaño de letra para el cuerpo del listado $bodyFont = explode(',', trim($parametros['body_font'])); if (count($bodyFont) != 3) { $bodyFont = array('Courier', '', '8'); } else { $bodyFont[0] = trim($bodyFont[0]); $bodyFont[1] = trim($bodyFont[1]); $bodyFont[2] = trim($bodyFont[2]); } // Altura de la línea. Por defecto 4 mm. $lineHeight = trim($parametros['line_height']); if ($lineHeight <= 0) { $lineHeight = 4; } // Construir la leyenda del filtro $leyendaFiltro = array(); if (is_array($this->filter['columnsSelected'])) { foreach ($this->filter['columnsSelected'] as $key => $column) { if ($this->filter['valuesSelected'][$key] != '') { $entidad = $this->circulares[$this->idCircular]['filters'][$key]['entity']; if ($entidad) { $aux = explode(",", $entidad); $entidad = $aux[0]; $idEntidad = $this->filter['valuesSelected'][$key]; $objeto = new $entidad($idEntidad); $valor = $objeto->__toString(); } else { $valor = $this->filter['valuesSelected'][$key]; } $leyendaFiltro[] = array('Column' => $parametros['filters'][$key]['caption'], 'Value' => $valor); } } } // CREAR EL DOCUMENTO $pdf = new ListadoPDF($orientation, $unit, $format, array('title' => $parametros['title'], 'titleFont' => $bodyFont, 'columns' => $parametros['columns'], 'leyendaFiltro' => $leyendaFiltro)); $pdf->SetTopMargin($margenes[0]); $pdf->SetRightMargin($margenes[1]); $pdf->SetLeftMargin($margenes[3]); $pdf->SetAuthor("Informatica ALBATRONIC, SL"); $pdf->SetTitle($parametros['title']); $pdf->AliasNbPages(); $pdf->SetFillColor(210); $pdf->AddPage(); $pdf->SetAutoPageBreak(true, $margenes[2]); // CUERPO $pdf->SetFont($bodyFont[0], $bodyFont[1], $bodyFont[2]); $em = new EntityManager($_SESSION['project']['conection']); $em->query($this->query); $rows = $em->fetchResult(); $nRegistros = $em->numRows(); $em->desConecta(); unset($em); $breakPage = strtoupper(trim((string) $parametros['break_page'])) == 'YES'; // ---------------------------------------------- // Cargo la configuración de la línea del listado // En el array $columnasMulticell guardo el nombre de los // campos que se imprimirán en Multicell y su anchura en la unidad de medida // establecida para calcular la altura máxima y controlar el salto de página // ---------------------------------------------- $configLinea = array(); $columnsMulticell = array(); $caracteresLinea = 0; foreach ($parametros['columns'] as $key => $value) { $caracteres = (int) $value['length']; $anchoColumna = $pdf->getStringWidth(str_pad(" ", $caracteres)) + 1; //Le sumo 1 para que haya 1 mm de separación entre cada columna $caracteresLinea += $caracteres; $tipo = trim((string) $value['type']); $align = strtoupper(trim((string) $value['align'])); if ($align != 'R' and $align != 'C' and $align != 'L' and $align != 'J') { $align = "L"; } $formato = trim((string) $value['format']); $total = strtoupper(trim((string) $value['total'])) == 'YES'; $configLinea[$value['field']] = array('field' => $value['field'], 'caracteres' => $caracteres, 'ancho' => $anchoColumna, 'align' => $align, 'formato' => $formato, 'type' => $tipo, 'total' => $total); if ($tipo == "text") { $columnsMulticell[] = array('field' => $value['field'], 'width' => $anchoColumna); } } // ----------------- $valorAnterior = array(); $subtotalRegistros = 0; // Itero el array con los datos para generar cada renglón del listado $totales = array(); $subTotales = array(); foreach ($rows as $row) { $subtotalRegistros++; // Control (si se ha definido) del(los) campo(s) de ruptura if (count($this->breakFields)) { // Recorro en orden inverso el array de campos de ruptura para // comprobar si ha cambiado el valor actual respecto al anterior. for ($i = 0; $i < count($this->breakFields); $i++) { //for ($i = count($breakField)-1; $i >= 0 ; $i--) { $columnaRuptura = $this->breakFields[$i]; $valorActual[$columnaRuptura] = $row[$columnaRuptura]; if ($valorAnterior[$columnaRuptura] != $valorActual[$columnaRuptura]) { if ($valorAnterior[$columnaRuptura] != '') { $this->pintaTotales($pdf, $parametros['columns'], $subTotales); $subTotales = array(); // Pinta el subtotal de registos if ($parametros['print_total_records']) { $pdf->Cell(0, 4, 'Subtotal Registos ' . $subtotalRegistros, 0, 1); $subtotalRegistros = 0; } // Cambio de página si procede if ($breakPage) { $pdf->AddPage(); } } // Pinto el valor del campo de ruptura $pdf->SetFont($bodyFont[0], 'B', $bodyFont[2]); $pdf->Cell(0, 10, $valorActual[$columnaRuptura]); $pdf->Ln(); $pdf->SetFont($bodyFont[0], $bodyFont[1], $bodyFont[2]); } $valorAnterior[$columnaRuptura] = $valorActual[$columnaRuptura]; } } $pdf->CheckLinePageBreak($lineHeight, $row, $columnsMulticell); // Coordenadas X e Y del renglón $x0 = $pdf->GetX(); $y0 = $pdf->GetY(); // Para controlar el desplazamiento vertical de los multicell $y1 = 0; // Recorro las columnas que componen cada renglón foreach ($configLinea as $value) { $texto = trim($row[$value['field']]); if ($value['formato']) { if ($value['type'] == 'money') { $texto = money_format($value['formato'], $texto); } else { $texto = sprintf($value['formato'], $texto); } } if ($value['type'] == 'text') { // Pinto un multicell sin recortar el texto $x = $pdf->GetX() + $value['ancho']; $pdf->MultiCell($value['ancho'], $lineHeight, $texto, 0, $value['align']); if ($pdf->GetY() > $y1) { $y1 = $pdf->GetY(); } $pdf->SetXY($x, $y0); } else { // Pinto una celda normal $pdf->Cell($value['ancho'], $lineHeight, $pdf->DecodificaTexto($texto, $value['caracteres']), 0, 0, $value['align']); } // Calcular Eventuales totales y subtotales de cada columna if ($value['total']) { $totales[(string) $value['field']] += (double) trim($row[$value['field']]); $subTotales[(string) $value['field']] += (double) trim($row[$value['field']]); } } // Si ha habido algun multicell, cambio la coordenada Y // al desplazamiento vertical mayor producido ($y1) if ($y1 != 0) { $pdf->SetXY($margenes[3], $y1); } else { $pdf->Ln(); } // Si se ha definido interlinea, se imprime a todo lo ancho if ($parametros['print_interline']) { $pdf->Cell(0, $lineHeight, str_repeat($parametros['print_interline'], $caracteresLinea + 5), 0, 1); } } unset($objeto); // Pintar los subtotales y totales si hay if (count($totales)) { if (count($this->breakFields)) { $this->pintaTotales($pdf, $parametros['columns'], $subTotales); } $pdf->Ln(); $this->pintaTotales($pdf, $parametros['columns'], $totales); } elseif (count($this->breakFields)) { // Pinta el subtotal de registos $pdf->Cell(0, 4, 'Subtotal Registos ' . $subtotalRegistros, 0, 1); } if ($parametros['print_total_records']) { if (count($this->breakFields)) { // Pinta el subtotal de registos //$subtotalRegistros++; $pdf->Cell(0, 4, 'Subtotal Registos ' . $subtotalRegistros, 0, 1); } // Total de registros impresos $pdf->Ln(); $pdf->SetFont('Arial', 'B', '8'); $pdf->Cell(0, 4, "Total Registros: " . $nRegistros); } // Pintar el gráfico if (is_array($parametros['grafico'])) { $this->pintaGrafico($pdf, $query, $parametros); } // Leyenda a pie de la última página if ($parametros['comment']) { $pdf->SetY(-25); $pdf->Write(4, $parametros['comment']); } $fichero = Archivo::getTemporalFileName(); if ($fichero) { $pdf->Output($fichero, 'F'); } unset($objeto); unset($pdf); return $fichero; }