2014-09-02 3 views
8

Я создаю файл Excel в своем WebAPI. Я «магазин» это в MemoryStream, а затем положить в ответ, как следующие:WebAPI и угловой файл в формате JS Excel - файл поврежден

var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(ms) }; 

      result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
      result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
      { 
       FileName = projectName + ".xlsx" 
      }; 
      // ms.Close(); 
      return result; 

Похоже на стороне сервера работает correcty. Если я напишу этот memystream в файл, файл будет создан и может быть открыт без каких-либо проблем.

С угловой стороны, как я могу воссоздать файл при нажатии на кнопку?

Я пытался что-то вроде этого:

$scope.exportQuotas = function (projectName) { 
    homeService.GetQuotas(projectName, $routeParams.token, $scope.selection).then(
      function (data) { 
       var dataUrl = 'data:application/octet-stream;' + data 
       var link = document.createElement('a'); 
       angular.element(link) 
        .attr('href', dataUrl) 
        .attr('download', "bl.xlsx") 
        .attr('target', '_blank') 
       link.click(); 
      }) 
} 

создан файл, но когда я попытался открыть его, он поврежден ... Я попытался изменить тип данных для vnd.ms-первенствовать в угловой но это не сработало ... Как я могу получить файл для загрузки по клику?

EDIT После Йорг ответа, я попробовал следующее: Что возвращает АФИ:

Status Code: 200 
Pragma: no-cache 
Date: Tue, 02 Sep 2014 02:00:24 GMT 
Server: Microsoft-IIS/8.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Content-Type: application/binary 
Access-Control-Allow-Origin: * 
Cache-Control: no-cache 
X-SourceFiles: =?UTF-8?B?  QzpcVXNlcnNcdHJpaGFuaC5waGFtXFByb2plY3RzXFF1b3RhUXVlcnlcUXVvdGFRdWVyeUFQSVxhcGlccXVvdGFcR2V0?= 
Content-Disposition: attachment; filename=O14Y0129AUG.xlsx 
Content-Length: 13347 
Expires: -1 

Из того, что я могу видеть, это выглядит правильно.

В стороне клиента:

    var file = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' }); 
       var fileURL = URL.createObjectURL(file); 
       window.open(fileURL); 

первенствует файл создается, но это все-таки поврежден ...

Благодаря

+0

Я получил свою работу следующим образом: http://stackoverflow.com/questions/22447952/angularjs-http-post-convert-binary-to-excel-file-and-download/22448640#22448640 – Jorg

+0

Это не работа для меня, хотя :(файл поврежден ... также как metionned, имя файла странно ... – user2522221

+0

является 'data' base64? – Jorg

ответ

16

Я была такая же проблема. Файл был в порядке на стороне сервера, но при загрузке он стал поврежденным.

Что для меня решило, так это добавить responseType: "arraybuffer" к запросу сервера.

Тогда при вызове этой линии var file = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' }); Переменная data должна быть типа ArrayBuffer, а не строки.

+2

Не могли бы вы предоставить полный код того, как вы добавили responseType:" arraybuffer "к серверный запрос? – Shivam657

+3

@ Shivam657 Так вы добавляете тип ответа к вашему запросу: '$ http.get (url, {responseType:" arraybuffer "})' – daniel

+0

Не работает с использованием угловых сервисов. – Shivam657

1

Основная проблема связана с тем, что по умолчанию XMLHttpRequest использует тип ответа по умолчанию, который является пустой строкой. См. Это link. Поэтому ваши двоичные данные неправильно обрабатываются.

При использовании javascript API вам необходимо позаботиться о типе ответа для двоичных данных. В противном случае он будет интерпретироваться как строка.

API, такой как загрузка с угловым файлом (последняя версия в настоящее время составляет 1.1.5), например, не дает возможности установить тип ответа данных, полученных после загрузки. Мне пришлось обновить API для определения типа ответа.