4

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

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;
}

但我得到了这个 expcetion:无法评估表达式,因为代码已优化或本机框架位于调用堆栈的顶部。

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

任何帮助将不胜感激!提前致谢!

~ 埃德奎尼诺斯

4

3 回答 3

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;
    }

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

于 2010-12-03T18:41:49.733 回答
1

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

在客户端页面上,我会使用 JS 将这个 ASPX 页面加载到一个动态注入的 iframe 中,该 iframe 的样式为style="display:none".

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

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

于 2010-12-03T21:52:00.490 回答
1

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

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

    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.- 初始化会话变量(作为 StringBuilder)通过 aspx 页面(主页)进行数据交换:

    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();
    }
}

有什么改进,有什么建议吗?

~ 埃德奎尼诺斯

于 2010-12-08T19:09:04.507 回答