经过一晚上的查找终于搞通了如何用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标签,在其中设置好要访问的下载地址,然后运行就可以了。