Forzar descarga de pdf en toba 3.4

¿Cómo puedo hacer para forzar la descarga de un pdf con cezpdf?
Tengo un evento filtrar/limpiar y un cuadro en un ci, cuando hago clic en filtrar se ejecuta el método conf_cuadro que es ahí donde quiero descargar el pdf, pero en vez de mostrarme el cuadro de diálogo para descargar me muestra esta pantalla:


Este es el código del método conf_cuadro:

	function conf__cuadro(sindicato_ei_cuadro $cuadro)
	{
		$array_caja = array();
		$array_caja_p = array();
		if (!empty($this->s__caja) || !empty($this->s__datos_filtro)) {
			$anterior_caja = $this->dep('datos')->tabla('caja')->get_anterior($this->s__datos_filtro);
			$saldo = 0;
			$total = 0;
			$saldo_dia = 0;
			$tot_dia = 0;
			if(count($anterior_caja)>0) $saldo += $anterior_caja[0]["sum"];
			if(!empty($saldo)) {
				$str_saldo = number_format($saldo, 2, ',', '.');
				$array_caja[] = array("comprob" => "Saldo anterior", "saldo" => $saldo);
				$array_caja_p[] = array("comprob" => "Saldo anterior", "saldo" => $str_saldo);
			}
			$fecha_aux = "";
			foreach ($this->s__caja as $value) {
                                $fecha_p = $value["fecha"] != $fecha_aux ? $value["fecha"] : "";
                                $fecha = $value["fecha"];
				if($fecha_aux != $fecha) {
					if(!empty($fecha_aux)) {
						$str_tot_dia = number_format($tot_dia,2,",",".");
						$str_saldo = number_format($saldo_dia, 2, ',', '.');
						$array_caja_p[] = array("fecha" => "", "nombre" => "", "comprob" => "Total $fecha_aux",
                                                "importe" => $str_tot_dia, "saldo" => $str_saldo);
					}
					$saldo_dia = 0;
					$tot_dia = 0;
					$fecha_aux = $fecha;
				}
				$total += round($value["importe"],2);
                $saldo_dia += round($value["importe"],2);
                $tot_dia += round($value["importe"],2);
				$importe = $value["importe"];
				$str_importe = number_format($value["importe"],2,",",".");
				$saldo = $value["saldo"];
				$str_saldo = number_format($value["saldo"],2,",",".");
				$array_caja[] = array("fecha" => $fecha, "razon_social" => $value["razon_social"],
										"comprob" => $value["comprob"], "importe" => $importe, "saldo" => $saldo);
				$array_caja_p[] = array("fecha" => $fecha_p, "razon_social" => $value["razon_social"],
										"comprob" => $value["comprob"], "importe" => $str_importe, "saldo" => $str_saldo);
			}
			$str_tot_dia = number_format($tot_dia,2,",",".");
			if(empty($saldo_dia)) $saldo_dia = $saldo;
            $str_saldo = number_format($saldo_dia, 2, ',', '.');
			if(empty($fecha_aux)) {
                $fecha_aux = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
            }
            $array_caja_p[] = array("fecha" => "", "razon_social" => "", "tipo" => "", "comprob" => "Total $fecha_aux",
									"importe" => $str_tot_dia, "saldo" => $str_saldo);
			$str_total = number_format($total, 2, ',', '.');
			$str_saldo = number_format($saldo, 2, ',', '.');
			$pdf = new Cezpdf();
			$pdf->selectFont("Helvetica");
			if(!empty($this->s__datos_filtro["fecha_desde"]) && !empty($this->s__datos_filtro["fecha_hasta"])) {
				$fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
				$fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
				$titulo = "Flujo de caja entrre " . $fecha_desde . " y " . $fecha_hasta;
			} elseif(!empty($this->s__datos_filtro["fecha_desde"])) {
				$fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
                $titulo = "Flujo de caja desde: " . $fecha_desde;
			} elseif(!empty($this->s__datos_filtro["fecha_hasta"])) {
				$fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
                $titulo = "Flujo de caja hasta: " . $fecha_hasta;
			}
			$pdf->ezStartPageNumbers(320, 10, 10, 'center', 'Página {PAGENUM} de {TOTALPAGENUM}');
			$cols = array('fecha'=>'Fecha', 'razon_social'=>'Empresa', 'comprob'=>'Nro. de comprobante',
                'importe'=>'Importe', 'saldo'=>'Saldo');
			$options = array('rowGap' => 5, 'width' => 500, 'cols'=>array('fecha'=>array('justification'=>'left', 'width'=>83.33),
                'razon_social'=>array('justification'=>'left', 'width'=>100),
                'comprob'=>array('justification'=>'center', 'width'=>100),
                'importe'=>array('justification'=>'right', 'width'=>100),
                'saldo'=>array('justification'=>'right', 'width'=>100)));
			$y = $pdf->ezTable($array_caja_p, $cols, $titulo, $options);
			$pdf->addText(310, $y-15,10, "Total:", 200);
			$pdf->addText(335, $y-15,10, $str_total, 100,'right');
			$pdf->addText(435, $y-15,10, $str_saldo, 100,'right');
			$nombre = "flujo_de_caja.pdf";
			$pdf->ezStream(array('download'=>1, 'Content-Disposition'=>$nombre, 'Accept-Ranges'=>1));
		}
		$cuadro->set_datos($array_caja);
	}

