I've tried to open itext created pdf file using jsp code but not opening valid pdf file.
BTW if I'll open pdf in generated path then it is valid generated pdf.
<%
//code to generate pdf on file location.
String pdfurl = filePDF.getAbsolutePath();
File pdf = null;
try {
System.out.println("pdfurl : " + pdfurl);
response.setCharacterEncoding("utf-8");
pdf = new File(pdfurl);
response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-Disposition", "inline;filename=checklist.pdf");
response.setHeader("Accept-Ranges", "bytes");
response.setContentLength((int) pdf.length());
OutputStream sos = response.getOutputStream();
FileInputStream input = new FileInputStream(pdf);
BufferedInputStream buf = new BufferedInputStream(input);
int readBytes = 0;
while ((readBytes = buf.read()) != -1) {
sos.write(readBytes);
}
System.out.println("Finished writing bytes to output stream.");
sos.flush();
sos.close();
input.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (null != pdf && pdf.exists() && !pdf.isDirectory()) {
try {
pdf.delete();
System.out.println("Deleted file from " + pdfurl + " successfully");
} catch (Exception ex) {
System.out.println("Error while deleting pdf from : " + pdfurl);
}
}
}
%>
And angularJS code for ajax call:
pfqa.createDocument = function(action,data){
$("body").addClass("loading");
var deferred = $q.defer();
var paramJsonObj= {
'userId' : userId,
};
var data = angular.copy(paramJsonObj);
data = angular.toJson(data);
$http({
url : 'services/downloadPDF.jsp',
dataType: 'json',
method : 'POST',
headers : {
'Content-type' : 'application/json',
},
data: {data: paramJsonObj},
responseType : 'arraybuffer'
}).success(function(data, status, headers, config) {
var file = new Blob([ data ], {
type : 'application/json'
});
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'checklist.pdf';
document.body.appendChild(a);
a.click();
}).error(function(data, status, headers, config) {
});
$("body").removeClass("loading");
}
Please guide me what I'm missing here.
What you are missing here is :
Use : application/pdf instead of application/json
$http({
url : 'services/downloadPDF.jsp',
dataType: 'json',
method : 'POST',
headers : {
'Content-type' : 'application/pdf',
},
data: {data: paramJsonObj},
responseType : 'arraybuffer'
}).success(function(data, status, headers, config) {
var file = new Blob([ data ], {
type : 'application/pdf'
});
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'checklist.pdf';
document.body.appendChild(a);
a.click();
}).error(function(err) {
console.log(err);
});
That's it !!!
Related
I'm trying to send an image + object from Angular to Spring Boot but everytime I try I get this error:
Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]
This is my Angular code:
addPostWithIMG(image: File, postRequest: PostRequest): Subscription {
const headers = new HttpHeaders();
headers.append('Content-Type', ' multipart/form-data content');
var file: FormData = new FormData();
file.append('file', image);
file.append('postRequest', JSON.stringify(postRequest));
console.log(file)
return this.http.post<PostRequest>(`${this.baseUrl + "multi"}`, file, {headers: headers}).subscribe({
next: (data: any) => {
console.log(data)
},
error: (err: any) => {
console.error(err)
},
complete: () => {
console.log("Done")
}
});
}
This my Spring Boot side:
#PostMapping(path = "multi")
public String multi(MultipartHttpServletRequest request) throws IOException {
String postJSON = request.getParameter("postRequest");
PostRequest = new Gson().fromJson(post, PostRequest.class);
MultipartFile file = request.getFile("file");
Binary files = new Binary(file.getBytes());
File fileToSave = new File("Post/src/main/resources/" + postRequest.getPostId() + ".png");
log.info("file: {}", fileToSave.getAbsolutePath());
if (!fileToSave.exists()) {
log.info("file created: {}", fileToSave);
fileToSave.createNewFile();
} else {
log.info("file already exist: {}", fileToSave);
}
// Try-with-resource
try (OutputStream out = new FileOutputStream(fileToSave.getAbsolutePath())) {
out.write(files.getData());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
return "Image saved";
}
Can Anyone help me to find the reason of thi exception
Thank you very much
Try to don't add:
headers.append('Content-Type', ' multipart/form-data content');
The web will automatically set for you
I have pdf saved in blob format in my database. It's coming empty on front end.
Here is my controller call:
#RequestMapping(value = "/viewDocument", method = RequestMethod.GET, produces=MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> viewDocument()
{
HttpHeaders headers = new HttpHeaders();
ByteArrayInputStream bis = null;
try{
File uFile = null;
uFile = maintainFileService.getDocument(123456L);
bis = new ByteArrayInputStream(uFile.getFile());
headers.add("Content-Disposition", "inline; filename=pdf.pdf");
}
catch(Exception e){
logger.error("Exception while viewing the pdf.");
}
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
And here is my ajax call:
$.ajax({
type : "GET",
url: "/esubmission/recorder/search/viewDocument" ,
timeout : 100000,
success : function(result) {
window.open(result);
},
error : function(e) {
console.log("ERROR: ", e);
},
done : function(e) {
console.log("DONE");
}
});
I think I am missing something but just couldn't figure it out. TIA
I am trying to implement logic of download pdf from db on angular 5. I am facing issue in download file. File gets downloaded but throws error on opening -"Failed to load".
I have looked at so many blogs and question/answers but not able to find the mistake in my code.
In Database -> pdf file content saved as BLOB
Rest web service ->
In below code pdfData is the data from BLOB type column, which is byte[] in java code here
#GetMapping("downloadReport/{reportId}")
public StreamingResponseBody downloadDocument(byte[] pdfData) {
return outputStream -> {
//This way working for sample
/*try (InputStream inputStream = new ByteArrayInputStream(
Files.readAllBytes(Paths.get("D:/pdfWithoutPassword.pdf")))) {
IOUtils.copy(inputStream, outputStream);
}*/
//This way not working when data fetched from Database
try (InputStream inputStream = new ByteArrayInputStream(pdfData)) {
IOUtils.copy(inputStream, outputStream);
}
outputStream.close();
};
Angular 5 code
downloadReport(reportType: string, reportId: string) {
let fileDownloadUrl = environment.apiUrl + "/downloadReport" + "/" + reportId;
return this.httpClient
.get(fileDownloadUrl, { observe: 'response', responseType: "blob"})
.subscribe(response => this.saveFileToSystem(response.body)),
error => console.log("Error downloading the file."),
() => console.info("OK");
}
saveFileToSystem(input: any) {
const blob = new Blob([input], { type: 'application/octet-stream' });
saveAs(blob, "testingpdf1.pdf");
}
Looking for help in solving this. Thanks in advance!
Here another way I did it you you can change :
#RequestMapping(value = "/generateReport", method = RequestMethod.POST)
public ResponseEntity<byte[]> generateReport(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
StringBuilder filename = new StringBuilder("MyPdfName").append(".pdf");
byte[] bytes = pdfGeneratorService.generatePDF();
headers.add("content-disposition", "inline;filename=" + filename.toString());
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
return response;
}
Try this :
From your html page
YourPdf.pdf
From your js file
generatePdf() {
this.yourService.generatePdf()
.subscribe(pdf => {
let mediaType = 'application/pdf';
let blob = new
Blob([this.converterService.base64ToArrayBuffer(pdf.pdfByteArray)], { type: mediaType });
saveAs(blob, fileName);
}, err => {
console.log('Pdf generated err: ', JSON.stringify(err));
});
}
Your converter service:
import { Injectable } from "#angular/core";
#Injectable()
export class ConverterService {
base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
}
My java web application has a rest service method and return a inputstream image.
#GET
#Path("/image/{id}")
#Produces("image/png")
public Response buscarFoto(#PathParam("id") Long id,
#Context HttpHeaders header,
#Context HttpServletResponse response) {
byte[] bytes = null;
bytes = yakifreeService.getImageStream(id);
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
response.setContentType("images/png");
response.setHeader("Content-Type", "image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + "image.png" + "\"");
try {
OutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
} catch (IOException ex) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ex.getMessage()).type(MediaType.TEXT_HTML).build();
}
return Response.ok().build();
}
The Angularjs client gets the inputstream image as following
Image.getImage({ id: $scope.model.image.id }).$promise.then(function (result){
if (result) {
$scope.model.image.dataURL = 'data:image/png;base64,' + result;
}
});
function(yakifree) {
return yakifree.factory("Image", ["$resource", "$rootScope",
function($resource, $rootScope) {
var Image = $resource($rootScope.contextApp + '/rest/image/:id', { }, {
getImage: { method:'GET', params: {}, isArray: false }
});
return Image;
}]);
});
And HTML shows
<img data-ng-src="{{model.image.dataURL}}" width="120" height="120">
The problem is the HTML does not show image. The result variable in javasript has the value:
Resource {0: "�", 1: "P", 2: "N", 3: "G", 4: "
", 5: "↵", 6: "", 7: "↵", 8: "
Can someone help me ? Thanks!
For me, the next approach works correctly
$resource(endpoint + 'images/:id', null, {
getImage: {
method: 'GET',
responseType: 'arraybuffer',
transformResponse: function(data) { return { data : data }}
}
})
...
const response = await resource.getImage({id}).$promise;
const binary = btoa(String.fromCharCode.apply(null, new Uint8Array(response.data)));
const img = 'data:image/png;base64,'+ binary;
...
<img src={img}/>
There is a page where i have files list. On cliking on any of the .txt it must get downloaded and a notification should be displayed as the notification we get in download anything on GoogleChrome.
This is my Js which is called after cliking on .txt files
Here i am doing is, i am getting the filename and the filepath of the selected file. And then using ajax sending those filename and filepath to the spring servlet.
if (options.downloadable) {
$(easyTree).find('.easy-tree-toolbar').append('<div class="fileDownload"><button class="btn btn-default btn-sm btn-primary"><span class="glyphicon glyphicon-circle-arrow-down"></span></button></div>');
$(easyTree).find('.easy-tree-toolbar .fileDownload > button').attr('title', options.i18n.downloadTip).click(function() {
var selected = getSelectedItems();
var fileName = $(selected).find(' > span > a').text();
alert("fileName**" + fileName);
var hrefValue = $(selected).find(' > span > a').attr('href');
alert("hrefValue**" + hrefValue);
if (selected.length <= 0) {
$(easyTree).prepend(warningAlert);
$(easyTree).find('.alert .alert-content').html(options.i18n.downloadNull);
} else {
$.ajax({
url: "/ComplianceApplication/downloadFileFromDirectory",
type: "GET",
data: {
hrefValue: hrefValue,
fileName: fileName
},
success: function(data) {
//$(selected).remove();
//window.location.reload();
},
error: function(e) {
}
});
}
});
}
This is my springController. Here I am getting all the data properly but the problem is file is not getting downloaded and am not even getting any error so that I can come to know what mistake I am doing.
#RequestMapping(value="/downloadFileFromDirectory",method = RequestMethod.GET)
public #ResponseBody void downloadFileFromDirectory(#PathVariable("fileName") String fileName,#RequestParam(value = "hrefValue") String hrefValue,HttpServletRequest request, HttpServletResponse response,Model model){
System.out.println("hrefValue***"+hrefValue);
String filePath = hrefValue;
ServletContext context = request.getSession().getServletContext();
File downloadFile = new File(filePath);
FileInputStream inputStream = null;
OutputStream outStream = null;
try {
inputStream = new FileInputStream(downloadFile);
response.setContentLength((int) downloadFile.length());
response.setContentType(context.getMimeType(downloadFile.getName()));
// response header
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
//String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
// Write response
outStream = response.getOutputStream();
IOUtils.copy(inputStream, outStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream)
inputStream.close();
if (null != outStream)
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Any suggestions ???
I usually use this kind of code with no problem:
public ResponseEntity<InputStreamResource> downloadFile(#PathVariable("idForm") String idForm)
{
try
{
File parent = new File(csvFilesPath);
File file = new File(parent, idForm+".csv");
HttpHeaders respHeaders = new HttpHeaders();
MediaType mediaType = new MediaType("text","csv");
respHeaders.setContentType(mediaType);
respHeaders.setContentLength(file.length());
respHeaders.setContentDispositionFormData("attachment", "file.csv");
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK);
}
catch (Exception e)
{
String message = "Errore nel download del file "+idForm+".csv; "+e.getMessage();
logger.error(message, e);
return new ResponseEntity<InputStreamResource>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
The problem it's in you ajax code, so you can use JQuery File Download.
It's as simple as
$.fileDownload('/url/to/download.pdf');
Here you can see a tutorial
http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/