经过一晚上的查找终于搞通了如何用ajax在mvc中进行文件的下载。
这个是找到的解决办法:http://www.ophome.cn/question/57638
下面记录一下:
由于在ajax中,成功后返回的数据只有text/html/script/xml/json等,但是就是没有文件流(FileStream),
所以只能退一步,先将要下载的文件生成好,存放在服务器上的指定文件夹上,然后在ajax的success中指定浏览器重新定向一个新的地址,这个地址指向控制器中下载文件的方法。
(window.location="下载的地址";)
具体的代码:
js里的代码:
$.ajax({ type: "POST", //dataType: "json", //data: { searchOptionObj: JSON.stringify(searchOption) }, data: searchOption, url: "../DataAnalyse/QueryData?ecode=" + WLDataAnylysis.SearchOption.energyCode , beforeSend: function () { }, success: function (data) { var chartData = eval("(" + data + ")"); window.location = '/DataAnalyse/Download?file=' + chartData; searchOption.dataToExcel = "0";//无关的代码 }, error: function (data) { return null; } });
后台的代码:
/// <summary> /// 下载Excel文件的方法 /// </summary> /// <param name="file">Excel文件的名字</param> /// <returns></returns> public virtual ActionResult Download(string file) { string fullPath = System.IO.Path.Combine(Server.MapPath("~/ExcelFiles"), file); return File(fullPath, "application/vnd.ms-excel", file); }
后台生成Excel的方法:
NPOIHelper.DataTableToExcel(cm, dm, "各点能耗查询导出", Server.MapPath("/") + "/ExcelFiles/各点能耗查询导出.xls"); return Content(JsonHelper.Serialize("各点能耗查询导出.xls"));
/// <summary> /// DataTable导出到Excel文件 /// </summary> /// <param name="dtSource">源DataTable</param> /// <param name="strHeaderText">表头文本</param> /// <param name="strFileName">保存位置</param> public static void DataTableToExcel(ChartModel cm, DataModel dm, string strHeaderText, string strFileName) { using (MemoryStream ms = DataTableToExcel(cm, dm, strHeaderText)) { using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)) { byte[] data = ms.ToArray(); fs.Write(data, 0, data.Length); fs.Flush(); } } //return ms; } /// <summary> /// DataTable导出到Excel的MemoryStream /// </summary> /// <param name="dtSource">源DataTable</param> /// <param name="strHeaderText">表头文本</param> public static MemoryStream DataTableToExcel(ChartModel cm, DataModel dm, string strHeaderText) { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(); #region 右击文件 属性信息 { DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); dsi.Company = "NPOI"; workbook.DocumentSummaryInformation = dsi; SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); si.Author = "文件作者信息"; //填加xls文件作者信息 si.ApplicationName = "创建程序信息"; //填加xls文件创建程序信息 si.LastAuthor = "最后保存者信息"; //填加xls文件最后保存者信息 si.Comments = "作者信息"; //填加xls文件作者信息 si.Title = "标题信息"; //填加xls文件标题信息 si.Subject = "主题信息";//填加文件主题信息 si.CreateDateTime = System.DateTime.Now; workbook.SummaryInformation = si; } #endregion HSSFCellStyle dateStyle = (HSSFCellStyle)workbook.CreateCellStyle(); HSSFDataFormat format = (HSSFDataFormat)workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); //取得列宽 int[] arrColWidth = new int[dm.DataItem[0].datetime.Length + 1]; for (int i = 0; i < dm.DataItem[0].datetime.Length; i++) { arrColWidth[i+1] = Encoding.GetEncoding(936).GetBytes(dm.DataItem[0].datetime[i].ToString()).Length; } //for (int i = 0; i < cm.Dataset; i++) //{ // for (int j = 0; j < dtSource.Columns.Count; j++) // { // int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length; // if (intTemp > arrColWidth[j]) // { // arrColWidth[j] = intTemp; // } // } //} int rowIndex = 0; foreach (Dataset ds in cm.Dataset) { #region 新建表,填充表头,填充列头,样式 if (rowIndex == 65535 || rowIndex == 0) { if (rowIndex != 0) { sheet = (HSSFSheet)workbook.CreateSheet(); } #region 表头及样式 { HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0); headerRow.HeightInPoints = 25; headerRow.CreateCell(0).SetCellValue(strHeaderText); HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle(); // headStyle.Alignment = CellHorizontalAlignment.CENTER; HSSFFont font = (HSSFFont)workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; // sheet.AddMergedRegion(new Region(0, 0, 0, dtSource.Columns.Count - 1)); //headerRow.Dispose(); } #endregion #region 列头及样式 { HSSFRow headerRow = (HSSFRow)sheet.CreateRow(1); HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle(); //headStyle.Alignment = CellHorizontalAlignment.CENTER; HSSFFont font = (HSSFFont)workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); headerRow.CreateCell(0).SetCellValue("名字\\时间"); headerRow.GetCell(0).CellStyle = headStyle; //设置列宽 sheet.SetColumnWidth(0, (arrColWidth[1] + 1) * 256); for (int i = 0; i < dm.DataItem[0].datetime.Length; i++) { headerRow.CreateCell(i + 1).SetCellValue(dm.DataItem[0].datetime[i].ToString()); headerRow.GetCell(i + 1).CellStyle = headStyle; //设置列宽 sheet.SetColumnWidth(i + 1, (arrColWidth[i + 1] + 1) * 256); } // headerRow.Dispose(); } #endregion rowIndex = 2; } #endregion #region 填充内容 HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex); HSSFCell newCell1 = (HSSFCell)dataRow.CreateCell(0); newCell1.SetCellValue(ds.Seriesname); if (ds.Data!=null&&ds.Data.Length>0) { for (int i = 0; i < ds.Data.Length-2; i++) { HSSFCell newCell = (HSSFCell)dataRow.CreateCell(i + 1); string drValue = ds.Data[i].Value.ToString(); double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); } } #endregion rowIndex++; } using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); ms.Flush(); ms.Position = 0; workbook.Clear(); //workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet return ms; } }
这个差不多是完整的实现方法了。
由于ajax请求的时候参数比较多是由post的方式传到方法里的,当参数比较少或者没有参数的时候可直接用js生成一个隐藏的form标签,在其中设置好要访问的下载地址,然后运行就可以了。