How do I load a file in javascript or jquery from a web method that is in byte []?

I am having problems uploading an excel file using jquery. I read on some forums that this is not possible with ajax and some say that you can achieve this by sending the results to an iframe. So far I have not been able to solve my problem.

Technical details: I am generating a database query with some parameters, the webservice executes this request and returns an excel file generated in openxml and returns bytes. I am using asp.net 4.0. If I use normal webcontrols and ajax the file loads without issue if in the refresh panel I set asp: postbacktrigger triggers to the button control.

I am trying to achieve the same results using only jqueryUi and jquery elements.

There are two methods on the server side:

ExportToExcel: This method receives parameters to call the rest web service, which returns excelfile.

SendExcelFileByBytes This is the method that returns the file in the request.

Here is the C # code:

[WebMethod]
    public static void ExportToExcel(List<int> status, List<Guid> companyId, List<DateTime> dateFrom, List<DateTime> dateTo, bool isGroupedByStore)
    {
        ReconciliationModule server = new ReconciliationModule(ConfigurationManager.AppSettings["serviceNamespace"], ConfigurationManager.AppSettings["ACSHostUrl"], ConfigurationManager.AppSettings["scopeAddress"]);
        SummaryReport summaryReport = new SummaryReport();

        List<Tuple<Guid, DateTime, DateTime, int>> parameters = new List<Tuple<Guid, DateTime, DateTime, int>>();

        for (int i = 0; i < dateTo.Count; i++)
        {
            parameters.Add(new Tuple<Guid, DateTime, DateTime, int>(
                companyId[i],
                dateFrom[i],
                dateTo[i],
                status[i]
            ));
        }

        byte[] x = server.GetSummaryReportInExcel(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["pwdOrSymmetricKey"], bool.Parse(ConfigurationManager.AppSettings["isSymmetricKey"]), isGroupedByStore, parameters);

        SendExcelFileByBytes(x);
    }

    private static void SendExcelFileByBytes(byte[] x)
    {
        System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"SummaryReport.xlsx\"");
        System.Web.HttpContext.Current.Response.AddHeader("Content-Type", "application/force-download");
        System.Web.HttpContext.Current.Response.AddHeader("Content-Type", "application/download");
        //System.Web.HttpContext.Current.Response.AddHeader("Content-Transfer-Encoding", "binary");
        System.Web.HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";//excel file
        System.Web.HttpContext.Current.Response.Clear();

        System.Web.HttpContext.Current.Response.BinaryWrite(x);
        //System.Web.HttpContext.Current.Response.Close();
        System.Web.HttpContext.Current.Response.Flush();
        System.Web.HttpContext.Current.Response.End();
    }

      

For jscript, my AjaxFunction call doesn't work and returns 200 OK message with results in responseText. So in the function that gets executed when something fails, I show the responseText in the table. If anyone can help me make this better it would be greatly appreciated. And here is the jscript code:

//Executes Ajax Calls using json as data type
function callAjax(callType, urlAddress, dataToSend, fnSucceeded, fnFailed) {
    $.ajax({
        type: callType,
        url: urlAddress,
        contentType: "application/json; charset=utf-8",
        data: dataToSend,
        dataType: "json",
        success: fnSucceeded,
        error: fnFailed
    });
}

//TODO: This function is the one i need to correct
function getSummaryReportInExcel() {

    ShowLoader('#reconciliation');
    var isGroupedByStore = new Boolean($('#CompanyTypes :checkbox').attr('checked'));
    var stat = getStatus();
    var status = new Array();
    var companyId = new Array();
    var dateFrom = new Array();
    var dateTo = new Array();
    var companiesToSearch = $('#CompanyConfigurations :checkbox:checked');

    //populating the parameters
    $(companiesToSearch).each(function (i, currentCompany) {
        status.push(stat);
        companyId.push($(currentCompany).select('checkbox').attr('value'));
        dateFrom.push($(currentCompany).parents().find('td:eq(2) :input').attr('value'));
        dateTo.push($(currentCompany).parents().find('td:eq(3) :input').attr('value'));
    });

    var data = "{ status : " + JSON.stringify(status) + ", companyId : " +  JSON.stringify(companyId) + ", dateFrom : " +  JSON.stringify(dateFrom) + ", dateTo : " +  JSON.stringify(dateTo) + ", isGroupedByStore : " + isGroupedByStore + " }";

    alert(data);

    callAjax(
        "POST", "UIJquery.aspx/ExportToExcel",
        data,
        //is not entering here
        function () {
            alert('Hola' + result.toString());

            //header.
            HideLoader();
        },
        //AjaxFailed
        function (result) {
            //alert(concatObject( result));
            $('#SearchResults').append(concatObject(result));
            //var iFrame = "<iframe src=" + result.responseText + "></iframe>";


            $('#IResults').html(result.responseText);
            //window.open(result.responseText, 'Download');
            HideLoader();
            //alert(concatObject(result));
        }
    );
}

      

This is what I see in developer tools in google chrome

HeadersPreviewResponseTiming
Request URL:http://localhost:53144/UIJquery.aspx/ExportToExcel
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:216
Content-Type:application/json; charset=UTF-8
Host:localhost:53144
Origin:http://localhost:53144
Referer:http://localhost:53144/UIJQuery.aspx
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11
X-Requested-With:XMLHttpRequest
Request Payload
{ status : [15,15], companyId : ["15afbacb-5c0c-4402-a5af-0f5a53221bbb","041d6a48-35ca-4d55-97ec-4fd5f4bdd11f"], dateFrom : ["11/06/2011","11/06/2011"], dateTo : ["11/12/2011","11/12/2011"], isGroupedByStore : true }
Response Headersview source
Cache-Control:private, max-age=0
Connection:Close
Content-Disposition:attachment; filename="SummaryReport.xlsx"
Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Date:Wed, 28 Mar 2012 18:22:32 GMT
Server:ASP.NET Development Server/10.0.0.0
Transfer-Encoding:chunked
X-AspNet-Version:4.0.30319

      

Any suggestions or better ways to do this, let me know.

+3


source to share


1 answer


Something like that ...

<script type="text/javascript">
function downloadExcelFile(url, dataToSend) {
   url += '?';
   for(var k in dataToSend) {
      url += k + '=' + encodeURIComponent(dataTosend[k]) + '&';
      }
   window.location = url;
   }
</script>

      

this will take the base url as the first argument, and the object containing the parameters as the second will build the full url from that and redirect the browser to it ... for example



downloadExcelFile('http://www.example.com/myWebservice/downloadExcel.aspx', {
   param1: 'value1',
   param2: 'value2'
   });

      

the browser in this case will be redirected to

http://www.example.com/myWebservice/downloadExcel.aspx?param1=value1&param2=value2&

      

+1


source







All Articles