6

My Angular 1.5 application connect to a Java/Tomcat/Spring backend server via REST.

One REST service generates PDF and send it to the client. It works fine on DEsktop browsers (FF, Chrome at least) but I cannot see the PDF content on iOS (ipad for instance) whatever the browser I am using (Chrome, Safari..)

Here is the Angular Code :

$http.get("/displayPdf", {responseType: 'arraybuffer', params: {id: 1}}).
 success(function(data) {
   var blob = new Blob([data], {type 'application/pdf'});
   var objectUrl =  window.URL.createObjectURL(blob);
   window.open(objectUrl);
 }
);

The Spring/Jax-RS code is :

@GET
@Path("displayPdf")
@Produces("application/pdf")
Response displayPdf(@QueryParam("id") Long id) {
  byte[] bytes = service.generatePdf(); 
  return javax.ws.rs.core.Response.ok().
    entity(bytes).
    header("Content-Type", "pdf").
    header("Content-Disposition", "attachment; filename='test.pdf'").
    build();
}

I have done my research here for instance(AngularJS: Display blob (.pdf) in an angular app) but could not find an appropriate solution.

So please, do you know what should I do to display the generated PDF to my iPad/iPhone end-users ?

Thanks a lot

2
  • Hi! You should visit that related post ;) stackoverflow.com/questions/21628378/… Commented Sep 14, 2016 at 23:37
  • @fabien7474 did the answers resolved your issue ? Commented Sep 16, 2016 at 7:12

3 Answers 3

25

None of the solutions proposed above did work for me.

The main issue comes from URL that wasn't retrieved correctly in iOS. The following code do the correct work :

window.URL = window.URL || window.webkitURL;

Also even with this, it did not work on Chrome iOS, neither Opera iOS...so after digging the internet and inspired with the following questions :

... I finally ended up with the following code (working on all iOS browsers except FF on iOS) :

if (window.navigator.msSaveOrOpenBlob) { //IE 11+
  window.navigator.msSaveOrOpenBlob(blob, "my.pdf");
} else if (userAgent.match('FxiOS')) { //FF iOS
  alert("Cannot display on FF iOS");
}
} else if (userAgent.match('CriOS')) { //Chrome iOS
  var reader = new FileReader();
  reader.onloadend = function () { $window.open(reader.result);};
  reader.readAsDataURL(blob);
} else if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i)) { //Safari & Opera iOS
  var url = $window.URL.createObjectURL(blob);
  window.location.href = url;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Can you please explain how can we make use of this in Angular?
1

Just add the below code as your $http call.I've handled for other browsers as well.

    $http.get("/displayPdf", {responseType: 'arraybuffer', params: {id: 1}}).success(function(data) {
    var blob = new Blob([data], {type 'application/pdf'});
    var anchor = document.createElement("a");
    if(navigator.userAgent.indexOf("Chrome") != -1||navigator.userAgent.indexOf("Opera") != -1){
                    $window.open(URL.createObjectURL(file,{oneTimeOnly:true}));
    }else if(navigator.userAgent.indexOf("iPad") != -1){
                    var fileURL = URL.createObjectURL(file);
                    //var anchor = document.createElement("a");
                    anchor.download="myPDF.pdf";
                    anchor.href = fileURL;
                    anchor.click();
    }else if(navigator.userAgent.indexOf("Firefox") != -1 || navigator.userAgent.indexOf("Safari") != -1){
                        var url = window.URL.createObjectURL(file);
                        anchor.href = url;
                        anchor.download = "myPDF.pdf";
                        document.body.appendChild(anchor);
                        anchor.click();
                        setTimeout(function(){
                            document.body.removeChild(anchor);
                            window.URL.revokeObjectURL(url);  
                        }, 1000);
      }
   });

3 Comments

This solution does not work for iPad. Still the same issue : nothing is displyaed
can you elaborate what issue you have faced while using this solution ? So that we can track what exactly happened as it is a tested out code.
Very simple : nothing happens on iPad whereas in Chrome for instance, Pdf is displayed.
0

i use basically your same setup but i build my pdf differently using, unable to test with iOS but i hope this helps some

$http({ url: $scope.url,
            method: "GET",
            headers: { 'Accept': 'application/pdf' },
            responseType: 'arraybuffer' })
        .then(function (response) {
            var file = new Blob([response.data], {type: 'application/pdf'});
            var fileURL = URL.createObjectURL(file);
            $scope.pdfContent = $sce.trustAsResourceUrl(fileURL);
        });//end http

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.