我正在寻找一些建议。我正在构建其他人编写的C#项目的其他功能。该项目的解决方案由一个MVC Web应用程序和几个类库组成。C#类库下载的Excel文件
我在编辑的是销售报告功能。在原始版本中,销售报告的摘要是在Web应用程序上生成的。当用户生成销售报告时,将在其中一个C#类库中调用一个Reporting类。我试图让用户选择一个单选按钮时,可以在Excel文件中下载销售报告。
下面是代码的报告类的一个片段:
public AdminSalesReport GetCompleteAdminSalesReport(AdminSalesReportRequest reportRequest)
{
AdminSalesReport report = new AdminSalesReport();
string dateRange = null;
List<ProductSale> productSales = GetFilteredListOfAdminProductSales(reportRequest, out dateRange);
report.DateRange = dateRange;
if (titleSales.Count > 0)
{
report.HasData = true;
report.Total = GetTotalAdminSales(productSales);
if (reportRequest.Type == AdminSalesReportRequest.AdminSalesReportType.Complete)
{
report.ProductSales = GetAdminProductSales(productSales);
report.CustomerSales = GetAdminCustomerSales(productSales);
report.ManufacturerSales = GetAdminManufacturerSales(productSales);
if (reportRequest.Download)
{
FileResult ExcelDownload = GetExcelDownload(productSales);
}
}
}
return report;
}
所以你可以看到,如果reportRequest.Download == true,则类应该启动创建Excel文件的过程。所有GetAdminSales函数都会使用linq查询来排列销售,如果它们显示在网页上。
所以我一直与GetAdminSales功能一起加入这个:
private FileResult GetExcelDownload(List<TitleSale> titleSales)
{
CustomisedSalesReport CustSalesRep = new CustomisedSalesReport();
Stream SalesReport = CustSalesRep.GenerateCustomisedSalesStream(productSales);
return new FileStreamResult(SalesReport, "application/ms-excel")
{
FileDownloadName = "SalesReport" + DateTime.Now.ToString("MMMM d, yyy") + ".xls"
};
}
和Excel文档的格式,我使用NPOI库,和我的格式化类布局像这样:
public class CustomisedSalesReport
{
public Stream GenerateCustomisedSalesStream(List<ProductSale> productSales)
{
return GenerateCustomisedSalesFile(productSales);
}
private Stream GenerateCustomisedSalesFile(List<ProductSale> productSales)
{
MemoryStream ms = new MemoryStream();
HSSFWorkbook templateWorkbook = new HSSFWorkbook();
HSSFSheet sheet = templateWorkbook.CreateSheet("Sales Report");
HSSFRow dataRow = sheet.CreateRow(0);
HSSFCell cell = dataRow.CreateCell(0);
cell = dataRow.CreateCell(0);
cell.SetCellValue(DateTime.Now.ToString("MMMM yyyy") + " Sales Report");
dataRow = sheet.CreateRow(2);
string[] colHeaders = new string[] {
"Product Code",
"Product Name",
"Qty Sold",
"Earnings",
};
int colPosition = 0;
foreach (string colHeader in colHeaders)
{
cell = dataRow.CreateCell(colPosition++);
cell.SetCellValue(colHeader);
}
int row = 4;
var adminTotalSales = GetAdminProductSales(productSales);
foreach (SummaryAdminProductSale t in adminTotalSales)
{
dataRow = sheet.CreateRow(row++);
colPosition = 0;
cell = dataRow.CreateCell(colPosition++);
cell.SetCellValue(t.ProductCode);
cell = dataRow.CreateCell(colPosition++);
cell.SetCellValue(t.ProductName);
cell = dataRow.CreateCell(colPosition++);
cell.SetCellValue(t.QtySold);
cell = dataRow.CreateCell(colPosition++);
cell.SetCellValue(t.Total.ToString("0.00"));
}
}
templateWorkbook.Write(ms);
ms.Position = 0;
return ms;
}
和以前一样,GetAdminSales(GetAdminProductSales等)包含在类的底部,并且只是用于收集数据的linq查询。
所以当我运行这个,我没有得到任何明显的错误。摘要销售报告正常显示在屏幕上,但没有Excel文档下载。我所做的,可能会把它关掉是在我的类库中我已经引用了System.Web.Mvc dll以下载文件(我之前没有做过任何其他的操作 - 在读完网络之后我觉得我可以在课堂库中使用它)。
当我通过代码进行调试以获得更接近的图片时,一切似乎都正常,所有正确的数据都被捕获,但我发现从一开始 - MemoryStream ms = new Memory Stream在我的格式化程序类报关行显示了这个(非常隐蔽提醒你) '((System.IO.Stream)(MS))ReadTimeout'
ReadTimeout 扔 类型的异常“System.InvalidOperationException 'int {System.InvalidOperationException}
+ {“超时不支持特德在此流。“} System.SystemException {} System.InvalidOperationException
我得到 'WriteTimeout' 一样......
很抱歉没能交代的长windedness。如果有人能指出我正确的方向,要么解决我目前的问题,要么让这项工作成为替代方法,我将不胜感激。
你好蒂姆,我知道我会留下一些东西。我打算在返回ms之前添加以下内容; - templateWorkbook.Write(ms);和ms。位置= 0;感谢慢跑我的记忆!在添加了这个但是我仍然得到相同的InvalidOperationException。还有什么想法? – 109221793 2011-04-21 09:04:20