2017-01-20 20 views
2

私はClosedXMLで作成したファイルをダウンロードしようとしています。ファイルが壊れていないことを確認しましたが、何らかの理由でAngular2ではなくAngular1だけで動作します。ファイルを返すためのWeb APIコードは次のとおりです。Angular2でAngular2のダウンロードはWeb APIからファイルが壊れています、ファイルが壊れています

HttpResponseMessage response = new HttpResponseMessage(); 
response.StatusCode = HttpStatusCode.OK; 
response.Content = new ByteArrayContent(ms.GetBuffer()); 
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
return response; 

、私のウェブサービスに:

let headers = new Headers(); 
headers.append('Content-Type', 'application/json'); 
headers.append('responseType', 'arrayBuffer'); 
this.observableDataGet = this._http.post(`${AppSettings.REPORTS_API_URL}/Report/MonthlySpreadsheet`, {headers: this.getHeaders()}) 
    .map(response => { 
     if (response.status == 400) { 
      return "FAILURE"; 
     } else if (response.status == 200) { 
      var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 
      var blob = new Blob([response.arrayBuffer()], { type: contentType }); 
      return blob; 
     } 
    }) 

と私のコンポーネントで:

.subscribe(blob => { 
    var downloadUrl= URL.createObjectURL(blob); 
    window.open(downloadUrl); 
}, 

ファイルがダウンロードされますが、アクセスしようとすると壊れてしまい、Angular1でダウンロードしたときにファイルのサイズは2倍になります。

Angular1でSAME APIを呼び出すと、ファイルが正常にダウンロードされます。

マイサービスコード:

alertAppService.generateMonthlySpreadsheet(header).then(function (data){ 
    var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}); 
    var objectUrl = URL.createObjectURL(blob); 
    window.open(objectUrl); 
:handleSuccessがサービスを呼び出すために(私はangular2のために取得することはできません)response.data

とコードを返す

function generateMonthlySpreadsheet(header) { 
    var request = $http({ 
     method: "post", 
     responseType: 'arraybuffer', 
     url: TEST_API_URL + 'Report/MonthlySpreadsheet', 
     timeout: 30000, 
     headers: header 
    }); 
    return (request.then(handleSuccess, handleError)); 
} 

興味深いことに、Angular2では、単に私のWebサービスをGETに変更した場合(私はPOSTを望んでいましたが、試してみたい)、サービスコードを取り除いて、単にこの呼び出しを行った場合、fiルで結構です:だから

window.open(`${AppSettings.REPORTS_API_URL}/Report/MonthlySpreadsheet`, "_blank"); 

、本当に、ここでの違いは何ですか?同じまたは非常に似たコードがAngular1では動作しますが、Angular2では動作しないのはなぜですか?

- カレン

答えて

3

私は他の人が同じ問題を発見したことを知っています。私はそれを解決しましたが、それを動作させるにはxhrに切り替える必要がありました。

この最初の方法は動作しません。私は上からややそれを簡素化:

generateMonthlySpreadsheet2(searchCriteria: Object) { 
     let headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     headers.append('responseType', 'blob'); 

     return this._http.post(`${AppSettings.REPORTS_API_URL}/Report/MonthlySpreadsheet`, {headers: headers}) 
      .map(response => { 
       if (response.status == 400) { 
        this.handleError; 
       } else if (response.status == 200) { 
        var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 
        var blob = new Blob([(<any>response)._body], { type: contentType });   // size is 89KB instead of 52KB 
//     var blob = new Blob([(<any>response).arrayBuffer()], { type: contentType }); // size is 98KB instead of 52KB 
//     var blob = new Blob([(<any>response).blob()], { type: contentType });   // received Error: The request body isn't either a blob or an array buffer 
        return blob; 
       } 
      }) 
      .catch(this.handleError); 
    } 

この第二の方法は、作業を行うものです。うまくいけば、これは他の人を助ける

generateMonthlySpreadsheet(searchCriteria: Object): Observable<Object[]> { 
    return Observable.create(observer => { 

     let xhr = new XMLHttpRequest(); 

     xhr.open('POST', `${AppSettings.REPORTS_API_URL}/Report/MonthlySpreadsheet`, true); 
     xhr.setRequestHeader('Content-type', 'application/json'); 
     xhr.responseType='blob'; 

     xhr.onreadystatechange = function() { 
      if (xhr.readyState === 4) { 
       if (xhr.status === 200) { 

        var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 
        var blob = new Blob([xhr.response], { type: contentType }); 
        observer.next(blob); 
        observer.complete(); 
       } else { 
        observer.error(xhr.response); 
       } 
      } 
     } 
     xhr.send(); 

    }); 
} 

!私はこの問題が他の場所に掲載されているのを見たので、そこに私のソリューションへのリンクも追加します。

- カレン

1

これは、(サービスが実際に応答としてのxlsxファイルを送り返していることを確認してください)私の仕事です:

  1. は、show「ファイルを保存」ポップアップのためにこれらの依存関係をインストールします。あなたのサービスで

    npm install file-saver --save-dev 
    npm install @types/file-saver --save-dev 
    
  2. インポート:

    import * as FileSaver from 'file-saver'; 
    
  3. 使用法:

    downloadFile(): void { 
        let url: string = “http://yourdomain.com/exports/excelExport.aspx”; 
        let headers = new Headers({ 'Content-Type': 'application/json'}); 
    
        //in case you have custom headers, else you can ignore this part 
    headers.set('x-custom-header1', “some value”); 
        headers.set('x-custom-header2', “some value2”); 
    
        let options = new RequestOptions({responseType: ResponseContentType.Blob, headers }); 
    
        this.http.get(url, options) 
         .map(res => res.blob()) 
         .subscribe(
         data => { 
    FileSaver.saveAs(data, 'Export.xlsx'); 
         }, 
         err => { 
          console.log('error'); 
          console.error(err); 
         }); 
    } 
    
1

これは私がスタイルの完全なファイルDwobnloadするために用いられる溶液である(色を...)

WEBAPI:

[HttpGet] 
     [Route("api/RapproResult/DownloadExcelReport/{reportName}")] 
     public HttpResponseMessage DownloadExcelReport(string reportName) 
     { 


      try 
      { 
       string filePath = HttpContext.Current.Server.MapPath("~/Report/Report_TEST.XLS"); 

       if (!string.IsNullOrEmpty(filePath)) 
       { 


        using (MemoryStream ms = new MemoryStream()) 
        { 
         using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
         { 
          byte[] bytes = new byte[file.Length]; 
          file.Read(bytes, 0, (int)file.Length); 
          ms.Write(bytes, 0, (int)file.Length); 

          HttpResponseMessage httpResponseMessage = new HttpResponseMessage(); 
          httpResponseMessage.Content = new ByteArrayContent(ms.GetBuffer()); 
          httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 
          httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 

          httpResponseMessage.StatusCode = HttpStatusCode.OK; 
          return httpResponseMessage; 
         } 
        } 
       } 
       return this.Request.CreateResponse(HttpStatusCode.NotFound, "File not found."); 
      } 
      catch (Exception ex) 
      { 
       return this.Request.CreateResponse(HttpStatusCode.InternalServerError, ex); 
      } 


     } 

これは角度サービス:

protected downloadExcelReportService(reportName: string) { 

     let completeUrl = this.downloadExcelReportUrl+reportName; 
     return Observable.create(observer => { 
      let xhr = new XMLHttpRequest(); 

      xhr.open('GET', completeUrl, true); 
      xhr.setRequestHeader('Content-type', 'application/json'); 
      xhr.responseType='blob'; 

      xhr.onreadystatechange = function() { 
       if (xhr.readyState === 4) { 
       if (xhr.status === 200) { 
        debugger; 
        var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 
        var blob = new Blob([xhr.response], { type: contentType }); 
        observer.next(blob); 
        observer.complete(); 
        return observer; 

       } else { 
        observer.error(xhr.response); 
       } 
       } 
      } 
      debugger; 
      xhr.send(); 
      }); 
    } 
私はそれがあなたの役に立てば幸い

そしてFileSaverアピ

import * as FileSaver from "file-saver"; 



downloadexcelReport(data) 
     { 
      this._servive.downloadExcelReport(data.RapproName) 
      .subscribe(
      _data => FileSaver.saveAs(_data, data.RapproName+".xls")), 
      error => console.log("Error downloading the file."), 
      () => console.log('Completed file download.'); 
     } 

を使用して最終的に角度成分方法。

関連する問題