水晶报表查看器CrystalReportViewer的ReportSource属性是object,目前对其赋值一般采用两种方式。第一种是采用返回ReportClass对象实例的方式,第二种是采用ReportDocument返回报表文件的方式。他们各有优劣。采用ReportClass oRpt = new ReportClass();的方式最终的发布方式可以不用报表文件(即后缀为*.rpt)的方式,这种方式的特定是加载很快,但是如果要修改报表文件的话就要打开工程修改编译后才能起作用。而第二种方式ReportDocument oRpt = new ReportDocument();则是根据路径加载了报表文件,可以独立修改报表文件,但是加载速度稍逊一筹。
下面是水晶报表开发中碰到的一些比较有用的代码,方便以后备忘,代码中都有备注:
private void frmReport_Load(object sender, EventArgs e)
{
ReplaceExportButton();
try
{
SuperReportFactory fa = new SuperReportFactory();
oRpt = fa.GetReportObject(ReportSort.Blood, printAllParam);
this.crViewer.ReportSource = oRpt;
this.crViewer.Zoom(2);
}
catch (Exception ex)
{
MessageBox.Show("报表数据异常:" + ex.Message +
"\r\n详细信息:" + "\r\n" + ex.StackTrace);
AppLogger.LogErrException("报表数据异常:", ex);
}
}
//水晶报表关闭同时卸载子报表,防止出现“report load fail”的错误
private void frmReportView_FormClosing(object sender, FormClosingEventArgs e)
{
if (oRpt != null)
{
if (oRpt.Subreports != null)
{
for (int i = 0; i < oRpt.Subreports.Count; i++)
{
oRpt.Subreports[i].Close();
oRpt.Subreports[i].Dispose();
}
}
oRpt.Close();
oRpt.Dispose();
oRpt = null;
}
crViewer.Dispose();
crViewer = null;
GC.Collect();
}
//自定义导出报表事件
private void CustomerExport_Click(object sender, EventArgs e)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "Adobe Acrobat (*.pdf)|*.pdf|Microsoft Word (*.doc)|*.doc|RTF 格式 (*.rtf)|*.rtf";
if (dlg.ShowDialog() == DialogResult.OK)
{
DiskFileDestinationOptions dfdo = new DiskFileDestinationOptions();
dfdo.DiskFileName = dlg.FileName;
oRpt.ExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
switch (dlg.FilterIndex)
{
case 1:
oRpt.ExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
break;
case 2:
oRpt.ExportOptions.ExportFormatType = ExportFormatType.WordForWindows;
break;
case 3:
oRpt.ExportOptions.ExportFormatType = ExportFormatType.RichText;
break;
default:
oRpt.ExportOptions.ExportFormatType = ExportFormatType.WordForWindows;
break;
}
oRpt.ExportOptions.DestinationOptions = dfdo;
oRpt.Export(); // 导出报表
MessageBox.Show("导出成功!", "导出报表", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
dlg.Dispose();
}
/// <summary>
/// 重写导出报表按钮
/// </summary>
private void ReplaceExportButton()
{
foreach (object ctl in crViewer.Controls)
{
string sControl = ctl.GetType().Name.ToString().ToLower();
if (sControl == "toolstrip")
{
ToolStrip tab1 = (ToolStrip)ctl;
for (int i = 0; i <= tab1.Items.Count - 1; i++)
{
if (tab1.Items[i].ToolTipText == "导出报表" || tab1.Items[i].ToolTipText == "Export Report")
{
ToolStripButton tbutton = new ToolStripButton();
Image img1 = tab1.Items[i].Image;
tab1.Items.Remove(tab1.Items[i]);
//设置新button属性
tbutton.Image = img1;
tbutton.ToolTipText = "AVE导出报表";
//在原位置上插入新Button
tab1.Items.Insert(0, tbutton);
//绑定自定义导出事件
tbutton.Click += new System.EventHandler(this.CustomerExport_Click);
break;
}
}
}
}
}
/// <summary>
/// 直接打印报表
/// </summary>
/// <param name="sort"></param>
/// <param name="paramHelper"></param>
public void PrintReportObject(ReportSort sort, PrintAllParam paramHelper)
{
try
{
ReportClass oRpt = GetReportObject(sort, paramHelper);
oRpt.PrintToPrinter(1, true, 1, 99999);
if (oRpt != null)
{
if (oRpt.Subreports != null)
{
for (int i = 0; i < oRpt.Subreports.Count; i++)
{
oRpt.Subreports[i].Close();
oRpt.Subreports[i].Dispose();
}
}
oRpt.Close();
oRpt.Dispose();
}
}
catch (Exception ex)
{
MessageBox.Show("报表异常:" + ex.Message);
AppLogger.LogErrException("报表数据异常:", ex);
}
}
/// <summary>
/// 设置报表表头对应的子报表数据
/// </summary>
/// <param name="ocRpt">子报表对象</param>
private void SetSubHeadData(ReportDocument ocRpt)
{
TextObject title = (TextObject)ocRpt.ReportDefinition.ReportObjects["txtHospitalName"];
title.Text = ParaHelper.uriPrintParam.HospitalName + "血常规检验报告单";
string fieldValues = string.Empty;
string fields = string.Empty;
string spStr = "|";
if (SickPrint.Rows.Count > 0)
{
if (SickPrint.Rows[0]["SickName"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.SickName}" + spStr;
fields += "姓名:" + spStr;
}
if (SickPrint.Rows[0]["SectionNum"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.SectionNum}" + spStr;
fields += "科别:" + spStr;
}
if (SickPrint.Rows[0]["InpatientNum"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.InpatientNum}" + spStr;
fields += "住院号:" + spStr;
}
if (SickPrint.Rows[0]["CheckDate"].ToString() == "True" ||
SickPrint.Rows[0]["CheckTime"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.CheckDate}" + spStr;
fields += "采样日期:" + spStr;
}
if (SickPrint.Rows[0]["Sex"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.Sex}" + spStr;
fields += "性别:" + spStr;
}
if (SickPrint.Rows[0]["SickbedNum"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.SickbedNum}" + spStr;
fields += "床号:" + spStr;
}
if (SickPrint.Rows[0]["UriSeqID"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.SickExamineID}" + spStr;
fields += "样液号:" + spStr;
}
if (SickPrint.Rows[0]["MedicalNum"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.MedicalNum}" + spStr;
fields += "病历号:" + spStr;
}
if (SickPrint.Rows[0]["Age"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.Age}" + spStr;
fields += "年龄:" + spStr;
}
if (SickPrint.Rows[0]["Result"].ToString() == "True")
{
fieldValues += "{SickBloodInfo.Result}" + spStr;
fields += "诊断:" + spStr;
}
}
string[] fldValueAry = fieldValues.Remove(fieldValues.Length - 1).Split(new string[] { spStr }, StringSplitOptions.None);
string[] fldAry = fields.Remove(fields.Length - 1).Split(new string[] { spStr }, StringSplitOptions.None);
for (int i = 1; i <= fldAry.Length; i++)
{
ocRpt.DataDefinition.FormulaFields["fld" + i].Text = "\"" + fldAry[i - 1] + "\"";
ocRpt.DataDefinition.FormulaFields["fldValue" + i].Text = fldValueAry[i - 1];
}
}
/// <summary>
/// 设置打印格式
/// </summary>
/// <param name="oRpt">当前要打印的主报表对象</param>
protected void SetPrintFormat(ReportDocument oRpt)
{
switch (GetPrintFormatCond())
{
case 0:
oRpt.PrintOptions.PaperSize = PaperSize.PaperA4;
break;
case 1:
oRpt.PrintOptions.PaperSize = PaperSize.PaperA5;
oRpt.PrintOptions.PaperOrientation = PaperOrientation.Landscape;
break;
case 2:
if (ParaHelper.printInstantType == "0")
{
oRpt.PrintOptions.PaperSize = PaperSize.PaperA4;
}
else if (ParaHelper.printInstantType == "1")
{
oRpt.PrintOptions.PaperSize = PaperSize.PaperA5;
oRpt.PrintOptions.PaperOrientation = PaperOrientation.Landscape;
}
break;
default:
oRpt.PrintOptions.PaperSize = PaperSize.PaperA4;
break;
}
}
/// <summary>
/// 设置A4模型一报表的图片信息
/// </summary>
/// <param name="ocRpt">模型一对应的图片子报表对象</param>
private void SetPictureInfoForA4T1(ReportDocument ocRpt)
{
int width = 3400; //每张图片的宽度
int height = 2550; //每张图片的高度
int vBlank = 60; //垂直方向图片间的间隔
int hBlank = 100; //水平方向图片间的间隔
int midLine = 5300; //模型一中,中线的位置
BlobFieldObject pic1 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic11"];
BlobFieldObject pic2 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic22"];
BlobFieldObject pic3 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic33"];
BlobFieldObject pic4 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic44"];
BlobFieldObject pic5 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic55"];
BlobFieldObject pic6 = (BlobFieldObject)ocRpt.ReportDefinition.ReportObjects["pic66"];
if (pic1 == null || pic2 == null || pic3 == null ||
pic4 == null || pic5 == null || pic6 == null)
{
MessageBox.Show("图形模板图形对象不存在,格式渲染失败。", "警告");
return;
}
if (GetIsPrintBmpCond() == 1)
{
#region 根据图片数不同,设置长宽变量的值
switch (GetPrintBmpNumCond())
{
case 1:
width = 5800;
height = 4350;
break;
case 2:
width = 4900;
height = 3675;
break;
case 4:
width = 3735;
height = 2800;
break;
case 3:
case 5:
case 6:
width = 3400;
height = 2550;
break;
}
#endregion
#region 根据图片数不同,设置图片的长和宽,左锚点和上锚点
switch (GetPrintBmpNumCond())
{
case 1:
pic1.Width = width;
pic1.Height = height;
pic1.Left = midLine - (pic1.Width / 2);
pic1.Top = vBlank;
break;
case 2:
pic1.Width = pic2.Width = width;
pic1.Height = pic2.Height = height;
pic1.Left = midLine - pic1.Width - hBlank;
pic2.Left = midLine + hBlank;
pic1.Top = pic2.Top = vBlank;
break;
case 3:
pic1.Width = pic2.Width = pic3.Width = width;
pic1.Height = pic2.Height = pic3.Height = height;
pic1.Left = midLine - (pic1.Width + hBlank + pic2.Width / 2);
pic2.Left = midLine - pic2.Width / 2;
pic3.Left = midLine + (pic2.Width / 2 + hBlank);
pic1.Top = pic2.Top = pic3.Top = vBlank;
break;
case 4:
pic1.Width = pic2.Width = pic3.Width = pic4.Width = width;
pic1.Height = pic2.Height = pic3.Height = pic4.Height = height;
pic1.Left = pic3.Left = midLine - pic1.Width - hBlank;
pic2.Left = pic4.Left = midLine + hBlank;
pic1.Top = pic2.Top = vBlank;
pic3.Top = pic4.Top = vBlank + pic1.Height + vBlank;
break;
case 5:
case 6:
pic1.Width = pic2.Width = pic3.Width = pic4.Width = pic5.Width = pic6.Width = width;
pic1.Height = pic2.Height = pic3.Height = pic4.Height = pic5.Height = pic6.Height = height;
pic1.Left = pic4.Left = midLine - (pic1.Width + hBlank + pic2.Width / 2);
pic2.Left = pic5.Left = midLine - pic2.Width / 2;
pic3.Left = pic6.Left = midLine + (pic2.Width / 2 + hBlank);
pic1.Top = pic2.Top = pic3.Top = vBlank;
pic4.Top = pic5.Top = pic6.Top = vBlank + pic1.Height + vBlank;
break;
default:
break;
}
#endregion
#region 根据图片数不同,设置图片的显示和隐藏属性
switch (GetPrintBmpNumCond())
{
case 1:
pic2.ObjectFormat.EnableSuppress = true;
pic3.ObjectFormat.EnableSuppress = true;
pic4.ObjectFormat.EnableSuppress = true;
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
break;
case 2:
pic3.ObjectFormat.EnableSuppress = true;
pic4.ObjectFormat.EnableSuppress = true;
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
break;
case 3:
pic4.ObjectFormat.EnableSuppress = true;
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
break;
case 4:
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
break;
case 5:
pic6.ObjectFormat.EnableSuppress = true;
break;
case 6:
break;
case 0:
default:
pic1.ObjectFormat.EnableSuppress = true;
pic2.ObjectFormat.EnableSuppress = true;
pic3.ObjectFormat.EnableSuppress = true;
pic4.ObjectFormat.EnableSuppress = true;
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
break;
}
#endregion
}
else
{
#region 不打印图片,设置图片长宽为0并隐藏
pic1.Top = pic2.Top = pic3.Top = pic4.Top = pic5.Top = pic6.Top = 0;
pic1.Left = pic2.Left = pic3.Left = pic4.Left = pic5.Left = pic6.Left = 0;
pic1.Width = pic2.Width = pic3.Width = pic4.Width = pic5.Width = pic6.Width = 0;
pic1.Height = pic2.Height = pic3.Height = pic4.Height = pic5.Height = pic6.Height = 0;
pic1.ObjectFormat.EnableSuppress = true;
pic2.ObjectFormat.EnableSuppress = true;
pic3.ObjectFormat.EnableSuppress = true;
pic4.ObjectFormat.EnableSuppress = true;
pic5.ObjectFormat.EnableSuppress = true;
pic6.ObjectFormat.EnableSuppress = true;
#endregion
LineObject line1 = (LineObject)ocRpt.ReportDefinition.ReportObjects["Line1"];
line1.ObjectFormat.EnableSuppress = true;
}
}
/// <summary>
/// 指定路径图片的二进制数组数据
/// </summary>
/// <param name="path">不带扩展名的完整图片路径</param>
/// <returns>返回图片的二进制数组数据</returns>
protected byte[] GetPictureData(string path)
{
byte[] bt;
string fileName = string.Empty;
string ext = string.Empty;
path = path.Trim();
ext = ".jpg";
fileName = path + ext;
if (!File.Exists(fileName))
{
ext = ".bmp";
fileName = path + ext;
}
if (!File.Exists(fileName))
{
return null;
}
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
bt = br.ReadBytes((int)fs.Length);
return bt;
}
/// <summary>
/// 判断字符串是否为数字,不包括负数
/// </summary>
/// <param name="value">传入的字符串</param>
/// <returns>为数字则返回true</returns>
public bool IsNumeric(string value)
{
return Regex.IsMatch(value.Trim(), @"^\d*[.]?\d*$");
}
/// <summary>
/// 返回报表文件的相对目录全路径用于采用ReportDocument方式加载路径的方式
/// </summary>
/// <param name="oRptName">不带后最的报表文件名</param>
/// <returns>返回报表文件的相对目录全路径</returns>
protected string GetSuperReportFullPath(string oRptName)
{
string fullPath = string.Empty;
if (!string.IsNullOrEmpty(oRptName))
fullPath = Environment.CurrentDirectory + @"\Report\" + oRptName + ".rpt";
else
throw new ArgumentNullException("报表文件名参数不能为空");
return fullPath;
}
///<summary>
/// 根据当前的打印参数获取对应的报表对象
/// </summary>
/// <returns>根据当前的打印参数获取对应的报表对象</returns>
public override ReportDocument GetCurrentReport()
{
//ReportClass oRpt = new ReportClass();
ReportDocument oRpt = new ReportDocument();
SuperUriDataSet ds = this.GetCurrentReportData();
//oRpt = new RptUriA4T1();
oRpt.Load(GetSuperReportFullPath("RptUriA4T1"));
this.SetSubHeadData(oRpt.Subreports["SubA4HeadLine.rpt"]);
this.SetSubFootData(oRpt.Subreports["SubA4FootNone.rpt"]);
this.SetPictureInfo(oRpt.Subreports["SubContPictT1.rpt"]);
this.FillOtherFields(oRpt, ds);
this.SetPrintFormat(oRpt);
oRpt.SetDataSource(ds);
return oRpt;
}