복붙노트

[JQUERY] AJAX MVC를 통해 Excel 파일을 다운로드

JQUERY

AJAX MVC를 통해 Excel 파일을 다운로드

해결법


  1. 1.직접 다른 접근 방식은 서버에 관련된 데이터를 게시하는 AJAX 호출을 사용하는 것입니다, 그래서 AJAX 호출을 통해 다운로드 할 파일을 반환 할 수 없습니다. 그런 다음 엑셀 파일을 생성하는 서버 측 코드를 사용할 수 있습니다 (나는 당신이이 부분 작업이있는 것처럼 소리가 있지만, 이것에 대한 EPPlus 또는 NPOI를 사용하는 것이 좋습니다).

    직접 다른 접근 방식은 서버에 관련된 데이터를 게시하는 AJAX 호출을 사용하는 것입니다, 그래서 AJAX 호출을 통해 다운로드 할 파일을 반환 할 수 없습니다. 그런 다음 엑셀 파일을 생성하는 서버 측 코드를 사용할 수 있습니다 (나는 당신이이 부분 작업이있는 것처럼 소리가 있지만, 이것에 대한 EPPlus 또는 NPOI를 사용하는 것이 좋습니다).

    그것은 일부 사용이 될 수 있기 때문에 나는 그러나 AJAX를 통해 파일을 다운로드 할 때 나는 더 이상 서버에 파일을 생성하지 않기 때문에 내가 업데이트 것이라고 생각 때문에 내 원래의 대답은 (아래), 이상 3 세였다, 나는 원래 대답을 떠난 여전히 따라 사용자의 특정 요구 사항.

    내 MVC 애플리케이션에서 일반적인 시나리오는 일부 사용자 설정 보고서 매개 변수 (날짜 범위, 필터 등)이있는 웹 페이지를 통해보고하고있다. 사용자가 서버에 게시 파라미터를 지정한 경우,보고는 (예를 들면 출력 된 엑셀 파일을 말한다)가 생성 된 후, I ​​고유 참조하여 TempData 양동이 바이트 배열로 결과 파일을 저장한다. 이 참조는 이후 최종 사용자의 브라우저에 TempData 다운로드에서 데이터를 추출하기 위해 별도의 컨트롤러 액션로 리디렉션 나의 AJAX 기능에 JSON 결과로 다시 전달됩니다.

    이 자세한 내용을 제공 당신이 모델 클래스에 바인드 양식을 가진 MVC보기를 가정하려면 모델 ReportVM를 호출 할 수 있습니다.

    첫째, 컨트롤러 액션이 게시 된 모델을받을 필요, 예는 다음과 같습니다

    public ActionResult PostReportPartial(ReportVM model){
    
       // Validate the Model is correct and contains valid data
       // Generate your report output based on the model parameters
       // This can be an Excel, PDF, Word file - whatever you need.
    
       // As an example lets assume we've generated an EPPlus ExcelPackage
    
       ExcelPackage workbook = new ExcelPackage();
       // Do something to populate your workbook
    
       // Generate a new unique identifier against which the file can be stored
       string handle = Guid.NewGuid().ToString();
    
       using(MemoryStream memoryStream = new MemoryStream()){
            workbook.SaveAs(memoryStream);
            memoryStream.Position = 0;
            TempData[handle] = memoryStream.ToArray();
       }      
    
       // Note we are returning a filename as well as the handle
       return new JsonResult() { 
             Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
       };
    
    }
    

    위의 컨트롤러에 게시물 내 MVC 양식을하고이 같은 응답 외모를 수신하는 AJAX 호출 :

    $ajax({
        cache: false,
        url: '/Report/PostReportPartial',
        data: _form.serialize(), 
        success: function (data){
             var response = JSON.parse(data);
             window.location = '/Report/Download?fileGuid=' + response.FileGuid 
                               + '&filename=' + response.FileName;
        }
    })
    

    컨트롤러의 동작은 파일의 다운로드를 처리하기 위해 :

    [HttpGet]
    public virtual ActionResult Download(string fileGuid, string fileName)
    {   
       if(TempData[fileGuid] != null){
            byte[] data = TempData[fileGuid] as byte[];
            return File(data, "application/vnd.ms-excel", fileName);
       }   
       else{
            // Problem - Log the error, generate a blank file,
            //           redirect to another controller action - whatever fits with your application
            return new EmptyResult();
       }
    }
    

    필요한 경우 쉽게 수용 할 수있는 또 하나의 변화는 하나 개의 컨트롤러 동작이 제대로 출력 파일 형식의 다양한 서비스를 제공 할 수 있도록 세 번째 매개 변수로 파일의 MIME 유형을 전달하는 것입니다.

    더 하우스 키핑 루틴이 필요하지 다시 한 번이 최종 사용자에게 원활한 그래서 이것은 생성되고 서버에 저장에 대한 실제 파일에 대한 필요성을 제거합니다.

    참고 아니라 세션보다 TempData를 사용하는 장점은 TempData 당신이 파일 요청의 높은 볼륨이있는 경우는 메모리 사용면에서보다 효율적으로 할 수 있도록 데이터가 지워 읽기되면. TempData 모범 사례를 참조하십시오.

    직접 다른 접근 방식은 서버에 관련된 데이터를 게시하는 AJAX 호출을 사용하는 것입니다, 그래서 AJAX 호출을 통해 다운로드 할 파일을 반환 할 수 없습니다. 그런 다음 엑셀 파일을 생성하는 서버 측 코드를 사용할 수 있습니다 (나는 당신이이 부분 작업이있는 것처럼 소리가 있지만, 이것에 대한 EPPlus 또는 NPOI를 사용하는 것이 좋습니다).

    파일이 서버에 생성되면 당신의 AJAX 호출에 반환 값으로 파일 경로 (또는 파일 이름)을 다시 통과 한 다음 파일을 다운로드 브라우저를 묻는 메시지가 표시됩니다이 URL에 자바 스크립트에서는 window.location을 설정 .

    그들은 페이지의 요청 유래를 떠나지 않을으로 최종 사용자의 관점에서, 파일 다운로드 작업이 원활.

    다음은이를 달성하기 위해 아약스 호출의 간단한 인위적인 예입니다 :

    $.ajax({
        type: 'POST',
        url: '/Reports/ExportMyData', 
        data: '{ "dataprop1": "test", "dataprop2" : "test2" }',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (returnValue) {
            window.location = '/Reports/Download?file=' + returnValue;
        }
    });
    

    다운로드 작업에 대한 샘플 컨트롤러 방법은 다음과 같습니다

    [HttpGet]
    public virtual ActionResult Download(string file)
    {   
      string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
      return File(fullPath, "application/vnd.ms-excel", file);
    }
    

  2. 2.내 2 센트는 - 대신 (세션) 캐시에 저장 - 당신은 서버의 물리적 파일로 엑셀을 저장할 필요가 없습니다. 캐쉬 변수의 고유 생성 된 이름을 사용합니다 (저장 엑셀 파일 있음가) -이 당신의 (초기) 아약스 호출의 반환 될 것입니다. 당신은 캐시에서 파일을 가지고, 등을 필요로하지 때 (삭제) 파일을 관리, 파일 액세스 문제를 처리하지 않아도이 방법을 검색 할 빠릅니다.

    내 2 센트는 - 대신 (세션) 캐시에 저장 - 당신은 서버의 물리적 파일로 엑셀을 저장할 필요가 없습니다. 캐쉬 변수의 고유 생성 된 이름을 사용합니다 (저장 엑셀 파일 있음가) -이 당신의 (초기) 아약스 호출의 반환 될 것입니다. 당신은 캐시에서 파일을 가지고, 등을 필요로하지 때 (삭제) 파일을 관리, 파일 액세스 문제를 처리하지 않아도이 방법을 검색 할 빠릅니다.


  3. 3.실제 파일을 만들지 않고 (이 AJAX를 사용할 필요가 없었다하지만) 나는 내 코드를 공유하고자 최근 MVC에서이 작업을 수행 할 수 있었다 :

    실제 파일을 만들지 않고 (이 AJAX를 사용할 필요가 없었다하지만) 나는 내 코드를 공유하고자 최근 MVC에서이 작업을 수행 할 수 있었다 :

    슈퍼 간단한 자바 스크립트 함수 (datatables.net 버튼 클릭이 트리거) :

    function getWinnersExcel(drawingId) {
        window.location = "/drawing/drawingwinnersexcel?drawingid=" + drawingId;
    }
    

    C # 컨트롤러 코드 :

        public FileResult DrawingWinnersExcel(int drawingId)
        {
            MemoryStream stream = new MemoryStream(); // cleaned up automatically by MVC
            List<DrawingWinner> winnerList = DrawingDataAccess.GetWinners(drawingId); // simple entity framework-based data retrieval
            ExportHelper.GetWinnersAsExcelMemoryStream(stream, winnerList, drawingId);
    
            string suggestedFilename = string.Format("Drawing_{0}_Winners.xlsx", drawingId);
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", suggestedFilename);
        }
    

    ExportHelper 클래스에서 나는 Excel 파일을 생성하기 위해 제 3 자 도구 (GemBox.Spreadsheet)를 사용 할 그리고 그것은 저장 스트림에 옵션이 있습니다. 존재가 말했다, 쉽게 메모리 스트림에 기록 할 수 Excel 파일을 생성하는 방법은 여러 가지가있을 수 있습니다.

    public static class ExportHelper
    {
        internal static void GetWinnersAsExcelMemoryStream(MemoryStream stream, List<DrawingWinner> winnerList, int drawingId)
        {
    
            ExcelFile ef = new ExcelFile();
    
            // lots of excel worksheet building/formatting code here ...
    
            ef.SaveXlsx(stream);
            stream.Position = 0; // reset for future read
    
         }
    }
    

    IE, 크롬, 파이어 폭스에서 브라우저 메시지는 파일을 다운로드하고 실제 탐색은 발생하지 않는다.


  4. 4.먼저 엑셀 파일을 생성합니다 컨트롤러 액션 만들기

    먼저 엑셀 파일을 생성합니다 컨트롤러 액션 만들기

    [HttpPost]
    public JsonResult ExportExcel()
    {
        DataTable dt = DataService.GetData();
        var fileName = "Excel_" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xls";
    
        //save the file to server temp folder
        string fullPath = Path.Combine(Server.MapPath("~/temp"), fileName);
    
        using (var exportData = new MemoryStream())
        {
            //I don't show the detail how to create the Excel, this is not the point of this article,
            //I just use the NPOI for Excel handler
            Utility.WriteDataTableToExcel(dt, ".xls", exportData);
    
            FileStream file = new FileStream(fullPath, FileMode.Create, FileAccess.Write);
            exportData.WriteTo(file);
            file.Close();
        }
    
        var errorMessage = "you can return the errors in here!";
    
        //return the Excel file name
        return Json(new { fileName = fileName, errorMessage = "" });
    }
    

    다음 다운로드 작업을 생성

    [HttpGet]
    [DeleteFileAttribute] //Action Filter, it will auto delete the file after download, 
                          //I will explain it later
    public ActionResult Download(string file)
    {
        //get the temp folder and file path in server
        string fullPath = Path.Combine(Server.MapPath("~/temp"), file);
    
        //return the file for download, this is an Excel 
        //so I set the file content type to "application/vnd.ms-excel"
        return File(fullPath, "application/vnd.ms-excel", file);
    }
    

    다운로드 후 파일을 삭제하고자 할 경우에 작성

    public class DeleteFileAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Flush();
    
            //convert the current filter context to file and get the file path
            string filePath = (filterContext.Result as FilePathResult).FileName;
    
            //delete the file after download
            System.IO.File.Delete(filePath);
        }
    }
    

    그리고 마지막으로 아약스 전화 당신의 MVC 면도기보기

    //I use blockUI for loading...
    $.blockUI({ message: '<h3>Please wait a moment...</h3>' });    
    $.ajax({
        type: "POST",
        url: '@Url.Action("ExportExcel","YourController")', //call your controller and action
        contentType: "application/json; charset=utf-8",
        dataType: "json",
    }).done(function (data) {
        //console.log(data.result);
        $.unblockUI();
    
        //get the file name for download
        if (data.fileName != "") {
            //use window.location.href for redirect to download action for download the file
            window.location.href = "@Url.RouteUrl(new 
                { Controller = "YourController", Action = "Download"})/?file=" + data.fileName;
        }
    });
    

  5. 5.나는 CSL에 의해 게시 솔루션을 사용하지만 난 당신이 전체 세션 동안 세션에서 파일 데이터를 저장 해달라고 추천 할 것입니다. TempData에게 파일 데이터를 이용하여 자동으로 (파일에 대한 GET 요청이다) 다음 요청 이후에 제거된다. 또한 다운로드 행동에 세션에서 파일 데이터의 제거를 관리 할 수 ​​있습니다.

    나는 CSL에 의해 게시 솔루션을 사용하지만 난 당신이 전체 세션 동안 세션에서 파일 데이터를 저장 해달라고 추천 할 것입니다. TempData에게 파일 데이터를 이용하여 자동으로 (파일에 대한 GET 요청이다) 다음 요청 이후에 제거된다. 또한 다운로드 행동에 세션에서 파일 데이터의 제거를 관리 할 수 ​​있습니다.

    세션 sessionState의 저장 및 얼마나 많은 파일 세션 중에 수출하고 있습니다 그리고 만약 당신이 많은 사용자를 가지고에 따라 많은 메모리 / 공간을 소모 할 수있다.

    내가 대신 TempData를 사용하는 CSL에서 서버 측 코드를 업데이트했습니다.

    public ActionResult PostReportPartial(ReportVM model){
    
       // Validate the Model is correct and contains valid data
       // Generate your report output based on the model parameters
       // This can be an Excel, PDF, Word file - whatever you need.
    
       // As an example lets assume we've generated an EPPlus ExcelPackage
    
       ExcelPackage workbook = new ExcelPackage();
       // Do something to populate your workbook
    
       // Generate a new unique identifier against which the file can be stored
       string handle = Guid.NewGuid().ToString()
    
       using(MemoryStream memoryStream = new MemoryStream()){
            workbook.SaveAs(memoryStream);
            memoryStream.Position = 0;
            TempData[handle] = memoryStream.ToArray();
       }      
    
       // Note we are returning a filename as well as the handle
       return new JsonResult() { 
             Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
       };
    
    }
    
    [HttpGet]
    public virtual ActionResult Download(string fileGuid, string fileName)
    {   
       if(TempData[fileGuid] != null){
            byte[] data = TempData[fileGuid] as byte[];
            return File(data, "application/vnd.ms-excel", fileName);
       }   
       else{
            // Problem - Log the error, generate a blank file,
            //           redirect to another controller action - whatever fits with your application
            return new EmptyResult();
       }
    }
    

  6. 6.ClosedXML.Excel을 사용함;

    ClosedXML.Excel을 사용함;

       public ActionResult Downloadexcel()
        {   
            var Emplist = JsonConvert.SerializeObject(dbcontext.Employees.ToList());
            DataTable dt11 = (DataTable)JsonConvert.DeserializeObject(Emplist, (typeof(DataTable)));
            dt11.TableName = "Emptbl";
            FileContentResult robj;
            using (XLWorkbook wb = new XLWorkbook())
            {
                wb.Worksheets.Add(dt11);
                using (MemoryStream stream = new MemoryStream())
                {
                    wb.SaveAs(stream);
                    var bytesdata = File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "myFileName.xlsx");
                    robj = bytesdata;
                }
            }
    
    
            return Json(robj, JsonRequestBehavior.AllowGet);
        }
    

  7. 7.

    $.ajax({
                    type: "GET",
                    url: "/Home/Downloadexcel/",
                    contentType: "application/json; charset=utf-8",
                    data: null,
                    success: function (Rdata) {
                        debugger;
                        var bytes = new Uint8Array(Rdata.FileContents); 
                        var blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
                        var link = document.createElement('a');
                        link.href = window.URL.createObjectURL(blob);
                        link.download = "myFileName.xlsx";
                        link.click();
                    },
                    error: function (err) {
    
                    }
    
                });
    

  8. 8.나는 모든 컨트롤러에서 벌금을 반환 할 듯 비록 아약스 호출에서 502 잘못된 게이트웨이 결과를 얻었다으로 허용 대답은 나를 위해 잘 작동하지 않았다.

    나는 모든 컨트롤러에서 벌금을 반환 할 듯 비록 아약스 호출에서 502 잘못된 게이트웨이 결과를 얻었다으로 허용 대답은 나를 위해 잘 작동하지 않았다.

    아마도 내가 TempData와 한계 치는되었다 - 확실하지,하지만 내가 대신 TempData의 IMemoryCache를 사용하는 경우, 그것은 벌금을 잘되었다, 그래서 여기 허용 대답의 코드 내 적응 버전입니다 :

    public ActionResult PostReportPartial(ReportVM model){
    
       // Validate the Model is correct and contains valid data
       // Generate your report output based on the model parameters
       // This can be an Excel, PDF, Word file - whatever you need.
    
       // As an example lets assume we've generated an EPPlus ExcelPackage
    
       ExcelPackage workbook = new ExcelPackage();
       // Do something to populate your workbook
    
       // Generate a new unique identifier against which the file can be stored
       string handle = Guid.NewGuid().ToString();
    
       using(MemoryStream memoryStream = new MemoryStream()){
            workbook.SaveAs(memoryStream);
            memoryStream.Position = 0;
            //TempData[handle] = memoryStream.ToArray();
    
            //This is an equivalent to tempdata, but requires manual cleanup
            _cache.Set(handle, memoryStream.ToArray(), 
                        new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(10))); 
                        //(I'd recommend you revise the expiration specifics to suit your application)
    
       }      
    
       // Note we are returning a filename as well as the handle
       return new JsonResult() { 
             Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
       };
    
    }
    

    허용 대답 (I은 변경하지)와 마찬가지로 AJAX 호출 남아 :

    $ajax({
        cache: false,
        url: '/Report/PostReportPartial',
        data: _form.serialize(), 
        success: function (data){
             var response = JSON.parse(data);
             window.location = '/Report/Download?fileGuid=' + response.FileGuid 
                               + '&filename=' + response.FileName;
        }
    })
    

    컨트롤러의 동작은 파일의 다운로드를 처리하기 위해 :

    [HttpGet]
    public virtual ActionResult Download(string fileGuid, string fileName)
    {   
        if (_cache.Get<byte[]>(fileGuid) != null)
        {
            byte[] data = _cache.Get<byte[]>(fileGuid);
            _cache.Remove(fileGuid); //cleanup here as we don't need it in cache anymore
            return File(data, "application/vnd.ms-excel", fileName);
        }
        else
        {
            // Something has gone wrong...
            return View("Error"); // or whatever/wherever you want to return the user
        }
    }
    

    ...

    이제 MemoryCache을 설정하기위한 몇 가지 추가 코드가 ...

    사용하기 위해 "_cache는"I 그래서 같은 컨트롤러 생성자 주입 :

    using Microsoft.Extensions.Caching.Memory;
    namespace MySolution.Project.Controllers
    {
     public class MyController : Controller
     {
         private readonly IMemoryCache _cache;
    
         public LogController(IMemoryCache cache)
         {
            _cache = cache;
         }
    
         //rest of controller code here
      }
     }
    

    그리고 확실히 당신은 Startup.cs에서 ConfigureServices에 다음이 있는지 확인하십시오 :

    services.AddDistributedMemoryCache();
    

  9. 9.이 스레드는 제가 여기에 공유하는 것을 내 자신의 솔루션을 만들 수있었습니다. 나는 문제없이 처음에는 GET 아약스 요청을 사용했지만 그것은 내가 POST에 swith를해야했다하도록 요청 URL 길이를 초과 한 지점에 도착.

    이 스레드는 제가 여기에 공유하는 것을 내 자신의 솔루션을 만들 수있었습니다. 나는 문제없이 처음에는 GET 아약스 요청을 사용했지만 그것은 내가 POST에 swith를해야했다하도록 요청 URL 길이를 초과 한 지점에 도착.

    자바 스크립트 JQuery와 파일 다운로드 플러그인을 사용하고,이 이후의 호출로 구성되어 있습니다. 하나 POST (PARAMS를 보내려면) 한 GET 파일을 retreive합니다.

     function download(result) {
            $.fileDownload(uri + "?guid=" + result,
            {
                successCallback: onSuccess.bind(this),
                failCallback: onFail.bind(this)
            });
        }
    
        var uri = BASE_EXPORT_METADATA_URL;
        var data = createExportationData.call(this);
    
        $.ajax({
            url: uri,
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(data),
            success: download.bind(this),
            fail: onFail.bind(this)
        });
    

    서버 측

        [HttpPost]
        public string MassExportDocuments(MassExportDocumentsInput input)
        {
            // Save query for file download use
            var guid = Guid.NewGuid();
            HttpContext.Current.Cache.Insert(guid.ToString(), input, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration);
            return guid.ToString();
        }
    
       [HttpGet]
        public async Task<HttpResponseMessage> MassExportDocuments([FromUri] Guid guid)
        {
            //Get params from cache, generate and return
            var model = (MassExportDocumentsInput)HttpContext.Current.Cache[guid.ToString()];
              ..... // Document generation
    
            // to determine when file is downloaded
            HttpContext.Current
                       .Response
                       .SetCookie(new HttpCookie("fileDownload", "true") { Path = "/" });
    
            return FileResult(memoryStream, "documents.zip", "application/zip");
        }
    

  10. 10.CSL의 대답은 내가 일하고 있어요 프로젝트에서 구현했지만, 난이 푸른에 수평 확장되었다 발생하는 문제는 우리의 파일 다운로드를 끊었다. 대신, 하나의 AJAX 호출이 작업을 수행 할 수 있었다 :

    CSL의 대답은 내가 일하고 있어요 프로젝트에서 구현했지만, 난이 푸른에 수평 확장되었다 발생하는 문제는 우리의 파일 다운로드를 끊었다. 대신, 하나의 AJAX 호출이 작업을 수행 할 수 있었다 :

    섬기는 사람

    [HttpPost]
    public FileResult DownloadInvoice(int id1, int id2)
    {
        //necessary to get the filename in the success of the ajax callback
        HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
    
        byte[] fileBytes = _service.GetInvoice(id1, id2);
        string fileName = "Invoice.xlsx";
        return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    }
    

    고객 (아약스 게시물에서 핸들 파일 다운로드 수정 된 버전)

    $("#downloadInvoice").on("click", function() {
        $("#loaderInvoice").removeClass("d-none");
    
        var xhr = new XMLHttpRequest();
        var params = [];
        xhr.open('POST', "@Html.Raw(Url.Action("DownloadInvoice", "Controller", new { id1 = Model.Id1, id2 = Model.Id2 }))", true);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function () {
            if (this.status === 200) {
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                }
                var type = xhr.getResponseHeader('Content-Type');
    
                var blob = typeof File === 'function'
                    ? new File([this.response], filename, { type: type })
                    : new Blob([this.response], { type: type });
                if (typeof window.navigator.msSaveBlob !== 'undefined') {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    var URL = window.URL || window.webkitURL;
                    var downloadUrl = URL.createObjectURL(blob);
    
                    if (filename) {
                        // use HTML5 a[download] attribute to specify filename
                        var a = document.createElement("a");
                        // safari doesn't support this yet
                        if (typeof a.download === 'undefined') {
                            window.location = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location = downloadUrl;
    
                    }
    
                    setTimeout(function() {
                            URL.revokeObjectURL(downloadUrl);
                        $("#loaderInvoice").addClass("d-none");
                    }, 100); // cleanup
                }
            }
        };
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.send($.param(params));
    });
    

  11. 11.

      $.ajax({
        global: false,
        url: SitePath + "/User/ExportTeamMembersInExcel",
        "data": { 'UserName': UserName, 'RoleId': RoleId, UserIds: AppraseeId },
        "type": "POST",
        "dataType": "JSON",
       "success": function (result) {
            debugger
            var bytes = new Uint8Array(result.FileContents);
            var blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = "myFileName.xlsx";
            link.click();
          },
        "error": function () {
            alert("error");
        }
    })
    
    
    [HttpPost]
        public JsonResult ExportTeamMembersInExcel(string UserName, long? RoleId, string[] UserIds)
        {
            MemoryStream stream = new MemoryStream();
            FileContentResult robj;
            DataTable data = objuserservice.ExportTeamToExcel(UserName, RoleId, UserIds);
            using (XLWorkbook wb = new XLWorkbook())
            {
                wb.Worksheets.Add(data, "TeamMembers");
                using (stream)
                {
                    wb.SaveAs(stream);
                }
            }
            robj = File(stream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "TeamMembers.xlsx");
            return Json(robj, JsonRequestBehavior.AllowGet);
        }
    

  12. 12.나는 매우 순진한 소리로 들리 겠지만, 꽤 비판을 끌 수 있지만, 여기에 어떻게 내가 해냈어 (그것은 수출 아약스 포함되지 않지만, 중 전체 다시 게시하지 않습니다)

    나는 매우 순진한 소리로 들리 겠지만, 꽤 비판을 끌 수 있지만, 여기에 어떻게 내가 해냈어 (그것은 수출 아약스 포함되지 않지만, 중 전체 다시 게시하지 않습니다)

    이 게시물이 답변을 주셔서 감사합니다. 간단한 컨트롤러 만들기

    public class HomeController : Controller
    {               
       /* A demo action
        public ActionResult Index()
        {           
            return View(model);
        }
       */
        [HttpPost]
        public FileResult ExportData()
        {
            /* An example filter
            var filter = TempData["filterKeys"] as MyFilter;
            TempData.Keep();            */
            var someList = db.GetDataFromDb(/*filter*/) // filter as an example
    
        /*May be here's the trick, I'm setting my filter in TempData["filterKeys"] 
         in an action,(GetFilteredPartial() illustrated below) when 'searching' for the data,
         so do not really need ajax here..to pass my filters.. */
    
         //Some utility to convert list to Datatable
         var dt = Utility.ConvertToDataTable(someList); 
    
          //  I am using EPPlus nuget package 
          using (ExcelPackage pck = new ExcelPackage())
          {
              ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Sheet1");
              ws.Cells["A1"].LoadFromDataTable(dt, true);
    
                using (var memoryStream = new MemoryStream())
                {                   
                  pck.SaveAs(memoryStream);
                  return File(memoryStream.ToArray(),
                  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                  "ExportFileName.xlsx");                    
                }                
            }   
        }
    
        //This is just a supporting example to illustrate setting up filters ..        
       /* [HttpPost]
        public PartialViewResult GetFilteredPartial(MyFilter filter)
        {            
            TempData["filterKeys"] = filter;
            var filteredData = db.GetConcernedData(filter);
            var model = new MainViewModel();
            model.PartialViewModel = filteredData;
    
            return PartialView("_SomePartialView", model);
        } */     
    } 
    

    그리고 여기 조회수는 ..

    /*Commenting out the View code, in order to focus on the imp. code     
     @model Models.MainViewModel
     @{Layout...}     
    
          Some code for, say, a partial View  
          <div id="tblSampleBody">
            @Html.Partial("_SomePartialView", Model.PartialViewModel)
          </div>
      */                                                       
    //The actual part.. Just **posting** this bit of data from the complete View...
    //Here, you are not posting the full Form..or the complete View
       @using (Html.BeginForm("ExportData", "Home", FormMethod.Post))
        {
            <input type="submit" value="Export Data" />
        }
    //...
    //</div>
    
    /*And you may require to pass search/filter values.. as said in the accepted answer..
    That can be done while 'searching' the data.. and not while
     we need an export..for instance:-             
    
    <script>             
      var filterData = {
          SkipCount: someValue,
          TakeCount: 20,
          UserName: $("#UserName").val(),
          DepartmentId: $("#DepartmentId").val(),     
       }
    
      function GetFilteredData() {
           $("#loader").show();
           filterData.SkipCount = 0;
           $.ajax({
              url: '@Url.Action("GetFilteredPartial","Home")',
              type: 'POST',
              dataType: "html",
              data: filterData,
              success: function (dataHTML) {
              if ((dataHTML === null) || (dataHTML == "")) {
                  $("#tblSampleBody").html('<tr><td>No Data Returned</td></tr>');
                    $("#loader").hide();
                } else {
                    $("#tblSampleBody").html(dataHTML);                    
                    $("#loader").hide();
                }
            }
         });
       }    
    </script>*/
    

    트릭의 요점은 우리가 양식 (면도기보기의 일부)되는에 우리는의 조치 방법, 반환 요구하고있다 게시, 즉 보인다하십시오 FileResult를,이 FileResult는 엑셀 파일을 반환합니다 .. 그리고 필터 값을 게시, 같은, 내가 다른 액션에 게시 요청을하고 같은 설명하기 위해 시도되었다 말했다 (당신이 필요한 경우 등) ..


  13. 13.나는 Asp.Net WebForm에 사용하고 그냥 내가 서버 측에서 파일을 다운로드 싶어요. 이 많은 기사는하지만, 난 그냥 기본적인 해답을 찾을 수 없습니다. 지금, 나는 기본적인 방법을 시도하고있어.

    나는 Asp.Net WebForm에 사용하고 그냥 내가 서버 측에서 파일을 다운로드 싶어요. 이 많은 기사는하지만, 난 그냥 기본적인 해답을 찾을 수 없습니다. 지금, 나는 기본적인 방법을 시도하고있어.

    그건 내 문제입니다.

    나는 런타임에 동적으로 입력 버튼을 많이 만들어야합니다. 그리고 나는 독특한 가진 FileNumber을주는 다운로드 버튼 각 버튼을 추가하고 싶습니다.

    이 같은 각 버튼을 만듭니다

    단편 + = "

    ";

    각 버튼은이 아약스 메서드를 호출합니다.

    {(아약스 $ 입력 : 'POST', URL : 'index.aspx / CreateExcelFile' 데이터 : jsonData, contentType의 '응용 프로그램 / JSON; 캐릭터 = UTF-8 ', dataType와 'JSON' 성공 : 기능 (ReturnValue를) { 에서는 window.location = '/ 보고서 / 다운로드 /'+ returnValue.d; } });

    그럼 기본적인 간단한 방법을 썼다.

    [WebMethod]
    public static string CreateExcelFile2(string fileNumber)
    {
        string filePath = string.Format(@"Form_{0}.xlsx", fileNumber);
        return filePath;
    }
    

    나는이 Form_1, Form_2, Form_3를 생성하고 .... 그리고 다른 프로그램이 오래된 파일을 삭제하기 위하여려고하고있다. 그러나 단지 응답을 사용하여 같은 다운로드 파일에 바이트 배열을 전송하는 방법이있는 경우. 나는 그것을 사용 싶어요.

    나는이 사람에게 유용하게 사용될 수 있기를 바랍니다.


  14. 14.양식 제출에

    양식 제출에

    public ActionResult ExportXls()
    {   
     var filePath="";
      CommonHelper.WriteXls(filePath, "Text.xls");
    }
    
     public static void WriteXls(string filePath, string targetFileName)
        {
            if (!String.IsNullOrEmpty(filePath))
            {
                HttpResponse response = HttpContext.Current.Response;
                response.Clear();
                response.Charset = "utf-8";
                response.ContentType = "text/xls";
                response.AddHeader("content-disposition", string.Format("attachment; filename={0}", targetFileName));
                response.BinaryWrite(File.ReadAllBytes(filePath));
                response.End();
            }
        }
    
  15. from https://stackoverflow.com/questions/16670209/download-excel-file-via-ajax-mvc by cc-by-sa and MIT license