Return generated pdf using spring MVC
You were on the right track with response.getOutputStream()
, but you're not using its output anywhere in your code. Essentially what you need to do is to stream the PDF file's bytes directly to the output stream and flush the response. In Spring you can do it like this:
@RequestMapping(value="/getpdf", method=RequestMethod.POST)
public ResponseEntity<byte[]> getPDF(@RequestBody String json) {
// convert JSON to Employee
Employee emp = convertSomehow(json);
// generate the file
PdfUtil.showHelp(emp);
// retrieve contents of "C:/tmp/report.pdf" that were written in showHelp
byte[] contents = (...);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
// Here you have to set the actual filename of your pdf
String filename = "output.pdf";
headers.setContentDispositionFormData(filename, filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<>(contents, headers, HttpStatus.OK);
return response;
}
Notes:
- use meaningful names for your methods: naming a method that writes a PDF document
showHelp
is not a good idea - reading a file into a
byte[]
: example here - I'd suggest adding a random string to the temporary PDF file name inside
showHelp()
to avoid overwriting the file if two users send a request at the same time
Return a PDF file with Spring MVC
That would be like the below:
@Controller
@RequestMapping("/generateReport.do")
public class ReportController
@RequestMapping(method = RequestMethod.POST)
public void generateReport(HttpServletResponse response) throws Exception {
byte[] data = //read PDF as byte stream
streamReport(response, data, "my_report.pdf"));
}
protected void streamReport(HttpServletResponse response, byte[] data, String name)
throws IOException {
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename=" + name);
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.getOutputStream().flush();
}
}
How to download pdf file and redirect to home page in Spring mvc
Just to get the pdf (download into browser from local file system), this code is sufficient:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/admin/generate_pdf")
public class PdfController {
@GetMapping(value = "/online", /*this is "nice to have" ->*/ produces = MediaType.APPLICATION_PDF_VALUE)
@ResponseBody // this is important, as the return type byte[]
public byte[] generating_pdf() throws IOException {//exception handling...
System.out.println("hello");//logging
// re-generate new file if needed (thread-safety!)...
// ..and dump the content as byte[] response body:
return Files.readAllBytes(Paths.get("d:\\sanjeet7.pdf"));
}
}
... if you need "a refresh", you can "rewrite" the file/re-call your service, but still maybe not the "thread-safest" solution.
Edit: With no further configuration (port/context root/...), You should reach this at: http://localhost:8080/admin/generate_pdf/online
If you want to "operate closer to the bytes" and with void
return type/no @ResponseBody
and want an additional redirect (to be tested), I think this should still work:
@Controller
public class ... {
@GetMapping(value = ..., produces ...)
//no request body, void return type, response will be autowired and can be handled
public void generatePdf(javax.servlet.http.HttpServletResponse response) throws ... {
java.io.OutputStream outStr = response.getOutputStream();
// dump from "somewhere" into outStr, "finally" close.
outStr.close();
//TO BE TESTED:
response.sendRedirect("/");
}
}
..or even (return a "view name" + operate on outputStream):
@GetMapping(value = ..., produces = "application/pdf")
//return a "view name" (!), and you can inject (only) the outputstream (without enclosing response)
public String generatePdf(java.io.OutputStream outputstream) throws... {
// ... do your things on outputstream, IOUtils is good...
// close the stream(?)
// ..and
return "redirect:/"; // to a redirect or a view name.
// .... (in a "spring way", which could also save you some "context path problems"
} ...
Return generated pdf using spring MVC With angularjs
You can use
headers.setContentType(MediaType.parseMediaType("application/pdf;charset=utf-8"));
Spring MVC pdf generation
tldr; you should be able to use a view and save it to a file.
Try using Flying Saucer and its iTextRenderer when you overload AbstractPdfView.
import org.xhtmlrenderer.pdf.ITextRenderer;
public class MyAbstractView extends AbstractView {
OutputStream os;
public void buildPdfDocument(Map<String,Object> model, com.lowagie.text.Document document, com.lowagie.text.pdf.PdfWriter writer, HttpServletRequest request, HttpServletResponse response){
//process model params
os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
String url = "http://www.mysite.com"; //set your sample url namespace here
renderer.setDocument(document, url); //use the passed in document
renderer.layout();
renderer.createPDF(os);
os.close();
}
}
protected final void renderMergedOutputModel(Map<String,Object> model,
HttpServletRequest request,
HttpServletResponse response)
throws Exception{
if(os != null){
response.outputStream = os;
}
public byte[] getPDFAsBytes(){
if(os != null){
byte[] stuff;
os.write(stuff);
return stuff;
}
}
}
You'll probably have to tweak the sample implementation shown here, but that should provide a basic gist.
Related Topics
"Unable to Acquire Application Service" Error While Launching Eclipse
Changing the Shapes of Points in Scatter Plot
Java:Why Should We Use Bigdecimal Instead of Double in the Real World
Missing Artifact Com.Sun:Tools:Jar
Docker: Combine Multiple Images
How to Update a Value, Given a Key in a Hashmap
How to Make Java Honor the Dns Caching Timeout
Best Way to Make Java's Modulus Behave Like It Should with Negative Numbers
How to Decode JSON with Unknown Field Using Gson
Java Ioexception "Too Many Open Files"
Sorting a List of Points with Java
File Upload with Java (With Progress Bar)
Instanceof - Incompatible Conditional Operand Types
What Are the Differences Between Arraylist and Vector