.net mvc中 如何利用ajax下载文件

时间:2021-12-02 09:56:45

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