2017-08-24 194 views
0

我無法使其通過web API下載由closedxml創建的excel文件。 如果我將文件保存在服務器上,它看起來不錯,但只要我把它放入一個流中並將它返回給web api,那麼在瀏覽器中只會收到一個損壞的文件。使用closedxml從web api下載excel文件

正如在幾篇文章中建議我使用httpResponseMessage,但也在瀏覽器中的頭文件名永遠不會到達。

我們使用:

「Microsoft.AspNet.WebApi」 版本= 「5.2.3」 targetFramework = 「net461

」ClosedXML「 版本=」 0.88.0" targetFramework = 「net461」

的WebAPI代碼:

var wb = new XLWorkbook(); 
      var ws = wb.Worksheets.Add("Parcel List"); 


      MemoryStream fs = new MemoryStream(); 
      wb.SaveAs(fs); 
      fs.Position = 0; 


      HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
      result.Content = new ByteArrayContent(fs.GetBuffer()); 
      result.Content.Headers.ContentLength = fs.Length; 
      result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
      { 
       FileName = "List" + "_" + DateTime.Now.ToShortDateString() + ".xlsx" 
      }; 
      result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 

      return result; 

下面的JavaScript代碼:

context.$http.post(config.get_API_URL() + 'api_call', excel_list, 
     {responseType: 'application/octet-stream'}) 
    .then(
    success_function, 
    error_function) 
} 

success_function:

function(response) { 

        var headers = response.headers; 
       var blob = new Blob([response.body], 
            {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}, 
            ); 

       window.open(window.URL.createObjectURL(blob)); 

       } 
+0

如果保存該文件,請將其重命名爲.zip,您可以打開它嗎?我試圖弄清楚內部是否損壞或者包裝在傳輸中是否被破壞。 –

+0

我將工作簿保存在服務器上,並將其重命名爲.zip,可以將其打開並查看結構。所以它似乎是損壞它的傳輸 – TwoHeadedSquirrel

+0

如果你可以打開.zip文件,那麼它不是損壞它的傳輸。當你將它保存在服務器上時,你能檢查內容長度與文件的確切長度嗎? –

回答

0

這個問題似乎是爲Web API調用的響應類型必須是{responseTyp的:「arraybuffer」},而不是{的responseType : '應用程序/八位字節流'}

context.$http.post('api-url', excel_list, {responseType: 'arraybuffer'}) .then( success_function, error_function) }

無論如何謝謝你快速幫助

0

看一看MVC擴展包在https://www.nuget.org/packages/ClosedXML.Extensions.Mvc/

PS:我已經告訴我要放棄這個每次。我是ClosedXML和ClosedXML.Extensions.Mvc的維護者。

+0

不幸的是,這也行不通。我們正在使用Web API而不是MVC。我在JavaScript中也收到了相同的結果,同樣也使用了該擴展中的「FileStreamResult」。 – TwoHeadedSquirrel

+0

好的。我會監視這個問題,如果有解決方案,我會將其添加到該擴展。 –

0

我可以成功下載一個工作簿現在這個代碼:

using ClosedXML.Excel; 
using System.IO; 
using System.Net; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Web.Http; 

namespace ClosedXML.Extensions.WebApi.Controllers 
{ 
    public class ValuesController : ApiController 
    { 
     public IHttpActionResult Get(int id) 
     { 
      return new TestFileActionResult(id); 
     } 
    } 

    public class TestFileActionResult : IHttpActionResult 
    { 
     public TestFileActionResult(int fileId) 
     { 
      this.FileId = fileId; 
     } 

     public int FileId { get; private set; } 

     public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
     { 
      HttpResponseMessage response = null; 

      var ms = new MemoryStream(); 
      using (var wb = new XLWorkbook()) 
      { 
       var ws = wb.AddWorksheet("Sheet1"); 
       ws.FirstCell().Value = this.FileId; 

       wb.SaveAs(ms); 

       ms.Seek(0, SeekOrigin.Begin); 

       response = new HttpResponseMessage(HttpStatusCode.OK); 
       response.Content = new StreamContent(ms); 
       response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
       response.Content.Headers.ContentDisposition.FileName = "test.xlsx"; 
       response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 

       response.Content.Headers.ContentLength = ms.Length; 
       ms.Seek(0, SeekOrigin.Begin); 
      } 

      return Task.FromResult(response); 
     } 
    } 
} 
+0

謝謝,但javascript部分如何查找web api調用並自行下載?有這個問題的感覺。 – TwoHeadedSquirrel

+0

我不是JavaScript專家。但請查看https://stackoverflow.com/a/24129082/179494中的問答。看起來像你嘗試做的事情有不同的支持。我的建議是嘗試使用直接的''標籤,而不是通過AJAX調用下載文件 –