从Spring@RestController接收的AngularJS显示PDF(字节[])

从Spring@RestController接收的AngularJS显示PDF(字节[]),angularjs,rest,spring-mvc,pdf,Angularjs,Rest,Spring Mvc,Pdf,我的要求是在我的angular js应用程序中以提交/发布的形式显示(新标签)/下载/嵌入PDF 我不希望服务器返回生成的PDF的唯一标识符,而是使用$window service打开一个新窗口,其url指向服务器端端点,该端点根据唯一标识符返回PDF。因为我需要动态生成pdf(无需存储在文件系统中) 类似的问题,但它不是为我工作 我的控制器 angular.module('EvaluationResultsModule').controller('CA_EvaluationResultsCtr

我的要求是在我的angular js应用程序中以提交/发布的形式显示(新标签)/下载/嵌入PDF

我不希望服务器返回生成的PDF的唯一标识符,而是使用$window service打开一个新窗口,其url指向服务器端端点,该端点根据唯一标识符返回PDF。因为我需要动态生成pdf(无需存储在文件系统中)

类似的问题,但它不是为我工作

我的控制器

angular.module('EvaluationResultsModule').controller('CA_EvaluationResultsCtrl',
    [ '$scope', 'EvaluationResultsService', '$sce', function($scope, EvaluationResultsService, $sce) {

        $scope.showPDF = function() {
            $scope.result = CA_EvaluationResultsService.getEvalutaionResultPDF($scope.evaluationResults);
            $scope.result.$promise.then(function(data) {
                var file = new Blob([data], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                $scope.pdfContent = $sce.trustAsResourceUrl(fileURL);
            });
        }
    } ]);
@RequestMapping(value = "/getPDF", method = RequestMethod.GET)
public byte[] getEvalutaionResultPDF()  {        
        byte[] data = //get byte Array from back-end service
        return data;
}
$scope.pdfFile = function() {
        service.getPdfFile().then(function (data) {

            //for browser compatibility  
            var ieEDGE = navigator.userAgent.match(/Edge/g);
            var ie = navigator.userAgent.match(/.NET/g); // IE 11+
            var oldIE = navigator.userAgent.match(/MSIE/g); 
            var name = "file";
            var blob = new window.Blob([data.data], { type: 'application/pdf' });

            if (ie || oldIE || ieEDGE) {
                var fileName = name+'.pdf';
                window.navigator.msSaveBlob(blob, fileName);
            }
            else {
                var file = new Blob([ data.data ], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                var a         = document.createElement('a');
                a.href        = fileURL; 
                a.target      = '_blank';
                a.download    = name+'.pdf';
                document.body.appendChild(a);
                a.click();
            }
        },
        function(error) {
            //error
        });
    };
我的服务

    angular.module('EvaluationResultsModule').factory('EvaluationResultsService', function($resource) {
    return $resource('./api/ca/evaluationResults/:dest', {}, {       
        getEvalutaionResultPDF : {
            method : 'GET',
            params : {
                dest : "getPDF"
            },
            responseType : 'arraybuffer',

        }
    });
});
response:  Object {data: ArrayBuffer, status: 200, headers: function, config: Object, statusText: "OK"}config: Objectdata: ArrayBufferbyteLength: (...)__proto__: ArrayBufferbyteLength: [Exception: TypeError: Method ArrayBuffer.prototype.byteLength called on incompatible receiver #<ArrayBuffer>]get byteLength: function byteLength() { [native code] }constructor: function ArrayBuffer() { [native code] }slice: function slice() { [native code] }__proto__: Objectheaders: function (name) {resource: Resourcestatus: 200statusText: "OK"__proto__: Object
var getPdfFile = function(){
        return $http.get("getPDF", {responseType: 'arraybuffer'});
};
静止控制器方法

@RequestMapping(value = "/getPDF", method = RequestMethod.GET)
    public byte[] getEvalutaionResultPDF()  {        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // Generate PDF using Jasper
        Map<String, Object> model = new HashMap<String, Object>();
        List<User> usersList = null; //populated from Service layer;
        JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(usersList);
        JasperPrint jasperPrint =  jasperPrint = JasperFillManager.fillReport(this.getClass().getClassLoader().getResourceAsStream("A4.jasper"), model, beanColDataSource);
        JasperExportManager.exportReportToPdfStream(jasperPrint, baos);
        return baos.toByteArray();
    }
@RequestMapping(value=“/getPDF”,method=RequestMethod.GET)
公共字节[]GetEvaluationResultPDF(){
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
//使用Jasper生成PDF
映射模型=新的HashMap();
List usersList=null;//从服务层填充;
JRBeanCollectionDataSource beanColDataSource=新的JRBeanCollectionDataSource(usersList);
JasperPrint JasperPrint=JasperPrint=JasperFillManager.fillReport(this.getClass().getClassLoader().getResourceAsStream(“A4.jasper”)、模型、beanColDataSource);
JasperExportManager.exportReportToPdfStream(美国宝钢jasperPrint);
返回baos.toByteArray();
}
我的响应已登录控制台

    angular.module('EvaluationResultsModule').factory('EvaluationResultsService', function($resource) {
    return $resource('./api/ca/evaluationResults/:dest', {}, {       
        getEvalutaionResultPDF : {
            method : 'GET',
            params : {
                dest : "getPDF"
            },
            responseType : 'arraybuffer',

        }
    });
});
response:  Object {data: ArrayBuffer, status: 200, headers: function, config: Object, statusText: "OK"}config: Objectdata: ArrayBufferbyteLength: (...)__proto__: ArrayBufferbyteLength: [Exception: TypeError: Method ArrayBuffer.prototype.byteLength called on incompatible receiver #<ArrayBuffer>]get byteLength: function byteLength() { [native code] }constructor: function ArrayBuffer() { [native code] }slice: function slice() { [native code] }__proto__: Objectheaders: function (name) {resource: Resourcestatus: 200statusText: "OK"__proto__: Object
var getPdfFile = function(){
        return $http.get("getPDF", {responseType: 'arraybuffer'});
};
response:Object{data:ArrayBuffer,status:200,headers:function,config:Object,statusText:“OK”}config:Objectdata:ArrayBufferbyteLength:(…)\uu-proto\uu:ArrayBufferbyteLength:[异常:类型错误:方法ArrayBuffer.prototype.byteLength在不兼容的接收器上调用#]获取byteLength:function-byteLength(){[本机代码]}构造函数:函数ArrayBuffer(){[native code]}切片:函数切片(){[native code]}}\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

我使用此代码,它对我有效:

休息控制器:

@RequestMapping(value = "/api/reports/pdf", method = RequestMethod.GET)
@Timed
public @ResponseBody byte[] getOpenedEventsInPdf(HttpServletResponse response) {
    response.setHeader("Content-Disposition", "inline; filename=file.pdf");
    response.setContentType("application/pdf");
// get file in bytearray from my custom service in backend
    byte[] file = jasperReportsService.getOpenedEventsReport(ReportFormat.PDF);
    return file;
}
JS/角度控制器

$scope.getPdf = function(){
  $http.get('/api/reports/pdf', {responseType: 'arraybuffer'})
  .success(function (data) {
    var file = new Blob([data], {type: 'application/pdf'});
    var fileURL = URL.createObjectURL(file);
    window.open(fileURL);
  });
}
HTML片段:

<a ng-click="getPdf()">Show PDF</a>
显示PDF

在以下链接中,您应该可以找到答案:

在此链接中,您将了解如何使用angularjs在iframe中显示pdf。 pdf是使用spring和jasper报告从API rest接收的

对于“浏览器兼容性”,给定代码工作正常:

从beck end控制器端获取字节数组数据并生成 js控制器端的文件

贝克端控制器

angular.module('EvaluationResultsModule').controller('CA_EvaluationResultsCtrl',
    [ '$scope', 'EvaluationResultsService', '$sce', function($scope, EvaluationResultsService, $sce) {

        $scope.showPDF = function() {
            $scope.result = CA_EvaluationResultsService.getEvalutaionResultPDF($scope.evaluationResults);
            $scope.result.$promise.then(function(data) {
                var file = new Blob([data], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                $scope.pdfContent = $sce.trustAsResourceUrl(fileURL);
            });
        }
    } ]);
@RequestMapping(value = "/getPDF", method = RequestMethod.GET)
public byte[] getEvalutaionResultPDF()  {        
        byte[] data = //get byte Array from back-end service
        return data;
}
$scope.pdfFile = function() {
        service.getPdfFile().then(function (data) {

            //for browser compatibility  
            var ieEDGE = navigator.userAgent.match(/Edge/g);
            var ie = navigator.userAgent.match(/.NET/g); // IE 11+
            var oldIE = navigator.userAgent.match(/MSIE/g); 
            var name = "file";
            var blob = new window.Blob([data.data], { type: 'application/pdf' });

            if (ie || oldIE || ieEDGE) {
                var fileName = name+'.pdf';
                window.navigator.msSaveBlob(blob, fileName);
            }
            else {
                var file = new Blob([ data.data ], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                var a         = document.createElement('a');
                a.href        = fileURL; 
                a.target      = '_blank';
                a.download    = name+'.pdf';
                document.body.appendChild(a);
                a.click();
            }
        },
        function(error) {
            //error
        });
    };
JS服务

    angular.module('EvaluationResultsModule').factory('EvaluationResultsService', function($resource) {
    return $resource('./api/ca/evaluationResults/:dest', {}, {       
        getEvalutaionResultPDF : {
            method : 'GET',
            params : {
                dest : "getPDF"
            },
            responseType : 'arraybuffer',

        }
    });
});
response:  Object {data: ArrayBuffer, status: 200, headers: function, config: Object, statusText: "OK"}config: Objectdata: ArrayBufferbyteLength: (...)__proto__: ArrayBufferbyteLength: [Exception: TypeError: Method ArrayBuffer.prototype.byteLength called on incompatible receiver #<ArrayBuffer>]get byteLength: function byteLength() { [native code] }constructor: function ArrayBuffer() { [native code] }slice: function slice() { [native code] }__proto__: Objectheaders: function (name) {resource: Resourcestatus: 200statusText: "OK"__proto__: Object
var getPdfFile = function(){
        return $http.get("getPDF", {responseType: 'arraybuffer'});
};
JS控制器

angular.module('EvaluationResultsModule').controller('CA_EvaluationResultsCtrl',
    [ '$scope', 'EvaluationResultsService', '$sce', function($scope, EvaluationResultsService, $sce) {

        $scope.showPDF = function() {
            $scope.result = CA_EvaluationResultsService.getEvalutaionResultPDF($scope.evaluationResults);
            $scope.result.$promise.then(function(data) {
                var file = new Blob([data], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                $scope.pdfContent = $sce.trustAsResourceUrl(fileURL);
            });
        }
    } ]);
@RequestMapping(value = "/getPDF", method = RequestMethod.GET)
public byte[] getEvalutaionResultPDF()  {        
        byte[] data = //get byte Array from back-end service
        return data;
}
$scope.pdfFile = function() {
        service.getPdfFile().then(function (data) {

            //for browser compatibility  
            var ieEDGE = navigator.userAgent.match(/Edge/g);
            var ie = navigator.userAgent.match(/.NET/g); // IE 11+
            var oldIE = navigator.userAgent.match(/MSIE/g); 
            var name = "file";
            var blob = new window.Blob([data.data], { type: 'application/pdf' });

            if (ie || oldIE || ieEDGE) {
                var fileName = name+'.pdf';
                window.navigator.msSaveBlob(blob, fileName);
            }
            else {
                var file = new Blob([ data.data ], {
                    type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);
                var a         = document.createElement('a');
                a.href        = fileURL; 
                a.target      = '_blank';
                a.download    = name+'.pdf';
                document.body.appendChild(a);
                a.click();
            }
        },
        function(error) {
            //error
        });
    };

感谢您简明扼要地回答了一些花了一些时间才找到的问题。非常感谢您……它对我来说非常有用,只是做了一些小改动……+1.如何处理Rest Controller中的异常?@Guus-您可以从响应
var contentDisposition=response.headers(“内容处置”);
var filename=(contentDisposition.split(“;”)[1].trim().split(“=”)[1]).replace(/“/g”“);
@amallard谢谢,我还找到了另一种方法。使用
角度文件保存程序
我现在可以做
文件保存程序.saveAs(文件,'my_file_name.pdf'))
您好,欢迎使用SO。请编辑您的问题,使其至少包含在该链接中可以找到的内容的摘要。如果链接无效,仅包含链接而没有任何解释或注释的答案可能会变得无效。谢谢!