首页 新闻 会员 周边

在MVC中将RDLC的二进制流数据通过RenderAction显示到页面上面

0
[已解决问题] 解决于 2012-04-01 17:44
public static class HotelReport
{
public static byte[] GenerateReport(string dtatSetName, IEnumerable dataSource,
                          string reportFilePath,string reportType, out string mimeType, 
                           out string encoding, out string fileNameExtension)
{
//报表数据源
ReportDataSource reportDataSource = new ReportDataSource(dtatSetName, dataSource);
//本地化报表
LocalReport localReport = new LocalReport();
localReport.ReportPath = reportFilePath;
localReport.DataSources.Add(reportDataSource);

string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>" + reportType + "</OutputFormat>" +
" <PageWidth>8.5in</PageWidth>" +
" <PageHeight>11in</PageHeight>" +
" <MarginTop>0.5in</MarginTop>" +
" <MarginLeft>1in</MarginLeft>" +
" <MarginRight>1in</MarginRight>" +
" <MarginBottom>0.5in</MarginBottom>" +
"</DeviceInfo>";

Warning[] warnings;
string[] streams;
byte[] renderedBytes;

renderedBytes = localReport.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);

return renderedBytes;
}
}

上面是用于将RDLC报表转换为二进制数据的方法。

下面的ReporesRelsult用于将这种数据写到输出当中

    public class ReportsResult : ActionResult
{
public ReportsResult(byte[] data, string mineType)
{
this.Data = data;
this.MineType = mineType;
}

public byte[] Data { get; set; }
public string MineType { get; set; }

public override void ExecuteResult(ControllerContext context)
{
if (Data == null)
{
new EmptyResult().ExecuteResult(context);
return;
}
context.HttpContext.Response.ContentType = MineType;

using (MemoryStream ms = new MemoryStream(Data))
{
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
context.HttpContext.Response.Output.Write(sr.ReadToEnd());
}
}
}
}

下面是控制器的action方法:

public ActionResult EmployeesNumberPerYear()
{
string dtatSetName = "DsENPerYear";
var dataSource = EmployeeReports.EmployeesNumberPerYear(employeeRepository);
string reportFilePath = Server.MapPath("~/RDLC/Employee/EmployeesNumberPerYear.rdlc");
string reportType = "PDF";

string mimeType;
string encoding;
string fileNameExtension;

byte[] renderedBytes = HotelReport.GenerateReport(dtatSetName, dataSource, reportFilePath,
reportType, out mimeType, out encoding, out fileNameExtension);
return new ReportsResult(renderedBytes, mimeType);
}

以及html的调用:

<div>
@{
Html.RenderAction("EmployeesNumberPerYear", "EmployeeReports");
}
</div>

其实问题就在于扩展的ActionResult,怎样将报表生成的RDLC转换过的二进制数据通过HttpContext来进行输出,并且RenderAction能够正确的显示出预览。

另外要说明的是,如果直接通过连接或url访问该action,excel的格式会直接用于保存,pdf的会显示出来。但我想让数据以预览的形式展示到div当中。



凡一二三的主页 凡一二三 | 初学一级 | 园豆:85
提问于:2012-04-01 11:11
< >
分享
最佳答案
0

EmployeesNumberPerYear是通过Ajax调用的吗?

奖励园豆:5
dudu | 高人七级 |园豆:31007 | 2012-04-01 15:12

不是的,那是一个类使用传人的IRespository来返回一个IList,因为在做RDLC报表的时候,必须有个提供IList类型的数据的方法。因为直接用控制器中的action,RDLC视图设计时找不到。

public class EmployeeReports
{
//获取每年员工的数量
public static IList<EmployeesNumberPerYear> EmployeesNumberPerYear(
IEmployeeRepository employeeRepository)
{
var enc = from e in employeeRepository.GetAll().AsQueryable()
group e by e.JoinTime.Year into g
select new EmployeesNumberPerYear
{
Year = g.Key,
Number = g.Count()
};
return enc.ToList();
}
}
///<summary>
/// 保存每个年份的员工数量
///</summary>
public class EmployeesNumberPerYear
{
public int Year { get; set; }
public int Number { get; set; }
}
凡一二三 | 园豆:85 (初学一级) | 2012-04-01 15:16

@远离尘世的理想乡: "想让数据以预览的形式展示到div当中",这个预览形式的数据是通过Ajax获取的吗?

dudu | 园豆:31007 (高人七级) | 2012-04-01 15:22

@dudu: 我想通过Html.RenderAction来呈现,不管怎样现在只要能以预览形式呈现就行了。

凡一二三 | 园豆:85 (初学一级) | 2012-04-01 15:26

@dudu: dudu大侠要不我发一份给你看看啊,可能我的代码入不了你的法眼啊。

凡一二三 | 园豆:85 (初学一级) | 2012-04-01 15:31

@远离尘世的理想乡: 

试试iframe:

<div>
<iframe src="EmployeesNumberPerYear的url"></iframe>
</div>

如果不用iframe,你先要解决如何在div中加载流文件的问题。

dudu | 园豆:31007 (高人七级) | 2012-04-01 15:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册