Personalizando el botón exportar del visor de Crystal Report

En una aplicación de escritorio en la que estoy trabajando uso el componente “Crystal Report Viewer” para visualizar mis informes.

El visor ofrece bastante funcionalidad, pero como muchas veces ocurre, no siempre se adecua al 100% a lo que quiere en cliente y toca buscar la mejor manera de personalizar.

En este caso, necesitaba personalizar algunos aspectos de la opción de exportar. Una opción es hacerte tu propia barra de herramientas pero en este caso, yo quería usar toda la funcionalidad posible y escribir simplemente el código para personalizar los aspectos que quería el cliente.

La solución que he encontrado después de navegar y pegarme un buen rato es sustituir el botón exportar por uno personalizado, pero sin que visualmente se vea afectado nada:


  1. Buscar una referencia al control de exportar que viene por defecto.
  2. Crear un botón nuevo y copiar las propiedades.
  3. Añadir el nuevo botón a la barra.
  4. Incluir un manejador del evento “Click” para el nuevo botón.
  5. Ocultar el botón de exportar por defecto.
  6. Incluir el código necesario en el manejado del evento Click para exportar el informe.

El código sería así…..


private void ChangeExportButton()
{

    foreach (Control ctrl in myCrystalReportViewer.Controls)
    {
        //Buscar toolstrip del visor de informes
        if (ctrl is ToolStrip)
        {
            ToolStrip ts = (ToolStrip)ctrl;

            foreach (ToolStripItem tsi in ts.Items)
            {

                //Buscar el botón exportar por un ImageIndex
                if (tsi is ToolStripButton && tsi.ImageIndex == 8)
                {

                 
                    ToolStripButton crXb = (ToolStripButton)tsi;

                    //Clonar el aspecto
                    ToolStripButton tsb = new ToolStripButton();
                    tsb.Size = crXb.Size;
                    tsb.Padding = crXb.Padding;
                    tsb.Margin = crXb.Margin;
                    tsb.TextImageRelation = crXb.TextImageRelation;

                    tsb.Text = crXb.Text;
                    tsb.ToolTipText = crXb.ToolTipText;
                    tsb.ImageScaling = crXb.ImageScaling;
                    tsb.ImageAlign = crXb.ImageAlign;
                    tsb.ImageIndex = crXb.ImageIndex;
                    tsb.Visible = crXb.Visible;
                    tsb.Enabled = crXb.Enabled;

                    //Añadir el nuevo botón
                    ts.Items.Insert(0, tsb);

                    tsb.Click += new EventHandler(Export_Click);


                    break;
                }
            }
        }
    }


    //Ocultar el botón por defecto
    this.myCrystalReportViewer.ShowExportButton = false;
}

