【问题标题】:AngularJS Display PDF (byte[]) received from Spring @RestController从 Spring @RestController 收到的 AngularJS 显示 PDF (byte[])
【发布时间】:2014-12-22 22:01:54
【问题描述】:

我的要求是在表单提交/发布时在我的 Angular js 应用程序中显示(新标签)/下载/嵌入 PDF。

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

AngularJS: Display blob (.pdf) in an angular app 类似的问题,但这对我不起作用。

我的控制器

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);
            });
        }
    } ]);

我的服务

    angular.module('EvaluationResultsModule').factory('EvaluationResultsService', function($resource) {
    return $resource('./api/ca/evaluationResults/:dest', {}, {       
        getEvalutaionResultPDF : {
            method : 'GET',
            params : {
                dest : "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();
    }

我的回复已登录控制台

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

【问题讨论】:

    标签: angularjs rest spring-mvc pdf


    【解决方案1】:

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

    REST 控制器:

    @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/Angular 控制器;

    $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>
    

    【讨论】:

    • 感谢您简洁地回答一些需要一些时间才能找到的问题。
    • 非常感谢......它对我有一点点改变...... +1。
    • 如何处理Rest Controller中的异常?
    • @Guus - 你可以从var contentDisposition = response.headers("Content-Disposition");var filename = (contentDisposition.split(';')[1].trim().split('=')[1]).replace(/"/g, '');的回复中得到它
    • @amallard 谢谢,我还找到了另一种方法。使用angular-file-saver 我现在可以做到FileSaver.saveAs(file, 'my_file_name.pdf');
    【解决方案2】:

    在下面的链接中,你应该可以找到答案:

    AngularJS Display PDF (byte[]) received from Spring(@RestController) + jasper report

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

    【讨论】:

    • 您好,欢迎来到 SO。请编辑您的问题,使其至少包含可在该链接中找到的内容的摘要。如果链接失效,只包含一个链接的答案,没有任何解释或评论,可能会变得毫无用处。谢谢!
    【解决方案3】:

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

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

    后端控制器

    @RequestMapping(value = "/getPDF", method = RequestMethod.GET)
    public byte[] getEvalutaionResultPDF()  {        
            byte[] data = //get byte Array from back-end service
            return data;
    }
    

    JS 服务

    var getPdfFile = function(){
            return $http.get("getPDF", {responseType: 'arraybuffer'});
    };
    

    JS 控制器

    $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
            });
        };
    

    【讨论】:

      猜你喜欢
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 2013-06-21
      • 2019-09-08
      • 2019-01-04
      • 1970-01-01
      相关资源
      最近更新 更多