C# 通过WebApi调用从页面下载excel文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14831860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:10:27  来源:igfitidea点击:

Download excel file from page via WebApi call

c#asp.netexcelasp.net-web-apixls

提问by Neil

I'm trying to send a 9MB .xlsfile as a response from web api controller method. The user will click a button on the page and this will trigger the download via the browser.

我正在尝试发送一个 9MB.xls文件作为来自 web api 控制器方法的响应。用户将点击页面上的一个按钮,这将通过浏览器触发下载。

Here's what I've got so far but it doesn't work however it doesn't throw any exceptions either.

这是我到目前为止所得到的但它不起作用但是它也不会抛出任何异常。

[AcceptVerbs("GET")]
public HttpResponseMessage ExportXls()
{
    try
    {
        byte[] excelData = m_toolsService.ExportToExcelFile();

        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new MemoryStream(excelData);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "Data.xls"
        };
        return result;
    }
    catch (Exception ex)
    {
        m_logger.ErrorException("Exception exporting as excel file: ", ex);
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
}

Here is the coffeescript/javascript jquery ajax call from a button click in the interface.

这是通过单击界面中的按钮进行的​​ coffeescript/javascript jquery ajax 调用。

$.ajax(
    url: route
    dataType: 'json'
    type: 'GET'
    success: successCallback
    error: errorCallback 
    )

Now that I think about it perhaps the dataType is wrong and shouldn't be json...

现在我想起来也许 dataType 是错误的,不应该是 json ...

采纳答案by Neil

I had to make a couple of small changes to get this to work

我必须做一些小改动才能让它发挥作用

First: Change the method to a post

第一:把方法改成post

[AcceptVerbs("POST")]

Second: Change from using the jQuery ajax lib to use a hidden form, here's my service function for doing the hidden form and submitting it.

第二:从使用jQuery ajax lib改为使用隐藏表单,这里是我做隐藏表单并提交它的服务功能。

exportExcel: (successCallback) =>
    if $('#hidden-excel-form').length < 1
        $('<form>').attr(
            method: 'POST',
            id: 'hidden-excel-form',
            action: 'api/tools/exportXls'
        ).appendTo('body');

    $('#hidden-excel-form').bind("submit", successCallback)
    $('#hidden-excel-form').submit()

Hopefully there's a better way to do this but for the time being it's working and downloading the excel file nicely.

希望有更好的方法来做到这一点,但目前它正在工作并且可以很好地下载 excel 文件。

回答by Robert

This will return a file when you click a particular button

当您单击特定按钮时,这将返回一个文件

 public FileResult ExportXls(){
     //the byte stream is the file you want to return
     return File(bytes, "application/msexcel")
     }

回答by Leo

Works also as a HTTP GET method, but don't use $ajax, instead use window.open(url);

也可用作 HTTP GET 方法,但不要使用 $ajax,而是使用 window.open(url);

C# code:

C#代码:

    [HttpGet]
    [Route("report/{scheduleId:int}")]
    public HttpResponseMessage DownloadReport(int scheduleId)
    {
        var reportStream = GenerateExcelReport(scheduleId);
        var result = Request.CreateResponse(HttpStatusCode.OK);

        result.Content = new StreamContent(reportStream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "Schedule Report.xlsx"
        };

        return result;
    }

JS code:

JS代码:

downloadScheduleReport: function (scheduleId) {
    var url = baseUrl + 'api/Tracker/report/' + scheduleId;
    window.open(url);
}

回答by Seher Acar

I experienced the same problem. Problem solved with the following:

我遇到了同样的问题。问题通过以下方式解决:

window.open(url)

window.open(url)

回答by Neena Dadhwal

It will store the excel file created in a folder in the system and once its sent to Browser, it will be deleted .

它会将创建的 excel 文件存储在系统的文件夹中,一旦发送到浏览器,它将被删除。

     //path to store Excel file temporarily
     string tempPathExcelFile = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Hour + DateTime.Now.Minute +
                          DateTime.Now.Second + DateTime.Now.Millisecond +
                          "_temp";
        try
        {
            //Get Excel using  Microsoft.Office.Interop.Excel;
            Excel.Workbook workbook = ExportDataSetToExcel();
            workbook.SaveAs(tempPathExcelFile, workbook.FileFormat);
            tempPathExcelFile = workbook.FullName;
            workbook.Close();
            byte[] fileBook = File.ReadAllBytes(tempPathExcelFile);
            MemoryStream stream = new MemoryStream();
            string excelBase64String = Convert.ToBase64String(fileBook);
            StreamWriter excelWriter = new StreamWriter(stream);
            excelWriter.Write(excelBase64String);
            excelWriter.Flush();
            stream.Position = 0;
            HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
            httpResponseMessage.Content = new StreamContent(stream);
            httpResponseMessage.Content.Headers.Add("x-filename", "ExcelReport.xlsx");
            httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
            httpResponseMessage.Content.Headers.ContentDisposition =
                new ContentDispositionHeaderValue("attachment");
            httpResponseMessage.Content.Headers.ContentDisposition.FileName = "ExcelReport.xlsx";
            httpResponseMessage.StatusCode = HttpStatusCode.OK;
            return httpResponseMessage;

        }
        catch (Exception ex)
        {
            _logger.ErrorException(errorMessage, ex);
            return ReturnError(ErrorType.Error, errorMessage);
        }
        finally
        {
            if (File.Exists(tempPathExcelFile))
            {
                File.Delete(tempPathExcelFile);
            }
        }

      //Javascript Code
      $.ajax({
                    url:  "/api/exportReport",
                    type: 'GET',
                    headers: {
                        Accept: "application/vnd.ms-excel; base64",
                    },
                    success: function (data) {   
                        var uri = 'data:application/vnd.ms-excel;base64,' + data;
                        var link = document.createElement("a");    
                        link.href = uri;
                        link.style = "visibility:hidden";
                        link.download = "ExcelReport.xlsx";
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);                        
                    },
                    error: function () {
                        console.log('error Occured while Downloading CSV file.');
                    },
                }); 
    In the end create an empty anchor tag at the end of your html file. <a></a>