private void Export_Click(object sender, EventArgs e)
{
    SaveFileDialog saveDiag = new SaveFileDialog();
    saveDiag.Title = “Exportar Informe”;
    saveDiag.Filter = “Adobe Acrobat (*.pdf)|*.pdf|Microsoft Excel (*.xls)|*.xls|Sólo datos de Microsoft Excel (*.xls)|*.xls|Microsoft Word (*.doc)|*.doc|Formato de texto enriquecido (*.rtf)|*.rtf”;
    saveDiag.FilterIndex = 1;


    if (saveDiag.ShowDialog() == DialogResult.OK)
    {
        DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();
        ReportDocument rptDoc = (ReportDocument)crystalReportViewer1.ReportSource;
        ExportOptions crExportOptions = rptDoc.ExportOptions;
        crDiskFileDestinationOptions.DiskFileName = saveDiag.FileName;
        crExportOptions.ExportDestinationOptions = crDiskFileDestinationOptions;
        crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;


        switch (saveDiag.FilterIndex)
        {
            case 1: // pdf
                crExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
                break;
            case 2: // xls
                crExportOptions.ExportFormatType = ExportFormatType.Excel;
                break;
            case 3: // xls
                crExportOptions.ExportFormatType = ExportFormatType.ExcelRecord;
                break;
            case 4: // doc
                crExportOptions.ExportFormatType = ExportFormatType.WordForWindows;
                break;
            case 5: // rtf
                crExportOptions.ExportFormatType = ExportFormatType.RichText;
                break;


        }
        rptDoc.Export(crExportOptions);
    }

Ibon Landa

bon Landa lleva más de 15 años dedicado al desarrollo de software. Durante este tiempo ha trabajado en diferentes empresas en las cuáles ha podido trabajar en diferentes entornos y tecnologías. Actualmente está focalizado principalmente en tareas de desarrollo, arquitectura, en las herramientas del ciclo de vida y en todo lo relacionado con la plataforma de Cloud Computing Microsoft Azure, área en el que ha sido reconocido como MVP. Participa de forma activa en la comunidad, escribiendo su blog, manteniendo un portal sobre Microsoft Azure y colaborando con Microsoft y grupos de usuarios en eventos de formación, talleres y giras de producto.

9 comentarios en “Personalizando el botón exportar del visor de Crystal Report”

  1. Hola, que tal.
    Realmente es interesante lo que haz realizado.
    Deseo hacer algo parecido, pero en VB 6
    lo que necesito es con el boton imprimir de crystal mandarlo a una funcion dentro de mi codigo y hacer mi propia impresion.
    Di me puedes ayudar te lo agradecere

    Gracias.

  2. Pues casi, casi es lo mismo que he hecho con el botón de exportar, pero sustituyendo el botón de imprimir de crystal por el tuyo propio y en lugar de llamar a exportar llamar al método PrintToPrinter de ReportDocument.

    En el código que pongo busco el botón de exportar y lo sustituyo. (…. && tsi.ImageIndex == 8) Tú en lugar del 8 tendrías que buscar el que le corresponde al botón de imprimir.

    Una vez que va a tu código creas el objeto ReportDocument tal y como lo hago en el ejemplo. Esta clase te ofrece métodos para imprimir los informes;PrintToPrinter.

    http://msdn.microsoft.com/en-us/library/aa691452(VS.71).aspx

  3. muy buena ayuda para los que recien estamos empezando, mira el problema que yo tengo, es que necesito crear el informe y guardarlo pero sin visualizar el mismo, por lo que vi en la Web se puede hacer de esta manera pero tb crear un pdf y guardarlo directamente alguna ayuda sobre esto, te lo agradeceria bastante ya que no me sale de ninguna de las dos formas
    gracias

  4. Hola, no sé cuál es número concreto que puedes probar a recorrar todos los valores y ver cuál es el del botón imprimir..

    foreach (ToolStripItem tsi in ts.Items)
    {
    if (tsi is ToolStripButton)
    {
    ToolStripButton crXb = (ToolStripButton)tsi;

    usas crXb.Text para ver cuál es el de imprmiir
    y así saber su tsi.ImageIndex
    }
    }

  5. Gracias por toda tu ayuda y abusando un poco te pido ayuda para algo que estoy seguro te sera muy sencillo.

    Con el segundo link que pusiste ya logre que mi aplicacion genere el reporte y desde el puedo imprimir y toda la cosa todo funciona bien salvo por un detalle
    Cuando le doy click al boton de exportar no me funciona me dice

    “No export DLLs found”

    Ya le pegue dlls al por mayor y no me funciona ya hasta reinstale y nada. se me ocurrio tratar de hacerlo por codigo pero no tengo idea.

    Ya se que ahi esta tu codigo pero yo tengo VB6 y como ya dijiste no lo manejabas así que mi pregunta es sabes porque no funciona el boton exportar desde el reporte (mencione que uso Cristal XI)

    Mi correo es pumadanny@gmail.com

  6. Gracias excelente aporte yo tenia el report document directo al crystal report con un store procedure . ahora mejore la aplicacion mostrando primero el cuadro de exportación.
    claro esto sirve dependiendo de las opciones que uno necesite.

    public void Export_Click()
    {
    SaveFileDialog saveDiag = new SaveFileDialog();
    saveDiag.Title = “Exportar Informe”;
    saveDiag.Filter = “Adobe Acrobat (*.pdf)|*.pdf|Microsoft Excel (*.xls)|*.xls|Sólo datos de Microsoft Excel (*.xls)|*.xls|Microsoft Word (*.doc)|*.doc|Formato de texto enriquecido (*.rtf)|*.rtf”;
    saveDiag.FilterIndex = 1;

    if (saveDiag.ShowDialog() == DialogResult.OK)
    {

    DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();
    ParameterField PF = new ParameterField();
    ParameterDiscreteValue PD = new ParameterDiscreteValue();
    ParameterFields PFS = new ParameterFields();

    PF.CurrentValues.Add(PD);
    PFS.Add(PF);

    PF.Name = “@Sector”;
    PD.Value = cboSector.SelectedValue;

    FSADRZONA_1060 zona = new FSADRZONA_1060 ();
    zona.crwZonas.ParameterFieldInfo = PFS;
    clsStoreZona listar = new clsStoreZona();
    rpListarZonas rp_zonas = new rpListarZonas ();
    rp_zonas.SetDataSource(listar.ListarZonapara (Convert.ToString(cboSector.SelectedValue)));
    zona.crwZonas.ReportSource = rp_zonas;
    ReportDocument oREP = (ReportDocument)zona.crwZonas.ReportSource;
    ExportOptions crExportOptions = oREP.ExportOptions;
    crDiskFileDestinationOptions.DiskFileName = saveDiag.FileName;
    crExportOptions.ExportDestinationOptions = crDiskFileDestinationOptions;
    crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;

    switch (saveDiag.FilterIndex)
    {
    case 1: // pdf
    crExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
    break;
    case 2: // xls
    crExportOptions.ExportFormatType = ExportFormatType.Excel;
    break;
    case 3: // xls
    crExportOptions.ExportFormatType = ExportFormatType.ExcelRecord;
    break;
    case 4: // doc
    crExportOptions.ExportFormatType = ExportFormatType.WordForWindows;
    break;
    case 5: // rtf
    crExportOptions.ExportFormatType = ExportFormatType.RichText;
    break;

    }
    oREP.Export(crExportOptions);
    }
    }

    deberas que gran ayuda.

  7. o tambien controlando en datatable en caso de que no haya registros en la consulta.
    public void Export_Click()
    {

    ParameterField PF = new ParameterField();
    ParameterDiscreteValue PD = new ParameterDiscreteValue();
    ParameterFields PFS = new ParameterFields();
    PF.CurrentValues.Add(PD);
    PFS.Add(PF);

    PF.Name = “@Sector”;
    PD.Value = cboSector.SelectedValue;

    FSADRZONA_1060 zona = new FSADRZONA_1060();
    zona.crwZonas.ParameterFieldInfo = PFS;
    clsStoreZona listar = new clsStoreZona();
    rpListarZonas rp_zonas = new rpListarZonas();
    DataTable dt = new DataTable();
    dt = listar.ListarZonapara(Convert.ToString(cboSector.SelectedValue));
    if (dt.Rows.Count > 0)
    {
    SaveFileDialog saveDiag = new SaveFileDialog();
    saveDiag.Title = “Exportar Informe”;
    saveDiag.Filter = “Adobe Acrobat (*.pdf)|*.pdf|Microsoft Excel (*.xls)|*.xls|Sólo datos de Microsoft Excel (*.xls)|*.xls|Microsoft Word (*.doc)|*.doc|Formato de texto enriquecido (*.rtf)|*.rtf”;
    saveDiag.FilterIndex = 1;

    if (saveDiag.ShowDialog() == DialogResult.OK)
    {

    DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();
    rp_zonas.SetDataSource(listar.ListarZonapara(Convert.ToString(cboSector.SelectedValue)));
    zona.crwZonas.ReportSource = rp_zonas;
    ReportDocument oREP = (ReportDocument)zona.crwZonas.ReportSource;
    ExportOptions crExportOptions = oREP.ExportOptions;
    crDiskFileDestinationOptions.DiskFileName = saveDiag.FileName;
    crExportOptions.ExportDestinationOptions = crDiskFileDestinationOptions;
    crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;

    switch (saveDiag.FilterIndex)
    {
    case 1: // pdf
    crExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
    break;
    case 2: // xls
    crExportOptions.ExportFormatType = ExportFormatType.Excel;
    break;
    case 3: // xls
    crExportOptions.ExportFormatType = ExportFormatType.ExcelRecord;
    break;
    case 4: // doc
    crExportOptions.ExportFormatType = ExportFormatType.WordForWindows;
    break;
    case 5: // rtf
    crExportOptions.ExportFormatType = ExportFormatType.RichText;
    break;

    }
    oREP.Export(crExportOptions);
    MessageBox.Show(“Exportación Finalizada”, “Exportar Informe”, MessageBoxButtons.OK, MessageBoxIcon.Information);
    limpiar();
    }

    }
    else

    { MessageBox.Show(“No Se Encontraron registros resultantes”, “Aviso”, MessageBoxButtons.OK, MessageBoxIcon.Information ); }
    }

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *