I have a web application that has a grid displaying a paged list of data to the user. The user needs the option to download the results to an Excel spreadsheet. However, the items displ开发者_StackOverflowayed in the grid are, like I said, Paged and I need the whole result set. In addition, I'm only displaying about 7 fields per item, whereas the spreadsheet will contain all 20+ fields for an item. So, I'm not looking for a grid-to-Excel solution.
I'm trying to do something that I've actually worked with before. At a previous employer (source code not available), we had an application that contained SQL Server report as an RDLC file. We would create a ReportViewer control in code (var reportViewer = new ReportViewer()). Then, we would bind the report to the control, give it a datasource and then render the results in whatever format we needed. In my case I need an Excel File, and then stream the ExcelFile back to the user in the response.
I'm using MVC3, so I'll be returning the Excel file as a FileContentResult. I've been searching the internet for a day and can't quite find what I'm looking for.
Controller action. The format parameter should be 'EXCEL'.
public FileResult Report(String format)
{
LocalReport report = new LocalReport();
report.ReportPath = Server.MapPath("~/TestReport.rdlc");
report.DataSources.Clear();
report.DataSources.Add(new ReportDataSource(GetData()));
report.Refresh();
return GetFileContentResult(report, format, null, "TestReport");
}
Helper method that creates a FileContentResult from any Report.
public FileContentResult GetFileContentResult(Report report, String format, String deviceInfo, String fileDownloadName)
{
String mimeType;
String encoding;
String filenameExtension;
String[] streamIds;
Warning[] warnings;
FileContentResult fileContentResult = new FileContentResult(report.Render(format, deviceInfo, out mimeType, out encoding, out filenameExtension, out streamIds, out warnings), mimeType);
fileContentResult.FileDownloadName = Path.ChangeExtension(fileDownloadName, filenameExtension);
return fileContentResult;
}
Edit: Forget to call the help function. Oops.
You might try something like the following... We fill a list of objects from our data access level and then pass that list of objects to something like the following...
public static byte[] SaveExcelData<T>(List<T> answer)
{
byte[] fileData = null;
var grid = new System.Web.UI.WebControls.GridView();
grid.DataSource = answer;
grid.DataBind();
HttpContext.Current.Response.ClearContent();
string headerAddition = "attachment; filename=";
headerAddition += answer[0].GetType().Name + ".xls";
HttpContext.Current.Response.AddHeader("content-disposition", headerAddition);
HttpContext.Current.Response.ContentType = "application/excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
grid.RenderControl(htw);
fileData = System.Text.Encoding.UTF8.GetBytes(sw.ToString());
return fileData;
}
精彩评论