20

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

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

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

这是通过界面中的按钮单击进行的咖啡脚本/javascript jquery ajax 调用。

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

现在我考虑一下,也许 dataType 是错误的,不应该是 json ......

4

6 回答 6

16

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

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代码:

downloadScheduleReport: function (scheduleId) {
    var url = baseUrl + 'api/Tracker/report/' + scheduleId;
    window.open(url);
}
于 2016-10-25T14:20:27.243 回答
13

我必须做一些小改动才能让它工作

第一:将方法改为post

[AcceptVerbs("POST")]

第二:从使用 jQuery ajax 库更改为使用隐藏表单,这是我的服务函数,用于执行隐藏表单并提交它。

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

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

于 2013-02-12T13:37:02.547 回答
1

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

window.open(url)

于 2018-01-02T07:16:58.627 回答
1

它将创建的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>
于 2019-05-07T15:57:30.833 回答
0

对于.NetCore,您可以简单地将类型返回为文件。

public IActionResult ExportAsExcel()
        {
            try
            {
                using (var ms = new MemoryStream())
                {
                    var data = ExportData(); // Note: This Should be DataTable
                    data.ConvertAsStream(ms);
                    ms.Position = 0;
                    return File(ms.ToArray(), "application/octet-stream", "ExcelReport.xlsx");
                }
               
               
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
                throw;
            }
        }
于 2020-11-22T06:00:28.370 回答
-4

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

 public FileResult ExportXls(){
     //the byte stream is the file you want to return
     return File(bytes, "application/msexcel")
     }
于 2013-02-12T13:40:04.753 回答