我正在寻找一些建议。我正在构建一个其他人写的C#项目的附加功能。该项目的解决方案包括一个MVC Web应用程序,其中包含一些类库。
我正在编辑的是销售报告功能。在原始版本中,在Web应用程序上生成了销售报告的摘要。当用户生成销售报告时,会在其中一个C#类库中调用Reporting类。我正在尝试在用户选择单选按钮时在excel文件中下载销售报告。
以下是Reporting类的代码片段:
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声明我的格式化程序类中的行显示了这个(非常隐藏的思想):
ReadTimeout'((System.IO.Stream)(ms))。ReadTimeout' 抛出了类型的例外 'System.InvalidOperationException'int {System.InvalidOperationException}
+ {“此流不支持超时。”} System.SystemException {System.InvalidOperationException}
我对'WriteTimeout'也是一样的......
对解释的长篇大论表示歉意。我很感激,如果有人能指出我正确的方向,要么是解决我当前的问题,要么是另一种方法来解决这个问题。
答案 0 :(得分:2)
在没有陷入细节的情况下,明显的错误是在GenerateCustomisedSalesFile
中你创建一个MemoryStream ms,什么也不做,然后返回它。