之前本人写过一篇Blog《ReportingService统计已打印标志》 ,大致解决了客户端统计打印报表的功能。
虽不十分完美,但具有实际可操作性。并在项目中得到了应用。在最近项目中应用了ReportingService生成各种不同
形式的文件,将使用心的分享给大家。
很多时候,用户需要生成导出文件(xls,pdf等)。生成文件有很多方法,比喻excel application或者StreamWriter流文件生成。
但是一旦用户需要发生更改,加字段、合并行列等。我们需要重新修改代码(有时改动比较复杂),编译版本,重新发布。
如果采用ReportingService方式,则很容易解决此类问题,只需修改报表文件(rdl),而且部署简单,并且和业务系统的耦合度大为降低,
也降低了系统风险。
如何制作报表文件不属于本文范围,为了直观形象说明问题,给出一张报表贴图如下:
|
Carrier Name: |
KAWASAKI KISEN KAISHA, LTD |
||||||||
|
Shipper Name: |
Maersk Logistics SHENZHEN on behalf of Shipper |
||||||||
|
Consignee Name: |
HOME DEPOT USA INC |
||||||||
|
Mlog Contractual Party: |
HOME DEPOT USA INC |
||||||||
|
Service Mode: |
CY/CY |
||||||||
|
Commodity: |
FURNITURE |
||||||||
|
Shipping Marks: |
|
||||||||
|
Service Contract#: |
16095 |
||||||||
|
Feeder Name: |
|
||||||||
|
Feeder Voyage: |
|
||||||||
|
Feeder ETD: |
|
||||||||
|
Feeder Load Port: |
|
||||||||
|
Feeder Discharge Port |
|
||||||||
|
Mother Vessel Name: |
COSCO DALIAN 0042E |
||||||||
|
Mother Vessel Voy: |
THD |
||||||||
|
Mother Vessel ETD: |
2009-03-07 |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
Container Type |
Remarks |
KGS |
CBM |
Carrier S/O |
MODS SO |
PO NO |
Additional Service |
|
|
|
1*40DRY |
|
10000 |
56 |
|
|
55193434 |
|
|
|
|
1*45HIGH |
|
10000 |
56 |
|
|
55193431 |
|
|
|
|
1*45HIGH |
|
10000 |
56 |
|
|
55193432 |
|
|
|
一、如何生成?
1、添加引用Microsoft.ReportViewer.WebForms,并添加命名空间using Microsoft.Reporting.WebForms;
2、生成文件代码如下:
public string ReportToExcel(string id)
{
#region 获取文件流
string fileName = "C:\\test.xls";
byte[] bytes = null;
try
{
ReportParameter[] p = {
new ReportParameter("pBooking_No", id),
new ReportParameter("pCarrier_SO", ""),
new ReportParameter("pUserId", "CUS300"),
};
ReportViewer testRV = new ReportViewer();
testRV.ServerReport.ReportServerUrl = new Uri("http://192.168.2.80/reportserver");
testRV.ServerReport.ReportPath = "/New_RealtimeReport/ShipperReport_bkd";
//不允许匿名访问,设置权限
testRV.ServerReport.ReportServerCredentials = new CustomReportCredentials("Test", "Test", "http://192.168.2.80/");
testRV.ServerReport.SetParameters(p);
testRV.ServerReport.Refresh();
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension = "xls";
bytes = testRV.ServerReport.Render("Excel", null, out mimeType,
out encoding, out extension, out streamids, out warnings);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
#endregion
#region 生成文件
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
try
{
fs.Write(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
//LogHelper.ErrorFormat("GetOtherCarrierMailBySGH:{0}", ex.Message + ex.StackTrace.ToString());
}
finally
{
fs.Close();
}
#endregion
return fileName;
}
3、传入参数调用即可;
string id = "88f308bd-30e4-4799-bbd0-9ba400b71189";
string fileName = ReportToExcel(id);
二、权限问题
如果报表允许匿名访问,则不需要这行代码
testRV.ServerReport.ReportServerCredentials = new CustomReportCredentials("Test", "Test", "http://192.168.2.80/");
如果不允许匿名访问,则需要实现ReportServerCredentials 接口方法;代码如下:
public class CustomReportCredentials : Microsoft.Reporting.WebForms.IReportServerCredentials
{
// local variable for network credential.
private string _UserName;
private string _PassWord;
private string _DomainName;
public CustomReportCredentials(string UserName, string PassWord, string DomainName)
{
_UserName = UserName;
_PassWord = PassWord;
_DomainName = DomainName;
}
public WindowsIdentity ImpersonationUser
{
get
{
return null; // not use ImpersonationUser
}
}
public ICredentials NetworkCredentials
{
get
{
return new NetworkCredential(_UserName, _PassWord, _DomainName);
}
}
public bool GetFormsCredentials(out Cookie authCookie, out string user, out string password, out string authority)
{
authCookie = null;
user = password = authority = null;
return false;
}
}
三、扩展性
此种做法具有很好的扩展性,如业务中需要将多票不同业务合并在一起,我们在前台页面可以将业务id合并在一起,传入报表参数,
报表后台很容易解析。
浙公网安备 33010602011771号