问题:我们发现直接使用ajax请求后台导出数据至Excel的过程中,后台程序必须为void类型,且使用ajax导出无任何反应,对于大数据的导出而言,不能使用ajax掌握导出的结束时间就无法给出结束提示。
解决办法:
1.服务器后台方法处理
我们使用NOPI创建一个NPOI.HSSF.UserModel.HSSFWorkbook book 创建一个book对象,将所有要处理的数据写入book对象中去,此时我们要配合缓存的使用,将book对象存在缓存中去,我们new一个Guid的随机缓存键值。
[HttpPost]
public ActionResult ExportSampleInfo(string projectId)
{
NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet1");
/*
业务代码
*/
var guid = "";
guid = Guid.NewGuid().ToString();
CacheHelper.SetCache(guid, book);
return Json(guid, JsonRequestBehavior.AllowGet);
}
此时抛出的键值由ajax接收,因为导出最花时间的就是业务处理所需要的时间,因此上面的业务处理做完了,此时也就意味着导出最花时间的任务已经结束:
$.ajax({
type: 'post',
url: '/Report/ExportSampleInfo',
data: { "projectId": projectId },
datatype: 'json',
success: function (data) {
document.getElementById("dvMsg").innerHTML = "导出成功!";
document.location.href = "/Report/OriginCode?guid=" + data;
},
error: function () {
alert('导出失败');
}
});
通过 document.location.href = "/Report/OriginCode?guid=" + data;请求后台将数据导出即可
public void OriginCode(string guid)
{
object obj = CacheHelper.GetCache(guid);
NPOI.HSSF.UserModel.HSSFWorkbook book = obj as NPOI.HSSF.UserModel.HSSFWorkbook;
if (book != null)
{
// 写入到客户端
System.IO.MemoryStream ms = new System.IO.MemoryStream();
book.Write(ms);
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyyMMddHHmmssfff")));
Response.BinaryWrite(ms.ToArray());
book = null;
ms.Close();
ms.Dispose();
}
CacheHelper.RemoveAllCache(guid);
}
总结而言,主要就是导出分两步走
第一步,业务的处理,业务比较复杂就比较花时间,处理完的数据保存到缓存当中去
第二步,将缓存键值送到前台,此时任务基本完成,前台收到后即可显示导出完成,只需要取出缓存写出数据即可
后面附上CacheHelper类的具体内容:
public class CacheHelper
{
#region 获取缓存
///
/// 获取缓存
///
/// 键
///
public static object GetCache(string cacheKey)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
return objCache[cacheKey];
}
#endregion
#region 设置数据缓存
///
/// 设置数据缓存
///
/// 键
/// 值
public static void SetCache(string cacheKey,object objObject)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Insert(cacheKey,objObject);
}
#endregion
#region 设置数据缓存
///
/// 设置数据缓存
///
///
///
///
public static void SetCache(string cacheKey,object objObject,TimeSpan timeout)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Insert(cacheKey,objObject,null,DateTime.MaxValue,timeout,System.Web.Caching.CacheItemPriority.NotRemovable,null);
}
#endregion
#region 设置数据缓存
public static void SetCache(string cacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
objCache.Insert(cacheKey,objObject,null,absoluteExpiration,slidingExpiration);
}
#endregion
#region 移除指定的数据缓存
public static void RemoveAllCache(string cacheKey)
{
System.Web.Caching.Cache _cache = HttpRuntime.Cache;
_cache.Remove(cacheKey);
}
#endregion
#region 移除全部缓存
public static void RemoveAllCache()
{
System.Web.Caching.Cache _cache = HttpRuntime.Cache;
IDictionaryEnumerator cacheEnum = _cache.GetEnumerator();
while (cacheEnum.MoveNext())
{
_cache.Remove(cacheEnum.Key.ToString());
}
}
#endregion
}