Экспорт таблицы HTML в Excel с помощью метода страницы - PullRequest
4 голосов
/ 18 ноября 2010

У меня есть следующий код на стороне клиента для извлечения данных из таблицы 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;
}

Но я получаю это исключение: Невозможно оценить выражение, потому что код оптимизирован или собственный вызов находится поверх вызоваstack.

Кто-нибудь знает, как решить эту проблему?

Любая помощь будет принята с благодарностью!Заранее спасибо!

~ Эдер Киньонес

Ответы [ 3 ]

1 голос
/ 04 декабря 2010

Не совсем AJAX, но я выполнил эту функцию раньше, создав отдельную страницу ASPX, которая генерирует файл CSV (как вы уже сделали в exportToCSV()).

На странице клиента, используя JS, я загружал бы эту страницу ASPX в динамически внедренный iframe, который стилизован в style="display:none".

Вы также можете включить iframe на страницу и просто использовать JS для загрузки в нее своей страницы «экспорта» по мере необходимости.

EDIT: Вы можете выполнить вызов PageMethod, чтобы отправить таблицу на сервер, сгенерировать CSV и сохранить ее в Session []. Затем, вернувшись на страницу, загрузите упомянутую выше страницу «Экспорт», чтобы извлечь этот CSV, сохраненный в сеансе.

1 голос
/ 08 декабря 2010

Я сделал то, что Леон предложил в качестве ответа, но вместо этого я использовал общий обработчик.

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

Есть ли какие-либо улучшения, предложения?

~ Eder Quiñones

1 голос
/ 03 декабря 2010
    /// <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;
    }

Но диалоговое окно сохранения файла не отображается ...

...