最近开始做一个项目,需要做导出excel,其实这个很简单的,刚开始的时候调用错误导致执行到Response.End(); 报“由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值”错误,根据网上的代码修改成 HttpContext.Current.ApplicationInstance.CompleteRequest();还是没有用。不知道是哪里出问题了,后来通过将数据通过excel的方式保存在服务器端然后通过下载的方式返回到客户端才勉强实现功能,但是又出现了一个小问题,因为服务器端下载需要将DCOM配置中Microsoft Excel Application的访问权限设置为“交互式”(否则会报“异常详细信息: System.UnauthorizedAccessException: 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005。”的错误),服务器在有远程连接的时候才能够下载,没有远程连接就会出现404错误。后来通过查看文档和网上查阅资料使用 datatable导出excel数据量给客户端保存下载 的方式实现功能。
具体代码如下:
js
//数据导入excel
var ajaxUrl = "Ajax/TaskList_Month.ashx";
function ForExcel() {
var params = {};
params.action = "excel";//返回后台后执行何种操作
params.city = $('#Q_OID').combobox("getValue"); //查询选项
params.start = $('#Q_F_ID').datebox("getValue");
params.end = $('#Q_EndDate').datebox("getValue");
//数据提交
$.ajax({
type: 'post',
url: ajaxUrl,
async: false,
data: params,
success: function (data) {
if (data != "") {
//location.href = data;
eval(data);
}
}
});
}
ashx.cs
protected Dao.Entity.SmartEFEntities dao = new SmartEFEntities();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (context.Session["oid"] == null && context.Session["accountid"] == null)
return;
string data = "";
try
{
string action = context.Request.Params["action"];
switch (action)
{
case "list":
data = GetList(context);
break;
case "excel":
data = ExcelData(context);
break;
//case "add":
// //添加数据
// data = Save(context);
// break;
//case "save":
// //修改数据
// data = Save(context);
// break;
//case "delete":
// //修改数据
// data = Delete(context);
// break;
default:
break;
}
}
catch(Exception ex)
{ ex.ToString(); }
context.Response.Write(data);
}
public string ExcelData(HttpContext context)
{
string messsage = "";
string city = context.Request.Params["city"];
string start = context.Request.Params["start"];
string end = context.Request.Params["end"];
string value = "?";
if (!string.IsNullOrWhiteSpace(city))
{
value += "city=" + city;
}
else
{
value += "city=yc";
}
if (!string.IsNullOrWhiteSpace(start))
{
value += "&start=" + start;
}
if (!string.IsNullOrWhiteSpace(end))
{
value += "&end=" + end;
}
return messsage = "window.open('OtherFunction/Task_ExcelData.aspx" + value + "')";
}
aspx.cs
public partial class Task_ExcelData : System.Web.UI.Page
{
protected Dao.Entity.SmartEFEntities dao = new SmartEFEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Bind();
}
}
void Bind()
{
IQueryable<V_TaskList_PassRate> Vpassrate = dao.V_TaskList_PassRate.AsQueryable();//linq中的视图
string city = Request.QueryString["city"];
string start = Request.QueryString["start"];
string end = Request.QueryString["end"];
if (!string.IsNullOrWhiteSpace(city))
{
Vpassrate = Vpassrate.Where(pp => pp.School_OID == city);
}
if (!string.IsNullOrWhiteSpace(start))
{
int StartTime=Convert.ToInt32(start);
Vpassrate = Vpassrate.Where(pp => pp.Mon >= StartTime);
}
if (!string.IsNullOrWhiteSpace(end))
{
int EndTime=Convert.ToInt32(end);
Vpassrate = Vpassrate.Where(pp => pp.Mon <= EndTime);
}
var list = Vpassrate.OrderByDescending(pp => pp.Mon)
.Select(pp => new T_PassRate
{
Mon = pp.Mon,
School_oid = pp.OID_Name,
Finish = pp.FinishTask,
Sumtask = pp.SumTask,
Passrate = pp.Expr1
}).ToList();
DataTable dt = new DataTable();
dt = ToDataTable(list);
string fileName = "" + DateTime.Now.Year + "年" + DateTime.Now.Month + "月" + DateTime.Now.Day + "日" + "维修任务单报表";
DataTable1Excel(dt, fileName);
}
//将json数据转化成datatable
public DataTable ToDataTable(IList list)
{
DataTable dt=new DataTable();
if (list.Count > 0)
{
dt.Columns.Add("月份");
dt.Columns.Add("地区");
dt.Columns.Add("维修任务单总数量");
dt.Columns.Add("任务单完成数量");
dt.Columns.Add("维修任务单完成率(%)");
DataRow dr = dt.NewRow();
foreach (T_PassRate item in list)
{
dr = dt.NewRow();
dr["月份"] = item.Mon;
dr["地区"] = item.School_oid;
dr["维修任务单总数量"] = item.Sumtask;
dr["任务单完成数量"] = item.Finish;
dr["维修任务单完成率(%)"] = Convert.ToInt32(item.Passrate);
dt.Rows.Add(dr);
}
}
return dt;
}
//将datatable数据导出excel
public static void DataTable1Excel(System.Data.DataTable dtData, string fileName)
{
System.Web.UI.WebControls.GridView gvExport = null;
// 当前对话
System.Web.HttpContext curContext = System.Web.HttpContext.Current;
// IO用于导出并返回excel文件
System.IO.StringWriter strWriter = null;
System.Web.UI.HtmlTextWriter htmlWriter = null;
if (dtData != null)
{
// 设置编码和附件格式
curContext.Response.ContentType = "application/vnd.ms-excel";
curContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
curContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName + ".XLS"));
curContext.Response.Charset = "utf-8";
// 导出excel文件
strWriter = new System.IO.StringWriter();
htmlWriter = new System.Web.UI.HtmlTextWriter(strWriter);
// 为了解决gvData中可能进行了分页的情况,需要重新定义一个无分页的GridView
gvExport = new System.Web.UI.WebControls.GridView();
gvExport.DataSource = dtData.DefaultView;
gvExport.AllowPaging = false;
gvExport.DataBind();
gvExport.RenderControl(htmlWriter);
curContext.Response.Write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\" />" + strWriter.ToString());
curContext.Response.End();
}
}
//自定义数据类
public class T_PassRate
{
int? mon;
public int? Mon
{
get { return mon; }
set { mon = value; }
}
string school_oid;
public string School_oid
{
get { return school_oid; }
set { school_oid = value; }
}
int? finish;
public int? Finish
{
get { return finish; }
set { finish = value; }
}
int? sumtask;
public int? Sumtask
{
get { return sumtask; }
set { sumtask = value; }
}
decimal? passrate;
public decimal? Passrate
{
get { return passrate; }
set { passrate = value; }
}
}
点击导出excel后出现: