一个 Devexpress 报表 分 部门打印 的实例 (一)
需要的工具如下
1 DXperience
2 VS2008和 LINQ
部门 Department has many 设备(Equipment), 商品 DataSource
实现:给定上面的数据,得ID号,将商品数据传送给 对应厨房Report ,并打印。
1 那首先是报表程序
安装完Devexpress之后,添加一个Winform或者 web application
(注:devexpress的web站点和web application ,winform的Report文件格式不同)
在“解决方案资源管理器添加 XtraReport文件。命名kitchen,看到了添加引用,其中本例子用不到charts和pivotGrid
详细的部署条件看这里的Redistributable Assemblies
在pageheader里添加8个xrlabel 重命名其ID和text属性(如图)
lbl_订单号 订单号 txt_订单号 text属性留空 以此类推
在KitchenDesigner.cs 文件里粘帖如下2个方法
//输入xrlabel的id,和要赋给该label的Datatable的列名string类型(来自于datatable)
publicvoid BindXRLabel(string xrLabelID, string bindingMember)
{
XRLabel xrLabel = (XRLabel)FindControl(xrLabelID, true);
xrLabel.DataBindings.Add("Text", DataSource, bindingMember);
}
//同上但为 string类型,
publicvoid BindXRLabelByText(string xrLabelID, string text)
{
XRLabel xrLabel = (XRLabel)FindControl(xrLabelID, true);
xrLabel.Text = text;
}
再次添加一个方法 GetKtchenReportSource()
//该方法为厨房报表赋值 (还是喜欢将这个方法放在kitchen report类里)
public static Kitchen GetKtchenReportSource(DataTable table)
{
Kitchen _Kitchen = new Kitchen();
_Kitchen.DataSource = table;
_Kitchen.BindXRLabel("txt_订单号", "订单号"); //再次注意这里指table的列名
_Kitchen.BindXRLabel("txt_商品名称", "商品名称");
_Kitchen.BindXRLabel("txt_部门名称", "部门名称");
_Kitchen.BindXRLabel("txt_设备名称", "设备名称");
return _Kitchen;
}
(这里以web Application为例),新建ASPX页面。
编写代码获取数据源调用并打印,这里使用LINQ(切换到2008)
1 添加DBML文件(Linq To Sql Classes),导入三个表, 添加关系如图
部门 Department 和( 设备(Equipment) 商品 DataSource)的assocation都是 department_id
实现文章最上的视图如下语句:(LINQ的JOIN学起来真够累的,要是有工具可以像查询分析器那样写多表join)使用LINQ进行多表操作(二)不知道用Lamba 表达式怎么写了
var query = from departmentInfo in db.Department_Infos
join datasource in db.DataSources
on departmentInfo.Department_ID
equals datasource.Department_Id into deps
join equipment in db.Equipment_Infos
on departmentInfo.Department_ID equals equipment.Equipment_DPID into equips
from c in equips.DefaultIfEmpty()
from d in deps.DefaultIfEmpty()
select new
{
订单号=d.orderFormId,
商品名称=d.MS_Name,
部门名称=departmentInfo.Department_Name,
设备名称=c.Equipment_Name
};
生成的SQL如下:和视图一样
SELECT t2.orderFormId AS订单号, t2.MS_Name AS商品名称,
t0.Department_Name AS部门名称, t1.Equipment_Name AS设备名称
FROM dbo.Department_Info AS t0 LEFTOUTERJOIN
dbo.Equipment_Info AS t1 ON
t0.Department_ID = t1.Equipment_DPID LEFTOUTERJOIN
dbo.DataSource AS t2 ON t0.Department_ID = t2.Department_Id
注意:偷懒这样写生成的SQL语句就有问题了
var query = from departmentInfo in db.Department_Infos.DefaultIfEmpty()
join datasource in db.DataSources.DefaultIfEmpty()
on departmentInfo.Department_ID
equals datasource.Department_Id
join equipment in db.Equipment_Infos.DefaultIfEmpty()
on departmentInfo.Department_ID equals equipment.Equipment_DPID
select new
{
订单号 = datasource.orderFormId,
商品名称 = datasource.MS_Name,
部门名称=departmentInfo.Department_Name,
设备名称 = equipment.Equipment_Name
};
现在有了数据源了,可以将LINQ生成的结果集转换为datatable 给report赋值了,
首先添加一个对LINQ TO DATSET的引用
DataTable table = DataTableExtensions.CopyToDataTable(query);
编译执行出错
Error 1 The type 'AnonymousType#1' cannot be used as type parameter 'T' in the generic type or method 'System.Data.DataTableExtensions.CopyToDataTable<T>(System.Collections.Generic.IEnumerable<T>)'. There is no implicit reference conversion from 'AnonymousType#1' to 'System.Data.DataRow'.
查博客园大部分讲datatable都没有说到这个问题,结果到了
How to: Implement CopyToDataTable<T> Where the Generic Type T Is Not a DataRow
原来微软没有实现泛型类不为DataRow的情况啊,人家subsonic开源项目都有executedataset方法。好吧复制那个类,修改一下。
DataTable table = new DataTable();
CustomLINQtoDataSetMethods.CopyToDataTable(query, table, LoadOption.PreserveChanges);
通过编译。
那么new 一个kitchen Report开始打印。
Kitchen.Kitchen kitchen = Kitchen.Kitchen.GetKtchenReportSource(table);
kitchen.Print("Foxit PDF Printer"); //这里用了Foxit Creator这款虚拟打印机。他在控制面板里的名字是Foxit PDF Printer
运行,就会看到跳出框保存,保存PDF(虽然Devexpress其实自带导出PDF功能了)就会看到生成的report了。(结果很可能和真实打印机不一样)