programing

WebApi 호출을 통해 페이지에서 Excel 파일 다운로드

bestprogram 2023. 7. 6. 22:25

WebApi 호출을 통해 페이지에서 Excel 파일 다운로드

9MB를 보내려고 합니다..xls파일을 webapi 컨트롤러 메서드의 응답으로 사용할 수 있습니다.사용자가 페이지의 버튼을 클릭하면 브라우저를 통해 다운로드가 트리거됩니다.

지금까지 제가 얻은 것은 이렇지만 작동하지는 않지만 어떤 예외도 던지지 않습니다.

[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 agax 호출입니다.

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

지금 생각해보면, 아마도 dataType이 잘못되었고 json이 되어서는 안 됩니다...

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

저는 이 일을 하기 위해 몇 가지 작은 변화를 해야 했습니다.

첫 번째: 게시물로 메서드 변경

[AcceptVerbs("POST")]

두 번째: jQuery agax 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()

이를 위한 더 나은 방법이 있기를 바라지만 당분간은 작동하고 엑셀 파일을 멋지게 다운로드하는 것입니다.

저도 같은 문제를 겪었습니다.다음을 통해 문제가 해결되었습니다.

window.open(url)

생성된 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>

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

특정 버튼을 클릭하면 파일이 반환됩니다.

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

언급URL : https://stackoverflow.com/questions/14831860/download-excel-file-from-page-via-webapi-call