My my requirement is to either display(new tab)/download/embed a PDF in my angular js app on form submit/post.
I do not want the server to return a unique identifier of the generated PDF and than use $window service to open a new window with it's url pointing to a server-side endpoint which returns PDf based on unique identifier. Because I need to generate the pdf on the fly (no storing in file system).
Similar question to this one AngularJS: Display blob (.pdf) in an angular app But it is not working for me.
My controller
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);
});
}
} ]);
My Service
angular.module('EvaluationResultsModule').factory('EvaluationResultsService', function($resource) {
return $resource('./api/ca/evaluationResults/:dest', {}, {
getEvalutaionResultPDF : {
method : 'GET',
params : {
dest : "getPDF"
},
responseType : 'arraybuffer',
}
});
});
Rest Controller Method
@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();
}
My response logged in console
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
I use this code and it works for me:
REST Controller:
@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 Controller;
$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 fragment:
<a ng-click="getPdf()">Show PDF</a>
For "Browser Compatibility" given code is working properly :
Get the byte array data from beck-end controller side and generate file on js controller side :
Beck-end controller
@RequestMapping(value = "/getPDF", method = RequestMethod.GET)
public byte[] getEvalutaionResultPDF() {
byte[] data = //get byte Array from back-end service
return data;
}
JS Service
var getPdfFile = function(){
return $http.get("getPDF", {responseType: 'arraybuffer'});
};
JS controller
$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
});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With