web-dev-qa-db-ja.com

Web Api呼び出しを介してページからExcelファイルをダウンロードする

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

以下は、インターフェースのボタンクリックからのcoffeescript/javascript jquery ajax呼び出しです。

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

考えてみると、おそらくdataTypeが間違っていて、jsonであってはいけません...

17
Neil

これを機能させるには、いくつかの小さな変更を行う必要がありました

最初:メソッドを投稿に変更します

[AcceptVerbs("POST")]

2番目: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()

これを行うためのより良い方法があればいいのですが、とりあえずはうまく機能し、Excelファイルをうまくダウンロードしています。

12
Neil

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);
}
10
Leo

同じ問題が発生しました。以下で解決された問題:

window.open(url)

1
Seher Acar

システム内のフォルダーに作成された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>
0
Neena Dadhwal