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:
- Buscar una referencia al control de exportar que viene por defecto.
- Crear un botón nuevo y copiar las propiedades.
- Añadir el nuevo botón a la barra.
- Incluir un manejador del evento «Click» para el nuevo botón.
- Ocultar el botón de exportar por defecto.
- 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);
}
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.
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
Perdón, preguntabas por VB6…no VB.NET…Aquí me pillas porque casi no hice nada con VB6.
Lo único que puede ponerte es algún enlace por si te puede ayudar.
http://www.elguille.info/colabora/vb/jnieto_CRYSTAL.HTM
http://www.elguille.info/vb/crystal/crystalDanielMaya.htm
Un saludo,
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
Perdon, pero he buscado el indice del boton Imprimir y no lo he podido encontrar. ¿Alguien sabe cual es este indice?
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
}
}
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
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.
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 ); }
}