¿Cómo puedo solucionar este error?

Hola Matias,

fijate que los eventos tienen una configuración de accion predefinida donde podes hacer un autovinculo que responda a un servicio especifico mediante Vinculo - Nombre Servicio.

Alli podes tanto definir la exportacion a pdf (mediante la libreria que usa Toba) o podes definir un servicio puntual, el cual atendes vos manualmente en un metodo especifico del CI.. .en cuyo caso haces la exportacion dentro de dicho metodo.

Lo que si te recomiendo, es que en el item marques el checkbox que indica el retraso del envio de encabezados… eso te permite sacar los headers correctos manualmente y luego enviar el pdf.

Tene en cuenta que el download cuenta como pedido de pagina, por lo que el estado de la operación no siempre te va a quedar donde esperabas.

Saludos

Gracias por la respuesta @richard, ahí lo configuré como dijiste pero falta algo porque cuando ejecuto el evento Filtrar el pdf se descarga vacío y no muestra el cuadro ni el gráfico que tengo en el ci (esto último tengo entendido porque no ejecuta el método generar_html).

Lo tengo configurado así:

Este es el código del método vista_pdf:

    function vista_pdf()
    {
        $array_caja = array();
        $datos_caja = $this->dep('datos')->tabla('caja')->get_listado($this->s__datos_filtro);
        $anterior_caja = $this->dep('datos')->tabla('caja')->get_anterior($this->s__datos_filtro);
        $saldo = 0;
        $total = 0;
        $saldo_dia = 0;
        $tot_dia = 0;
        if (count($anterior_caja) > 0) $saldo += $anterior_caja[0]["sum"];
        if (!empty($saldo)) {
            $str_saldo = number_format($saldo, 2, ',', '.');
            $array_caja[] = array("comprob" => "Saldo anterior", "saldo" => $str_saldo);
        }
        $fecha_aux = "";
        foreach ($datos_caja as $value) {
            $fecha_p = $value["fecha"] != $fecha_aux ? $value["fecha"] : "";
            $fecha = $value["fecha"];
            if ($fecha_aux != $fecha) {
                if (!empty($fecha_aux)) {
                    $str_tot_dia = number_format($tot_dia, 2, ",", ".");
                    $str_saldo = number_format($saldo_dia, 2, ',', '.');
                    $array_caja[] = array("fecha" => "", "nombre" => "", "comprob" => "Total $fecha_aux",
                        "importe" => $str_tot_dia, "saldo" => $str_saldo);
                }
                $saldo_dia = 0;
                $tot_dia = 0;
                $fecha_aux = $fecha;
            }
            $total += round($value["importe"], 2);
            $saldo_dia += round($value["importe"], 2);
            $tot_dia += round($value["importe"], 2);
            $importe = $value["importe"];
            $str_importe = number_format($value["importe"], 2, ",", ".");
            $saldo = $value["saldo"];
            $str_saldo = number_format($value["saldo"], 2, ",", ".");
            $array_caja[] = array("fecha" => $fecha_p, "razon_social" => $value["razon_social"],
                "comprob" => $value["comprob"], "importe" => $str_importe, "saldo" => $str_saldo);
        }
        $str_tot_dia = number_format($tot_dia, 2, ",", ".");
        if (empty($saldo_dia)) $saldo_dia = $saldo;
        $str_saldo = number_format($saldo_dia, 2, ',', '.');
        if (empty($fecha_aux)) {
            $fecha_aux = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
        }
        $array_caja[] = array("fecha" => "", "razon_social" => "", "tipo" => "", "comprob" => "Total $fecha_aux",
            "importe" => $str_tot_dia, "saldo" => $str_saldo);
        $str_total = number_format($total, 2, ',', '.');
        $str_saldo = number_format($saldo, 2, ',', '.');
        $pdf = new Cezpdf();
        $pdf->selectFont("Helvetica");
        if (!empty($this->s__datos_filtro["fecha_desde"]) && !empty($this->s__datos_filtro["fecha_hasta"])) {
            $fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
            $fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
            $titulo = "Flujo de caja entre " . $fecha_desde . " y " . $fecha_hasta;
        } elseif (!empty($this->s__datos_filtro["fecha_desde"])) {
            $fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
            $titulo = "Flujo de caja desde: " . $fecha_desde;
        } elseif (!empty($this->s__datos_filtro["fecha_hasta"])) {
            $fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
            $titulo = "Flujo de caja hasta: " . $fecha_hasta;
        }
        $pdf->ezStartPageNumbers(320, 10, 10, 'center', 'Página {PAGENUM} de {TOTALPAGENUM}');
        $cols = array('fecha' => 'Fecha', 'razon_social' => 'Empresa', 'comprob' => 'Nro. de comprobante',
            'importe' => 'Importe', 'saldo' => 'Saldo');
        $options = array('rowGap' => 5, 'width' => 500, 'cols' => array('fecha' => array('justification' => 'left', 'width' => 83.33),
            'razon_social' => array('justification' => 'left', 'width' => 100),
            'comprob' => array('justification' => 'center', 'width' => 100),
            'importe' => array('justification' => 'right', 'width' => 100),
            'saldo' => array('justification' => 'right', 'width' => 100)));
        $y = $pdf->ezTable($array_caja, $cols, $titulo, $options);
        $pdf->addText(310, $y - 15, 10, "Total:", 200);
        $pdf->addText(335, $y - 15, 10, $str_total, 100, 'right');
        $pdf->addText(435, $y - 15, 10, $str_saldo, 100, 'right');
        $nombre = "flujo_de_caja.pdf";
        $pdf->ezStream(array('download' => 1, 'Content-Disposition' => $nombre, 'Accept-Ranges' => 1));
    }

Qué me falta para que funcione correctamente?

Ya lo logré hacer andar, vi que me faltaba agregar el parámetro toba_vista_pdf, pero al hacer clic en el botón filtrar no me atrapa el evento evt__filtro__filtrar, cómo puedo hacer para que me asigne los datos ingresados (fecha_desde, fecha_hasta) a la variable global del ci $this→s__datos_filtro?

Por favor respóndanme esta pregunta, necesito resolverlo con urgencia, gracias.

Ya lo solucioné, usé este código en el evento evt__filtro__filtrar:

	function evt__filtro__filtrar($datos)
	{
		if(array_no_nulo($datos)) {
			$fecha_desde = $datos['fecha_desde'];
			$fecha_hasta = $datos['fecha_hasta'];
			$url = toba::vinculador()->get_url(
				'',
				'',
				array(
					'fecha_desde' => $fecha_desde,
					'fecha_hasta' => $fecha_hasta
				),
				array(
					'servicio' => 'vista_pdf',
				)
			);
			header("Location: $url");
			exit;
		} else {
			toba::notificacion()->error("El filtro no posee valores");
		}
	}

Y le puse acción predeterminada ninguna a este evento.

Por favor diganme si hay algún método de toba que pueda usar en vez de la función header de php.

Hola Matias,

la idea no seria que el evento lo dispare el filtro, ya que necesitas recibir los datos del mismo para poder filtrar el cuadro, podes por tanto generar un evento en el cuadro mismo que dispare la descarga del pdf.

Terminas haciendo dos clicks pero no tiene sentido tener un cuadro que nunca vas a ver porque el filtrado te dispara una descarga todo el tiempo.

Terminas recurriendo a dicha función porque estas intentando llevar a cabo 2 comportamientos en simultaneo con un mismo elemento. No tenes muchas opciones ya que necesitas que el cliente lleve adelante la interaccion via un redirect.

Pensa la parte del evento a nivel de cuadro.

Saludos

No uso ningún cuadro, lo único que tengo en la pantalla del ci es el formulario donde hago el filtro, con los campos fecha_desde, fecha_hasta y el botón filtrar y cuando hago clic en ese botón me descarga el pdf con el detalle de los registros que concuerdan con el filtro y un gráfico de torta.

Hola Matias,

ok, si no tenes cuadro podes usar el CI para disparar el evento igualmente.

El tema es que cada componente dispara un evento a la vez, por lo tanto no podes disparar el filtrado y download al mismo tiempo.

Otra opcion, es que dispares el filtrado y en el pedido de pagina ese envias en la etapa de servicios un JS que haga el redirect que dispare el otro evento, pero tenes que tener los 2 eventos separados.

Saludos

El código del ci lo tengo así y funciona perfecto:

<?php
class ci_facturacion_por_provincia extends sindicato_ci
{
	protected $s__datos_filtro;

