AngularJS / JAX-RS:如何获得正确的Excel文档响应

我想通过JAX-RS web服务导出Excel文件,然后从Web应用程序下载/打开它。 这听起来很有效,无论是从curl调用,还是从AngularJS v1.4.7前端调用。 我在Windows 7 Professional下使用Microsoft Excel 2013 64位。

在服务器端,web服务实现如下:

@POST @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("/compare") public Response compare( @FormDataParam("controlFile") InputStream controlIs, @FormDataParam("controlFile") FormDataContentDisposition controlFileDetail, @FormDataParam("testFile") InputStream testIs, @FormDataParam("testFile") FormDataContentDisposition testFileDetail ) { //(...) //creating my Excel file using Apache POI SXSSFWorkbook File file = new File(reportFileName); ResponseBuilder responseBuilder = Response.ok((Object) file, MediaType.APPLICATION_OCTET_STREAM) .header("Access-Control-Allow-Origin", "*") .header("Content-Disposition", "attachment; filename=test.xlsx"); return responseBuilder.build(); } 

我可以通过curl查询webservice并获得预期的结果

curl -X POST -F“controlFile=@loremIpsum1.xml”-F“testFile=@loremIpsum2.xml” http:// localhost:8080 / xmlcompare-rs / xmlcompare / compare > comparison.xls

对于文件中没有redirect的信息,导出的格式如下所示:

  åì⌐H ♂ _rels/.rels╡Æ┴j├0♀å∩y ú{π┤â1F£^╩á╖1║╨l%1I,c{[·÷≤vZJ[ c║ ²· ☼ñz;Oú°á►-;♣δ▓☻AN│▒«S≡zxZ=Çê ¥┴æ↔)8RämS╘/4b╩;▒╖>èlΓóé>% (e╘=M↑K÷Σ≥ñσ0a╩mΦñG=`GrSU≈2ⁿ÷Ǫ►B,|┼▐{│å∩╤▓♫↑:J (...) 

我现在正在从AngularJS前端调用完全相同的web服务,其中web服务调用如下:

 angular.module('compareWwwApp') .service('compareService', ['$http', function ($http) { this.xmlcompare = function(controlFile, testFile){ var fd = new FormData(); fd.append('controlFile', controlFile); fd.append('testFile', testFile); var xmlcompareUrl='http://localhost:8080/xmlcompare-rs/xmlcompare/compare'; $http.post(xmlcompareUrl, fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined} }) .success(function(result){ var blob = new Blob([result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); var objectUrl = URL.createObjectURL(blob); window.open(objectUrl); }) .error(function(){ }); } }]); 

Web服务听起来像预期的那样从服务器端执行(来自日志),并返回浏览器中显示的xlsx文档。

在这里输入图像说明

点击下载的文档,Excel打开并告诉我“我们发现XXX.xlsx中的某些内容存在问题,您是否希望我们尝试恢复为mych,我们可以?(..)” ,然后“Excel无法打开文件XXX.xlsx,因为文件格式或文件扩展名无效。确认文件没有被损坏,文件扩展名与“

我做了一些尝试切换到键入“application / vnd.ms-excel”或返回一个StreamingOutput而不是MediaType.APPLICATION_OCTET_STREAM对象,如图所示,但没有成功。

有什么build议?

谢谢,

你需要在你的POST调用中添加responseType: 'arraybuffer' 。 那么一切都会好的。

所以会的

 $http.post(xmlcompareUrl, fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined}, responseType: 'arraybuffer' }) 
 JS ---- window.open("http://localhost:8080/xmlcompare-rs/xmlcompare/compare"); Rest ------ @GET @Path("excelmisreport") @Produces("application/vnd.ms-excel") public Response getExcelReport(){ ResponseBuilder response = Response.ok((Object) file); response.header("Content-Disposition", "attachment; filename=MISReport.xls"); return response.build(); } No need multiform data 

您可以尝试从您的代码中删除以下行:

 .success(function(result){ var blob = new Blob([result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); var objectUrl = URL.createObjectURL(blob); window.open(objectUrl); }) .error(function(){ }); 

只要调用API应该返回一个正确的响应, content-disposition头设置,因此,浏览器应该能够调用“下载/保存文件”对话框。