コード例 #1
0
ファイル: Listado.class.php プロジェクト: albatronic/hermes
 /**
  * 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;
 }
コード例 #2
0
 /**
  * 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;
 }