2016-09-11 118 views
1

Pleasssse帮我... 我有一个xlsm文件(excel与宏)在服务器端(c#),并希望下载它在客户端(javascript,angularjs )。 所以..在服务器端控制器中,我返回一个HttpResponseMessage并在客户端 - 下载它。在客户端dowclock时xlsm文件被破坏

的问题是,打开已下载该文件时,它已损坏...

我做了一个简短的测试案例来说明问题。


服务器端(C#ApiController):

[HttpGet] 
public HttpResponseMessage exportDPs() 
{    
    var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); 
    var stream = new FileStream(@"D:\excel\data.xlsm", FileMode.Open); 
    response.Content = new StreamContent(stream); 
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
    response.Content.Headers.ContentDisposition.FileName = "DPs.xlsm"; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    response.Content.Headers.ContentLength = stream.Length; 
    response.StatusCode = System.Net.HttpStatusCode.OK; 
    return response; 
} 

客户端(JavaScript,angularjs):

$scope.exportDPs = function() { 
    $http({ 
     method: GET, 
     url: '../Api/DPs/exportDPs', 
    }).success(function (data) { 
     var file = data; 
     var encodedUri = encodeURI(file); 
     var link = document.createElement("a"); 
     link.setAttribute("href", "data:application/vnd.ms-excel.sheet.macroEnabled.12;charset=utf-8,\uFEFF" + encodedUri); 
     link.setAttribute("download", "DPs"); 
     link.click();       
    })  
} 
+0

检查字节数,使字节的数量肯定没有改变。您的流可能使用了破坏文件的默认ASCII编码。您需要使用不会更改文件的UTF8编码。我会使用以下内容:StreamReader stream = new StreamReader(@“D:\ excel \ data.xlsm”,Encoding.UTF8); – jdweng

+0

为什么在文件内容前加上BOM('\ uFEFF')?这可能是导致你的问题。 –

+0

此外,为什么不把代码放到'href'属性中,然后调用'.click()'。尝试下载文件,然后将其作为数据URI从链接提供,这无疑会使问题复杂化。 –

回答

0

的问题可能是你加前缀的来自具有Unicode字节顺序标记(BOM)的服务器的内容 - \uFEFF。 BOM仅用于文本文件,但XLSM是一个二进制文件(更具体地说,它是XML文件的ZIP文件)。

但是,最好的办法是简化您的JavaScript,以便直接下载文件,而不是试图在后台下载文件并从中创建数据URI。

这应该做你想要什么:

$scope.exportDPs = function() { 
    var link = document.createElement("a"); 
    link.setAttribute("href", "../Api/DPs/exportDPs"); 
    link.setAttribute("download", "DPs"); 
    link.click();       
} 
+0

再次感谢。我的URL需要接收一个复杂的参数(对象数组),我该如何在URL中做到这一点? – mor

+0

@mor数组通常在查询字符串中传递,如下所示:'?Values [] = 1&Values [ ] = 2&Values [] = 3'这样的数组:'Values = [1,2,3]'。如果你需要比这更复杂的东西,你有两个简单的选择:1)创建一个JSON字符串并将其传递给查询字符串。 2)创建一个'form'元素,其中包含一些'input'元素而不是'a'元素,并且使用'form.submit()'而不是'link.click()'。如果你需要更多的帮助,你应该问另一个问题。 –

+0

谢谢,我会尽力做到这一点。 – mor