web-dev-qa-db-fra.com

Télécharger le fichier Excel à partir de la page via l'appel Web Api

J'essaie d'envoyer un 9 Mo .xls fichier comme réponse de la méthode du contrôleur web api. L'utilisateur cliquera sur un bouton de la page et cela déclenchera le téléchargement via le navigateur.

Voici ce que j'ai jusqu'à présent, mais cela ne fonctionne pas, mais il ne génère aucune exception non plus.

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

Voici l'appel ajees coffeescript/javascript jquery à partir d'un clic de bouton dans l'interface.

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

Maintenant que j'y pense, le dataType est peut-être faux et ne devrait pas être json ...

18
Neil

J'ai dû faire quelques petits changements pour que cela fonctionne

Tout d'abord: changez la méthode en une publication

[AcceptVerbs("POST")]

Deuxièmement: Changez d'utiliser la bibliothèque jQuery ajax pour utiliser un formulaire caché, voici ma fonction de service pour faire le formulaire caché et le soumettre.

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

Espérons qu'il existe une meilleure façon de le faire, mais pour le moment, cela fonctionne et télécharge bien le fichier Excel.

12
Neil

Fonctionne également comme méthode HTTP GET, mais n'utilisez pas $ ajax, utilisez plutôt window.open (url);

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

Code JS:

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

J'ai rencontré le même problème. Problème résolu avec les éléments suivants:

window.open(url)

1
Seher Acar

Il stockera le fichier Excel créé dans un dossier du système et une fois envoyé au navigateur, il sera supprimé.

     //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