How to upload and download the same request using Angularjs and Web api?

Asked

Viewed 1,032 times

3

I am developing a functionality that will receive a spreadsheet in format . xlsx, will perform a processing and return this sheet with the columns added, in which case I should upload a file and in Success would download. In my attempts either I can send the file or just receive not got both without corrupting the return file, in the following code I can receive the file, perform the processing and perform the download however the file comes corrupted, I do not believe it is a problem in my api because if I make a call get or even post I can download the file.

Angular

 // chamada do upload.
$scope.uploadFiles = function () {

    //FILL FormData WITH FILE DETAILS.
    var data = new FormData();

    for (var i in $scope.files) {
        data.append("uploadedFile", $scope.files[i]);
    }

    // ADD LISTENERS.
    var objXhr = new XMLHttpRequest();
    objXhr.responseType = "arraybuffer";
    //objXhr.setRequestHeader("Accept", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    objXhr.onload = onsuccess;
    objXhr.onerror = onerror;

    // SEND FILE DETAILS TO THE API.
    objXhr.open("POST", "/api/v1/public/PostContent");
    objXhr.send(data);

    function onsuccess(result) {
        if (result == null) {
            toastr["error"]("RETORNO NULO", "Título da mensagem");
        }
        var blob = new Blob([result], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
        var objectUrl = URL.createObjectURL(blob);
        window.open(objectUrl);
    };

    function onerror(result) {

        if (result.status == 415) {
            toastr["error"]("Arquivo não suportado", "Título da mensagem");
        } else {
            toastr["error"]("Erro ao tentar ler o arquivo", "Título da mensagem");
        }
    };
}

Web Api Controller

[HttpPost]
    [Route("PostContent")]
    public async Task<HttpResponseMessage> PostContent()
    {
        if (!Request.Content.IsMimeMultipartContent())
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

        CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data"));

        await Request.Content.ReadAsMultipartAsync(provider);
        MultipartFileData file = provider.FileData.FirstOrDefault();

        FileInfo info = new FileInfo(file.LocalFileName);
        var package = new ExcelPackage(info)
        //PROCESSAMENTO DA PLANILHA

            MemoryStream ms = new MemoryStream();

            package.SaveAs(ms);

            var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(ms.GetBuffer())
            };
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
            {
                FileName = $"Vai{ DateTime.Now }.xlsx"
            };
            return result;
}

In View Loading the file

        <input type="file" id="file" name="file" multiple
               onchange="angular.element(this).scope().getFileDetails(this)" />

        <button type="button" ng-click="uploadFiles()">Carregar</button>

Someone knows how to do it?

1 answer

1


I managed to solve, it follows as it was the code, I am using Angular Material so the 'apsUploadFile' directive to leave the input file button in the material style design.

Angular

    app.controller('processoCtrl', function ($scope, $http, $location) {

        function send(data, uploadUrl, success, error) {
                var fd = new FormData();
                for (var key in data) {
                    fd.append(key, data[key]);
                }
                return $http.post(uploadUrl, fd, {
                    headers: { 'Content-Type': undefined },
                    responseType: 'arraybuffer'
                });
            };

        $scope.uploadArquivo = function (data) {
                var upload = { data: data };
                var uploadUrl = 'api/enviaraquivo';
                var nomearquivo = $('input').val().split('\\')[2].split('.')[0];
                send(upload, uploadUrl).
                    then(function (result, status, xhr) {
                        $scope.actived = !$scope.actived;
                        $scope.publicacaonaoencontrada = false;
                        $("#upload").prop('disabled', false);
                        var filename = nomearquivo + '_Analisada_.xlsx';
                        var blob = new Blob([result.data], { type:     "application/octet-stream" });
                        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); }, 100);
                        }
                       alert('arquivo processado com sucesso');
                    }, function (result) {
                        $("#upload").prop('disabled', false);

                        if (result.status == 401) {
                            alert('acesso não autorizado, realize o login');
                        } else {
                            alert('Arquivo fora dos padrões');
                        }

                    });
            }
    }).directive('apsUploadFile', apsUploadFile);
//Código para colocar um design material no input file

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        template: '<input id="upload"  accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" type="file" class="ng-hide" file-model="upload">' +
            ' <md-button id="uploadButton" class="md-raised md-primary" aria-label="attach_file"> Carregar planilha </md-button>' +
            '<md-input-container class="input-file-text" md-no-float><input id="textInput" ng-model="fileName" type="text" placeholder="Nenhum arquivo selecionado" ng-readonly="true"></md-input-container>' +
            '<md-button class="md-raised md-primary" ng-disabled="upload == null" ng-click="uploadArquivo(upload)">Upload</md-button>',
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs) {
    var input = $(element[0].querySelector('#upload'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function (e) {
            input.click();
        });
        textInput.click(function (e) {
            input.click();
        });
    }

    input.on('change', function (e) {
        var files = e.target.files;
        if (files[0]) {
            scope.fileName = files[0].name;
        } else {
            scope.fileName = null;
        }
        scope.$apply();
    });
}

View

<div ng-controller="processoCtrl as processo">
    <div class="upload-page">
        <div class="form">
            <form method="post" target="hidden-form">
                <h2>Carregue o arquivo</h2>
                <div class="form">
                    <div class="input-group">
                        <md-content layout-padding layout="row" layout-align="start end">
                            <aps-upload-file style="text-align: center;"></aps-upload-file>
                        </md-content>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

Controler Web Api

 [HttpPost]
    [Route("enviararquivo")]
    public async Task<HttpResponseMessage> PostArquivo()
    {

        if (!Request.Content.IsMimeMultipartContent())
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

        try
        {
            CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data"));
            await Request.Content.ReadAsMultipartAsync(provider);

            MultipartFileData file = provider.FileData.FirstOrDefault();

            FileInfo info = new FileInfo(file.LocalFileName);
            var planilhaDaRequisicao = new ExcelPackage(info);
            MemoryStream streamPlanilhaRequisicao = new MemoryStream();
            planilhaDaRequisicao.SaveAs(streamPlanilhaRequisicao);

            var streamPlanilhaAnalizada = servicePublicacao.VerificaPublicacao(streamPlanilhaRequisicao);
            var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(streamPlanilhaAnalizada.GetBuffer())
            };
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
            {
                FileName = $"download{ DateTime.Now }.xlsx"
            };

            return result;
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Arquivo fora dos padrões para consulta");
        }
    }

For worksheet processing I am using the library Epplus.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.