【问题标题】:How to Display blob (.pdf) in an AngularJS app如何在 AngularJS 应用程序中显示 blob (.pdf)
【发布时间】:2014-03-04 21:38:56
【问题描述】:

我一直在尝试显示我从$http.post 响应中以 blob 形式获得的 pdf 文件。 pdf 必须在应用程序中显示,例如使用 <embed src>

我遇到了几个堆栈帖子,但不知何故,我的示例似乎不起作用。

JS:

根据this doc,我继续尝试...

$http.post('/postUrlHere',{myParams}).success(function (response) {
 var file = new Blob([response], {type: 'application/pdf'});
 var fileURL = URL.createObjectURL(file);
 $scope.content = fileURL;
});

现在据我了解,fileURL 创建了一个临时 URL,博客可以将其用作参考。

HTML:

<embed src="{{content}}" width="200" height="200"></embed>

我不确定如何在 Angular 中处理这个问题,理想的情况是 (1) 将其分配给一个范围,(2) 'prepare/rebuild ' blob 到 pdf (3) 使用 &lt;embed&gt; 将其传递给 HTML,因为我想在应用程序中显示它。

我已经研究了一天多,但不知何故,我似乎无法理解它在 Angular 中是如何工作的……让我们假设那里没有 pdf 查看器库。

【问题讨论】:

  • 嗨 D'lo DeProjuicer,您是否设法解决了通过 Angular 生成 PDF 的问题?
  • @michael D'lo DeProjuicer 对于 Angular 2 中的相同情况应该怎么做?

标签: angularjs pdf blob


【解决方案1】:

首先您需要将responseType 设置为arraybuffer。如果要创建数据块,则需要这样做。见Sending_and_Receiving_Binary_Data。所以你的代码看起来像这样:

$http.post('/postUrlHere',{myParams}, {responseType:'arraybuffer'})
  .success(function (response) {
       var file = new Blob([response], {type: 'application/pdf'});
       var fileURL = URL.createObjectURL(file);
});

下一部分是,您需要使用$sce 服务来使角度信任您的网址。这可以通过这种方式完成:

$scope.content = $sce.trustAsResourceUrl(fileURL);

别忘了注入$sce服务。

如果这一切都完成了,您现在可以嵌入您的 pdf:

<embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>

【讨论】:

  • 对我来说,这在 Chrome (35.0.1916.114 m) 中不起作用。通过使用 而不是 解决了这个问题:
  • 对我来说 (AngularJS 1.25) 我必须这样做:new Blob([response.data]
  • @HoffZ:我用一个完整的替换了快捷方法$http.get,指定了responseType字段:{ url: "http://127.0.0.1:8080/resources/jobs/af471106-2e71-4fe6-946c-cd1809c659e5/result/?key="+$scope.key, method: "GET", headers: { 'Accept': 'application/pdf' }, responseType: 'arraybuffer' }它有效:)
  • 对我来说,使其工作的唯一方法是使用 response.data 而不是 response 创建 blob,如下所示:var file = new Blob([response.data], {type: 'application/pdf'});
  • @yosep-kim 这在 IE 上不起作用,因为 IE 中不存在 URL 对象:caniuse.com/#search=URL
【解决方案2】:

我使用 AngularJS v1.3.4

HTML:

<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>

JS 控制器:

'use strict';
angular.module('xxxxxxxxApp')
    .controller('xxxxController', function ($scope, xxxxServicePDF) {
        $scope.downloadPdf = function () {
            var fileName = "test.pdf";
            var a = document.createElement("a");
            document.body.appendChild(a);
            a.style = "display: none";
            xxxxServicePDF.downloadPdf().then(function (result) {
                var file = new Blob([result.data], {type: 'application/pdf'});
                var fileURL = window.URL.createObjectURL(file);
                a.href = fileURL;
                a.download = fileName;
                a.click();
            });
        };
});

JS 服务:

angular.module('xxxxxxxxApp')
    .factory('xxxxServicePDF', function ($http) {
        return {
            downloadPdf: function () {
            return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) {
                return response;
            });
        }
    };
});

Java REST Web 服务 - Spring MVC:

@RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf")
    public ResponseEntity<byte[]> getPDF() {
        FileInputStream fileStream;
        try {
            fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf"));
            byte[] contents = IOUtils.toByteArray(fileStream);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/pdf"));
            String filename = "test.pdf";
            headers.setContentDispositionFormData(filename, filename);
            ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
            return response;
        } catch (FileNotFoundException e) {
           System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
        }
        return null;
    }

【讨论】:

  • 哪个版本的 Safari? window.URL 在 safari 9 及之后版本中很好:caniuse.com/#search=createObjectURL
  • 我在我的 MacBook pro 和 safari 9.0.2 上进行了测试和验证。
  • 同样,macBook el Captain。 window.URL.createObjectURL(文件);我不知道问题出在哪里,但代码不起作用。可能是我做错了什么。任何谢谢。我没有时间检查它不起作用并使用 FileSaver.js
  • 如果您的申请在线,请发布您的网址?你有同样的后端吗?
  • safari 不支持下载属性。 caniuse.com/#search=download
【解决方案3】:

michael 的建议对我来说就像是一种魅力 :) 如果您将 $http.post 替换为 $http.get,请记住 .get 方法接受 2 个参数而不是 3 个...这是浪费我时间的地方... ;)

控制器:

$http.get('/getdoc/' + $stateParams.id,     
{responseType:'arraybuffer'})
  .success(function (response) {
     var file = new Blob([(response)], {type: 'application/pdf'});
     var fileURL = URL.createObjectURL(file);
     $scope.content = $sce.trustAsResourceUrl(fileURL);
});

查看:

<object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>

