水晶报表的打印

开发工具与关键技术:vs asp.net mvc
作者:邹志深
撰写时间:2019.5.2
下面让我来给大家讲解下我对水晶报表的打印的了解;我对打印水晶报表进行分了好几个步骤,接下来就让我来给大家讲下打印水晶报表的第一步,先在页面写一些与水晶报表相关的代码;如下图:
水晶报表的打印
上图就是我在写水晶报表的第一步,也就是在页面上写一个方法来装水晶报表,上图的第二行那里是给别人的提示,然后再写一个方法来获取水晶报表在控制器那边写的代码图中的layer.close(layIndex)这里的意思是当你点击确定之后关闭提示框,window.open()括号里面放的是路径与变量,路径是放在双引号中间的而问号是拼接的意思,strConditions:这个是
全局变量来的,你要查询的数据的id赋值给strConditions这个变量而且这个名字是可以随便起的。这样他的第一步就完成了。
那么接下来就是水晶报表的第二步数据查询和条件筛选,这第二步的代码是在控制器那边的写的,在控制器的那边先创建一个类在类里面传进你要打印的参数也就是id,如我这里是打印学生的毕业证书的那么我就要在括号里传进学院id、年级id、和班级id来查询学生的信息再来打印证书。如下面的代码:
public ActionResult PrintAchievement(int AcademeID, int GradeID, int ClassID)
这就是新建一个类开头要的代码而括号里就是我们打印什么而写的变量,那么接下来就是查询数据了如下图:
水晶报表的打印
上图的意思是新建一个列表来装你要的数据,如上图就是新建一个成绩列表来装数据库中的你想要的数据。上图的意思是建立一个名字为listAchievement的表来装数据库中的成绩表的数据,图中的group by 是分组查询的意思而 group tbAchievement by tbAchievement.UserID into tbStudent:的意思是根据tbAchievement这张表的UserID进行分组查询命名为tbStudent,key:是进行分组的关键字段,然后就是给listAchievement里面你要的元素赋值,图中的赋值是用Lambda表达式来赋值的如:
AchievementID=tbStudent.OrderByDescending(m=>m.Achievement).FirstOrDefault().AchievementID == 》这就是Lambda表达式的写法 OrderByDescending:这是排序,FirstOrDefault:返回第一个值,整句代码的意思就是对成绩进行降序的排序,返回一个最高的值,如1、2、3的OrderByDescending:降序就是3、2、1,而FirstOrDefault:返回第一个值也就是最大的那个数字:3这样就可以提取最大的成绩的id了。
Achievement=tbStudent.OrderByDescending(m=>m.Achievement).FirstOrDefault().Achievement == 》这句代码是对成绩进行降序的排序,然后提取最高成绩的那个成绩。
ExamNumber=tbStudent.OrderByDescending(m=>m.ExamNumber).FirstOrDefault().ExamNumber== 》这句代码的意思是对考试序号进行降序排序提取最后,提取考试最多序号的那一个。
EligibleTypeID=tbStudent.OrderByDescending(m=>m.Achievement).FirstOrDefault().EligibleTypeID == 》这句代码的意思是对合格类型进行降序的排序,因为合格类型是根据成绩来进行排序的成绩越高就越到后面所以对它进行降序排序后就排第一了所以是提取成绩最高的那一次的合格类型。给上面的代码赋值后接下来就是查询代码了如下图;
水晶报表的打印
上图就是对查询了而且还是多表查询主要连接了三张表格,如何看的懂是连接几张表呢这是有一个办法的你只要看有多少join就行了,图中就是连接了三张表分别是:PW_Student、SYS_Class和SYS_EligibleType这三张表在这里这三张表分别是学生表、班级表和合格类型表注意list< AchievementVo >这尖括号里面得AchievementVo是要新建一个类的而且还要继承成绩表才可以,如: public class AchievementVo : PW_Achievement 这是开头的第一句而且继承的那里就是冒号那也就是:AchievementVo : PW_Achievement这样就是继承了。然后就是写PW_Achievement这张表里面没有的属性写法如下:
public string StudentNumber { get; set; } == 》这是学生的学号也就是成绩表里面没有的属性把它们一一写进去,这里还有:StudentName、StudentSex、Class、EligibleType、StartTime、AcademeID、GradeID、ClassID也就是学生姓名、性别、班级、合格类型、考试开始时间、学院ID、年级ID和班级ID把他们像上面那句代码那样写进去。注意:数字的变量用int类型,有文字的变量用string类型,ID如果允许为空的变量用 ?int类型也就是int32类型而这里的id都是允许为空的所以用 ?int的类型如AcademeID是像下面的那样写:
public int? AcademeID { get; set; } 这样就可以了,接下来就是讲一下这张图的第一句代码的意思:from tbAchievement in listAchievement == 》也就是从listAchievement这张列表中命名为tbAchievement开始查询的意思,下面就是进行连表查询然后就是根据图中命名为tbAchievement这张表的成绩进行降序来查询最后就是给新建类里面的属性进行赋值也就是给AchievementVo里面的元素赋值,注意:AchievementVo这个类里面的元素进行赋值时在哪张表的就要在那张表的元素如:StudentNumber = tbStudent.StudentNumber 学号是在tbStudent这张表的就要像上面那句例子来写就可以了。接下来就是判断刷选了如下:
if (AcademeID > 0){
listResult = listResult.Where(m => m.AcademeID == AcademeID).ToList();
} == 》这里的意思是如果AcademeID > 0 那么就让listResult这张表的条件是listResult这张表的AcademeID等于页面传过来的AcademeID;
if (GradeID > 0){
listResult = listResult.Where(m => m.GradeID == GradeID).ToList();
} == 》这里的意思是如果GradeID > 0 那么就让listResult这张表的条件是listResult这张表的GradeID等于页面传过来的GradeID;
if (ClassID > 0){
listResult = listResult.Where(m => m.ClassID == ClassID).ToList();
} == 》这里的意思是如果ClassID > 0那么就让listResult这张表的条件是listResult这张表的ClassID等于页面传过来的AcademeID;这样数据查询和条件筛选就可以了。
接下来就到了第三步了如下面的代码:
DataTable dtResult = LINQToDataTable (listResult); == 》这里的意思是将查询出来的数据转化为DataTable的格式赋值给dtResult:是可以随便命名的。
这里的LINQToDataTable它是一个方法需要新建一个类如下图:
水晶报表的打印
这图就是名为LINQToDataTable新建类它的意思是:新建一个类型为DataTable类型的类其命名为LINQToDataTable< T > :尖括号里面的T是个参数来的;而DataTable dtReturn = new DataTable(); 这句代码的意思是返回的DataTable对象其命名为dtReturn;PropertyInfo[] oProps = null;这一句代码的意思是:保存列集合的属性信息数组先赋值数组为空。然后就是判断varlist是否等于空如果是的话就继续下一步到了返回dtReturn,接下来就是遍历循坏了把varlist赋值给T然后判断oProps是否等于空是的话就给oProps赋值然后就是遍历循坏PropertyInfo数组,取到colType的类型然后判断属性是否为为泛型类型,如果是就获取泛型类型的参数:colType = colType.GetGenericArguments()[0];也就是给colType赋值接下来就是将类型的属性名称与属性类型作为DataTable的列数据;然后新建一个用于添加 DataTable中的DataRow对象也就是DataRow dr = dtReturn.NewRow();然后就是循环遍历属性集合之后就是为DataRow中的指定列赋值也就是:dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);这一句代码。将具有结果值的DataRow添加到DataTable集合中:dtReturn.Rows.Add(dr);最后返回DataTable对象这样这个新建类就完成了。
接下来就是PrintReport.ReportDB dbReport = new PrintReport.ReportDB(); == 》这句代码的意思是实例化数据集dbReport;而下一句代码是:
dbReport.Tables[“tbAchievement”].Merge(dtResult);== 》它的意思是将dtResult放入数据集中名为“tbAchievement”的表格中;
PrintReport.AchievementReport rp = new PrintReport.AchievementReport(); == 》这句代码的意思是:实例化数据报表命名为rp;
那么接下来就是获取文件的物理路径了如;string strRpPath = Server.MapPath("~/") + “Areas\ExaminationManagement\PrintReport\AchievementReport.rpt”;那么下一句代码是:rp.Load(strRpPath); == 》将报表加载到报表模板中。接下来就是:
rp.SetDataSource(dbReport); == 》它的意思是设置报表的数据源。下面那句代码就是最后就是这一句代码,它的意思是:将报表转化为文件流输出Stream dbStream = rp.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
最后就是返回数据:return File(dbStream, “application/pdf”);这样水晶报表的打印就完成了。