I was able to solve it, here's the code, I'm using Angular Material , so the 'apsUploadFile' directive to leave the button of the input file in the style of the material 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>
Controller 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 spreadsheet processing I'm using the EPPlus library.