【讨论】:

  • responseType:'arraybuffer',刚刚节省了我几个小时的睡眠时间! +1
  • 如何触发保存而不是用html打印?
  • 谢谢,这为我节省了几个小时,您也可以将$scope.content = $sce.trustAsResourceUrl(fileURL); 替换为$window.open(fileURL, '_self', ''); 并全屏打开文件。
【解决方案4】:

我在 Opera 浏览器中使用“window.URL”时遇到了困难,因为它会导致“未定义”。此外,使用 window.URL,PDF 文档永远不会在 Internet Explorer 和 Microsoft Edge 中打开(它将永远等待)。我想出了以下适用于 IE、Edge、Firefox、Chrome 和 Opera 的解决方案(未在 Safari 上测试过):

$http.post(postUrl, data, {responseType: 'arraybuffer'})
.success(success).error(failed);

function success(data) {
   openPDF(data.data, "myPDFdoc.pdf");
};

function failed(error) {...};

function openPDF(resData, fileName) {
    var ieEDGE = navigator.userAgent.match(/Edge/g);
    var ie = navigator.userAgent.match(/.NET/g); // IE 11+
    var oldIE = navigator.userAgent.match(/MSIE/g); 

    var blob = new window.Blob([resData], { type: 'application/pdf' });

    if (ie || oldIE || ieEDGE) {
       window.navigator.msSaveBlob(blob, fileName);
    }
    else {
       var reader = new window.FileReader();
       reader.onloadend = function () {
          window.location.href = reader.result;
       };
       reader.readAsDataURL(blob);
    }
}

如果有帮助,请告诉我! :)

【讨论】:

  • 这种方式不会在IE浏览器窗口中打开PDF文档,而是提示用户下载。有什么解决办法吗?
  • 上面的代码是下载PDF文件,让你的默认PDF阅读器应用接管打开它。它甚至在移动设备上运行良好。原因是,虽然我能够在某些浏览器上打开 PDF,但我无法在其他浏览器上打开它。所以我认为最好有一个可以在所有浏览器(包括移动浏览器)上运行的解决方案来下载 PDF 文件。
  • 您可以使用以下代码在新选项卡中查看 PDF:window.open(reader.result, '_blank');
【解决方案5】:

过去几天我一直在努力下载 pdf 和图像,我只能下载简单的文本文件。

大多数问题都有相同的组成部分,但需要一段时间才能找出正确的顺序以使其发挥作用。

谢谢@Nikolay Melnikov,您对这个问题的评论/回复是它成功的原因。

简而言之,这是我的 AngularJS 服务后端调用:

  getDownloadUrl(fileID){
    //
    //Get the download url of the file
    let fullPath = this.paths.downloadServerURL + fileId;
    //
    // return the file as arraybuffer 
    return this.$http.get(fullPath, {
      headers: {
        'Authorization': 'Bearer ' + this.sessionService.getToken()
      },
      responseType: 'arraybuffer'
    });
  }

来自我的控制器:

downloadFile(){
   myService.getDownloadUrl(idOfTheFile).then( (response) => {
      //Create a new blob object
      let myBlobObject=new Blob([response.data],{ type:'application/pdf'});

      //Ideally the mime type can change based on the file extension
      //let myBlobObject=new Blob([response.data],{ type: mimeType});

      var url = window.URL || window.webkitURL
      var fileURL = url.createObjectURL(myBlobObject);
      var downloadLink = angular.element('<a></a>');
      downloadLink.attr('href',fileURL);
      downloadLink.attr('download',this.myFilesObj[documentId].name);
      downloadLink.attr('target','_self');
      downloadLink[0].click();//call click function
      url.revokeObjectURL(fileURL);//revoke the object from URL
    });
}

【讨论】:

    【解决方案6】:

    responseType 添加到从 angular 发出的请求中确实是解决方案,但对我来说,直到我将 responseType 设置为 blob,而不是 arrayBuffer。代码不言自明:

        $http({
                method : 'GET',
                url : 'api/paperAttachments/download/' + id,
                responseType: "blob"
            }).then(function successCallback(response) {
                console.log(response);
                 var blob = new Blob([response.data]);
                 FileSaver.saveAs(blob, getFileNameFromHttpResponse(response));
            }, function errorCallback(response) {   
            });
    

    【讨论】:

    • 其实'blob'类型可以写得更短:FileSaver.saveAs(response.data, getFileNameFromHttpResponse(response));无需创建Blob
    【解决方案7】:

    我刚刚在使用 AngularJS v1.7.2 的项目中使用的代码建议

    $http.get('LabelsPDF?ids=' + ids, { responseType: 'arraybuffer' })
                .then(function (response) {
                    var file = new Blob([response.data], { type: 'application/pdf' });
                    var fileURL = URL.createObjectURL(file);
                    $scope.ContentPDF = $sce.trustAsResourceUrl(fileURL);
                });
    
    <embed ng-src="{{ContentPDF}}" type="application/pdf" class="col-xs-12" style="height:100px; text-align:center;" />
    

    【讨论】:

    • 也请添加一些简短的内容。
    【解决方案8】:

    最新答案(针对 Angular 8+):

    this.http.post("your-url",params,{responseType:'arraybuffer' as 'json'}).subscribe(
      (res) => {
        this.showpdf(res);
      }
    )};
    
    public Content:SafeResourceUrl;
    showpdf(response:ArrayBuffer) {
      var file = new Blob([response], {type: 'application/pdf'});
      var fileURL = URL.createObjectURL(file);
      this.Content = this.sanitizer.bypassSecurityTrustResourceUrl(fileURL);
    }
    
      HTML :
    
      <embed [src]="Content" style="width:200px;height:200px;" type="application/pdf" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2018-08-16
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      相关资源
      最近更新 更多