通过页面方法将HTML表导出到Excel

时间:2010-11-18 16:59:43

标签: c# asp.net jquery ajax pagemethods

我在客户端有以下代码用于从HTML表中检索数据,然后通过页面方法将其发送到服务器:

function dtExportToCSV(dataTable) {
    var elements = dtDataToJSON(dataTable);
    var headers = dtHeadersToJSON(tableSelector);

    jQuery.ajax({
        type: "POST",
        url: "Report.aspx/exportToCSV",
        data: "{'elements': " + elements + ", 'headers': " + JSON.stringify(headers) + "}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",

        success: function(msg) {
            if (msg.d) {
            } else {
            }
        },

        error: function(xhr, ajaxOptions, thrownError) {
            alert(xhr.statusText);
        }
    });
}

然后我在服务器端使用以下代码,将检索到的数据导出到CSV文件。

/// <summary>
/// 
/// </summary>
/// <param name="elements"></param>
/// <param name="headers"></param>
[WebMethod(EnableSession=true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static bool exportToCSV(List<object> elements, List<string> headers)
{
    try
    {
        string attachmentType = "attachment; filename=ShortageReport.csv";

        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.ClearContent();
        HttpContext.Current.Response.AddHeader("content-disposition", attachmentType);
        HttpContext.Current.Response.ContentType = "text/csv";
        HttpContext.Current.Response.AddHeader("Pragma", "public");

        writeHeadersInfo(headers);

        HttpContext.Current.Response.End();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    return false;
}

但我得到了这个说法: 无法评估表达式,因为代码已经过优化,或者本机框架位于调用堆栈之上。

有谁知道如何处理这个问题?

任何帮助都将受到高度赞赏! 在此先感谢!

~EderQuiñones

3 个答案:

答案 0 :(得分:1)

    /// <summary>
    /// 
    /// </summary>
    /// <param name="elements"></param>
    /// <param name="headers"></param>
    [WebMethod(EnableSession=true)]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static bool exportToCSV(List<object> elements, List<string> headers)
    {
        try
        {
            string attachmentType = "attachment; filename=Shortage Report.csv";

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ClearHeaders();

            HttpContext.Current.Response.AddHeader("Content-Disposition", attachmentType);
            HttpContext.Current.Response.ContentType = "text/csv";

            writeHeadersInfo(headers);
            writeBodyInfo(headers, elements);

            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        return true;
    }

但它没有显示保存文件对话框......

答案 1 :(得分:1)

不完全是AJAX但我之前通过构建一个生成CSV文件的单独ASPX页面来完成此功能(正如您在exportToCSV()中所做的那样)。

在客户端页面上,使用JS我会在动态注入的iframe中加载此ASPX页面,该iframe使用style="display:none"设置样式。

您还可以在页面上包含iframe,并根据需要使用JS加载“导出”页面。

修改 您可以执行PageMethod调用以将表发送到服务器,生成CSV并将其存储在Session []中。然后在返回页面时,加载上面提到的“导出”页面以检索存储在会话中的CSV。

答案 2 :(得分:1)

我做了Leon建议的答案,但我使用了通用处理程序。

1.-从客户端检索数据,构建json&amp;将数据发送到服务器(主页):

    function dtExportToCSV(dataTable) {
        var elements = dtDataToJSON(dataTable);
        var headers = dtHeadersToJSON(tableSelector);

        jQuery.ajax({
            type: "POST",
            url: "ashx/Export.ashx",
            data: "{'elements': " + elements + ", 'headers': " + headers + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",

            success: function(msg) {
                window.open("Export.aspx", "Export CSV", "width=120,height=300");
            },

            error: function(xhr, ajaxOptions, thrownError) {
                alert(xhr);
            }
        });

        return false;
    }

2.-通过aspx页面(主页)初始化会话变量(作为StringBuilder)进行数据交换:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["ExportCSV"] == null)
        {
            Session["ExportCSV"] = new StringBuilder();
        }

        if (!IsPostBack)
        {

        }   

    }

3.-构建CSV(通用处理程序):

public class Export : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        object json = null;
        byte[] input = null;

        JavaScriptSerializer javascriptSerializer = null;
        StringBuilder sb = null;

        List<object> elementList = null;
        List<string> headerList = null;

        try
        {
            input = readToEnd(context.Request.InputStream);
            sb = new StringBuilder();
            javascriptSerializer = new JavaScriptSerializer();

            foreach (byte chr in input)
            {
                sb.Append((char)chr);
            }

            json = javascriptSerializer.DeserializeObject(sb.ToString());

            elementList = new List<object>();
            headerList = new List<string>();

            var dictionary = json.toType(new Dictionary<string, object>());
            foreach (KeyValuePair<string, object> keyValuePair in dictionary)
            {
                switch (keyValuePair.Key)
                {
                    case "elements":
                    case "ELEMENTS":
                        {
                            object[] elements = (object[])keyValuePair.Value;
                            foreach (object element in elements)
                            {
                                elementList.Add(element);
                            }
                            break;
                        }

                    case "headers":
                    case "HEADERS":
                        {
                            object[] headers = (object[])keyValuePair.Value;
                            foreach (object header in headers)
                            {
                                headerList.Add((string)header);
                            }

                            break;
                        }
                }
            }

            ((StringBuilder) context.Session["ExportCSV"]).Append(writeBodyInfo(elementList, headerList));
            ((StringBuilder) context.Session["ExportCSV"]).Append(writeHeadersInfo(headerList));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
    }
}

4.-显示保存文件对话框(Export.aspx):

public partial class Export : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            exportToCSV();
        }
    }

    private void exportToCSV()
    {
        Context.Response.Clear();
        Context.Response.ClearContent();
        Context.Response.ClearHeaders();

        Context.Response.AddHeader("Content-Disposition", "attachment;filename=ShortageReport.csv");
        Context.Response.ContentType = "text/csv";

        char[] separator = Environment.NewLine.ToCharArray();
        string csv = ((StringBuilder)Session["ExportCSV"]).ToString();

        foreach (string line in csv.Split(separator))
        {
            Context.Response.Write(line);
        }

        Context.Response.Flush();
        Context.Response.End();
    }
}

有任何改进,建议吗?

~EderQuiñones