废话不说,直接上干货
1,在VS2010.NET中想要使用CrystalReport Viewer 13.0 必须先去SAP官网下载免费的插件:CRforVS_13_0_3.exe。
2,用Visual C#新建一个WinForm,在工具栏--组件--右击“选择项...”在出现的一堆列表中选择
3,在IDE的菜单上方,选择XXX项目--属性--目标框架。可能是从原来的“.NET Framework 4 Client Profile”→“.NET Framework 4”
4,更改项目的app.config内的内容,如下:
<?xml version="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>5,基本工作结束了,接下来是如何动态显示你的水晶报表
水晶报表是一开始就利用Crystal Report 2008绑定XML为数据源做好的模板.rpt,而XML则是需要动态加载的。
重载下窗体的Load函数:
private void crystalReportViewer1_Load(object sender, EventArgs e) { //获取和设置包含该应用程序的目录的名称 result: X:\xxx\xxx\ (.exe文件所在的目录+"\") string dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; string iniFilePath = dir+"CrystalRepoConfig.ini"; ReadIniFile iniFile = new ReadIniFile(iniFilePath); bool isExist = iniFile.ExistINIFile(); if (!isExist) { System.Windows.Forms.MessageBox.Show("配置文件路径不正确:" + iniFilePath); return; } bool hasPath = iniFile.ValueExists("CrystalReport", "DatafilePath"); if (!hasPath) { System.Windows.Forms.MessageBox.Show("配置文件CrystalRepoConfig.ini中对应样品文件路径不正确"); return; } hasPath = iniFile.ValueExists("CrystalReport", "TemplatePath"); if (!hasPath) { System.Windows.Forms.MessageBox.Show("配置文件CrystalRepoConfig.ini中对应报表文件路径不正确"); return; } string xmlfilePath = iniFile.ReadValue("CrystalReport", "DatafilePath"); string templatePath = iniFile.ReadValue("CrystalReport", "TemplatePath"); ; System.Windows.Forms.MessageBox.Show("报表打开中…请稍等"); ReportDocument rd = new ReportDocument(); rd.Load(templatePath); DataSet ds = new DataSet(); ds.ReadXml(xmlfilePath); rd.SetDataSource(ds); this.crystalReportViewer1.ReportSource = rd; this.crystalReportViewer1.RefreshReport(); } }代码中的核心语句也就最后的7句,新建一个dataset的实例,即XML,传入路径并加载。新建一个水晶报表的实例,即rpt文件,传入路径并加载。最后绑定到Viewer上并显示。
而路径的加载选用了轻便的ini配置文件
public class ReadIniFile { public string FileName; //INI文件名 //声明读INI文件的API函数 [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath); [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); public ReadIniFile(string INIPath) { FileName = INIPath; } public string ReadValue(string section, string key) { StringBuilder strBuffer = new StringBuilder(255); int bufLen = GetPrivateProfileString(section, key, "", strBuffer, strBuffer.Capacity, FileName); return strBuffer.ToString(); } private void GetStringsFromBuffer(Byte[] Buffer, int bufLen, StringCollection Strings) { Strings.Clear(); if (bufLen != 0) { int start = 0; for (int i = 0; i < bufLen; i++) { if ((Buffer[i] == 0) && ((i - start) > 0)) { String s = Encoding.GetEncoding(0).GetString(Buffer, start, i - start); Strings.Add(s); start = i + 1; } } } } //从Ini文件中,将指定的Section名称中的所有Ident添加到列表中 public void ReadSection(string Section, StringCollection Idents) { Byte[] Buffer = new Byte[16384]; //Idents.Clear(); int bufLen = GetPrivateProfileString(Section, null, null, Buffer, Buffer.GetUpperBound(0), FileName); //对Section进行解析 GetStringsFromBuffer(Buffer, bufLen, Idents); } //检查某个Section下的某个键值是否存在 public bool ValueExists(string Section, string Ident) { StringCollection Idents = new StringCollection(); ReadSection(Section, Idents); return Idents.IndexOf(Ident) > -1; } // 验证文件是否存在 public bool ExistINIFile() { return File.Exists(FileName); } }