	//-----------------------------------------------------------------------------------
	//---- vista_pdf --------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function vista_pdf(toba_vista_pdf $salida)
	{
		$total = 0;
		$ctacte = array();
		$ctacte_g = array();
		$this->s__datos_filtro = toba::memoria()->get_parametros();
		if (!empty($this->s__datos_filtro)) {
			$datos = $this->dep('datos')->tabla('facturas')->get_provincia($this->s__datos_filtro);
			$provincia_aux = "";
			$importe_pro = 0;
			foreach ($datos as $value) {
				$provincia = $provincia_aux != $value['provincia'] ? $value['provincia'] : "";
				$provincia_g = utf8_encode($value['provincia']);
				if($provincia_aux != $value['provincia']){
					if (!empty($provincia_aux)){
						$str_importe = number_format($importe_pro, 2, ',', '.');
						$ctacte[] = array('provincia' => "", 'descripcion' => "<b>Total provincia</b>", 'importe' => "<b>$str_importe</b>");
						if($importe_pro != 0) {
							$provincia_g = utf8_encode($provincia_aux);
							$ctacte_g[] = array('provincia' => $provincia_g, 'importe' => $importe_pro);
						}
					}
					$provincia_aux = $value['provincia'];
					$importe_pro = 0;
				}
				$descripcion = $value['descripcion'];
				$importe = $value['importe'];
				$str_importe = number_format($importe, 2, ',', '.');
				$ctacte[] = array('provincia' => $provincia, 'descripcion' => $descripcion, 'importe' => $str_importe);
				$importe_pro += $importe;
				$total += $importe;
			}
			$str_importe = number_format($importe_pro, 2, ',', '.');
			$ctacte[] = array('provincia' => "", 'descripcion' => "<b>Total provincia</b>", 'importe' => "<b>$str_importe</b>");
			if($importe_pro != 0) {
				$provincia_g = utf8_encode($provincia_aux);
				$ctacte_g[] = array('provincia' => $provincia_g, 'importe' => $importe_pro);
			}
			$labels = array();
			$valores = array();
			foreach ($ctacte_g as $value) {
				$labels[] = $value["provincia"];
				$valores[] = $value["importe"];
			}
			$grafico = toba::componente("balance");
			$grafico->conf()->serie__agregar("balance", $valores);
			$grafico->conf()->serie__set_leyendas($labels);
			$grafico->conf()->serie__set_titulo("Facturaci�n por provincia");
			$imagen = toba::proyecto()->get_path_temp() . "/" . md5(uniqid(time())) . ".jpg";
			$grafico->conf()->imagen__generar($imagen);
			$str_total = number_format($total, 2, ',', '.');
			$ctacte[] = array('provincia' => '', 'descripcion' => "Total", 'importe' => $str_total);
			$salida->set_pdf_fuente("Helvetica");
			if(!empty($this->s__datos_filtro["fecha_desde"]) && !empty($this->s__datos_filtro["fecha_hasta"])) {
				$fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
				$fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
				$titulo = "Facturaci�n por provincia entre " . $fecha_desde . " y " . $fecha_hasta;
			} elseif(!empty($this->s__datos_filtro["fecha_desde"])) {
				$fecha_desde = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_desde"]));
				$titulo = "Facturaci�n por provincia desde: " . $fecha_desde;
			} elseif(!empty($this->s__datos_filtro["fecha_hasta"])) {
				$fecha_hasta = date("d/m/Y", strtotime($this->s__datos_filtro["fecha_hasta"]));
				$titulo = "Facturaci�n por provincia hasta: " . $fecha_hasta;
			}
			$salida->numerar_paginas('right', 'P�gina {PAGENUM} de {TOTALPAGENUM}');
			$cols = array('provincia'=>'Provincia', 'descripcion'=>'Concepto', 'importe'=>'Importe');
			$options = array('rowGap' => 5, 'width' => 500, 'cols'=>array('provincia'=>array('justification'=>'left'),
				'descripcion'=>array('justification'=>'left'),
				'importe'=>array('justification'=>'right')));
			$salida->insertar_imagen($imagen);
			$salida->titulo($titulo);
			$tabla = array('datos_tabla' => $ctacte, 'titulos_columnas' => $cols);
			$salida->tabla($tabla, true, 10, $options);
			$salida->set_nombre_archivo("facturacion_provincias.pdf");
			$salida->enviar_archivo();
		}
	}

	//-----------------------------------------------------------------------------------
	//---- filtro -----------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function evt__filtro__filtrar($datos)
	{
		if(array_no_nulo($datos)) {
			$id_provincia = $datos['id_provincia'];
			$fecha_desde = $datos['fecha_desde'];
			$fecha_hasta = $datos['fecha_hasta'];
			$url = toba::vinculador()->get_url(
				'',
				'',
				array(
					'id_provincia' => $id_provincia,
					'fecha_desde' => $fecha_desde,
					'fecha_hasta' => $fecha_hasta
				),
				array(
					'servicio' => 'vista_pdf',
				)
			);
			header("Location: $url");
			exit;
		} else {
			toba::notificacion()->error("El filtro no posee valores");
		}
	}

}
?>