I wish to show this file on page but this code make a direct download
<a th:href="#{/pdf/Manjaro-User-Guide.pdf}">Show Pdf file</a>
I'm using Spring-Thymeleaf
Thanks!
I found the solution by commenting the line below
//response.setHeader("Content-Disposition", "attachment; filename=\"demo.pdf\"");
Here is the code example:
#GetMapping(value = "/pdf")
public void showPDF(HttpServletResponse response) throws IOException {
response.setContentType("application/pdf");
//response.setHeader("Content-Disposition", "attachment; filename=\"demo.pdf\"");
InputStream inputStream = new FileInputStream(new File(rootLocation + "/Manjaro-User-Guide.pdf"));
int nRead;
while ((nRead = inputStream.read()) != -1) {
response.getWriter().write(nRead);
}
}
Source
Thanks!
Related
I am trying to read a template file from disk and add a paragraph to it. Once done, i want to open this as a new file . The template should not have the changes saved into it. I tried the code below and the result is , the template is getting modified with the change but the file that is opening in browser does not have those changes. Clearly I am not getting the modified stream in response. How do I do that and also avoid making change to the template file .
public class DocumentCreator
{
public static void CreateDoc()
{
string strDoc = #"C:\Ash\foo.docx";
string txt = "Bruno Rovani";
using (Stream stream = File.Open(strDoc, FileMode.Open))
{
OpenAndAddToWordprocessingStream(stream, txt);
}
}
public static void OpenAndAddToWordprocessingStream(Stream stream, string txt)
{
// Open a WordProcessingDocument based on a stream.
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(stream, true))
{
// Assign a reference to the existing document body.
Body body = wordprocessingDocument.MainDocumentPart.Document.Body;
// Add new text.
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text(txt));
// HTTP response
HttpResponse Response = HttpContext.Current.Response;
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AddHeader("Content-Disposition", "attachment; filename=myfile.docx");
//stream = wordprocessingDocument.MainDocumentPart.GetStream();
stream.Position = 0;
stream.CopyTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
}
Resolved
Added wordprocessingDocument.MainDocumentPart.Document.Save();
PS: The template is still being modified. Don't think there is way to avoid this but since I will be doing a find and replace in real scenario it is not a big problem for me.
so the function looks like
public static void OpenAndAddToWordprocessingStream(Stream stream, string txt)
{
// Open a WordProcessingDocument based on a stream.
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(stream, true))
{
// Assign a reference to the existing document body.
Body body = wordprocessingDocument.MainDocumentPart.Document.Body;
// Add new text.
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text(txt));
**wordprocessingDocument.MainDocumentPart.Document.Save();**
// HTTP response
HttpResponse Response = HttpContext.Current.Response;
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AddHeader("Content-Disposition", "attachment; filename=myfile.docx");
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
This is my upload image code in Spring Boot:
String root = ctx.getRealPath("/");
File dir = new File(root + File.separatorChar + "images");
if (!dir.exists())
dir.mkdir();
String path = dir.getAbsolutePath() + File.separatorChar
+ product.getProductName() + "."
+ file.getContentType().split("/")[1];
System.out.println(path);
File file1 = new File(path);
try {
FileOutputStream fod = new FileOutputStream(file1);
fod.write(file.getBytes());
fod.close();
product.setProductPicture("/images/" + product.getProductName()
+ "." + file.getContentType().split("/")[1]);
} catch (IOException e) {
e.printStackTrace();
}
The uploading of files works fine, only problem with this code is that when i use ctx.getRealPath("/") it returns temporary location and when i restart the spring boot app i loose already existing files which was already uploaded as it creates a new temporary directory.
This causes some problem as i also have to display this pics on my site and now it returns "image not found error".
So I needed a solution which will allow me to upload files in a permanent location and serve files from there on the browser.
Note: I'm using thymeleaf for views.
I found a solution for my problem. I created a new function which will only return bytes[] and sent as response body as follows:
#RequestMapping(value = "image/{imageName}")
#ResponseBody
public byte[] getImage(#PathVariable(value = "imageName") String imageName) throws IOException {
File serverFile = new File("/home/user/uploads/" + imageName + ".jpg");
return Files.readAllBytes(serverFile.toPath());
}
And in html <img alt="Image" th:src="#{image/userprofile}" width="250" height="250"/>
Here is how I did it.
Step 1: Create a uploads folder in your project directory.
Step 2: Create ResourceConfig file
#Configuration
public class ResourceConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploads/**").addResourceLocations("file:uploads/");
}
}
Step 3: Add your html thymleaf
<img th:src="#{'/uploads/' + ${someobject.someAttribute}}"/>
Thanks a lot. I have to do this but with an image storage in my db, as follows:
#GetMapping("/muestra/{idproducto}")
#ResponseBody
public byte[] muestraImagen(Model model,
//id of the product i need to show the picture
#PathVariable("idproducto")Integer idproducto, HttpServletResponse response) {
//object from database
Productos producto = productosRepository.findByIdproducto(idproducto);
logger.info("sal imagen yo te invoco");
//return the attr of my object (blob)
return producto.getArchivo();
}
and in html:
<img alt="Image" th:src="#{/tienda/productos/muestra/{id}(id=${producto.idproducto})}" width="250" height="250"/>
I am trying to download a .csv file on clicking the Download button in my jsp.The jsp code is like following......
<form:form method="POST" id="poCSVForm"
action="downloadPoCsv" commandName="poCSVcmd" modelAttribute="poCSVcmd">
<div class="content">
<fieldset>
<legend>Page Name</legend>
<div>
<div class="contentpane">
<table>
<tr>
<td><button type="submit" value="Download" id="downId" class="dwnldbtn">Download</button>
<button type="button" class="exit smallbtn" value="Exit">Exit</button></td>
</tr>
</table>
</div>
</div>
</fieldset>
</div>
</form:form>
Then my controller code is like this......
#RequestMapping(value = "/downloadPoCsv", method = RequestMethod.POST)
public void doPoCsvDownload(
#ModelAttribute("poCSVcmd") PurchaseOrderCSVBean poCsvBean,
Map<String, Object> model, HttpServletRequest req,HttpServletResponse response) throws IOException {
CSVWriter writer = null;
String filepath = null;
try {
HttpSession session = req.getSession();
Session hsession = (Session) session
.getAttribute(MOLConstants.HIBERNATE_SESSION_KEY);
filepath = "purchaseOrder" + new Date().getTime() + ".csv";
ServletContext context = req.getServletContext();
String realPath = context.getRealPath("");
System.out.println("appPath = " + realPath);
// construct the complete absolute path of the file
String fullPath = realPath + "\\stuff\\" + filepath;
System.out.println("fullPath = " + fullPath);
File downloadFile = new File(realPath);
try {
if (!downloadFile.exists()) {
if (downloadFile.mkdir()) {
} else {
throw new RuntimeException("Could not create directory");
}
}
} catch (Exception e) {
throw new RuntimeException();
}
String mimeType = context.getMimeType(fullPath); // get MIME type of the file
if (mimeType == null) {
mimeType = "application/octet-stream"; // set to binary type if MIME mapping not found
}
System.out.println("MIME type: " + mimeType);
// set content attributes for the response
response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
// set headers for the response
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",downloadFile.getName());
response.setHeader(headerKey, headerValue);
List<PoCsvUploadView> csvDataList = poService.getPoCsvData(poCsvBean.getExp_ind(),poCsvBean.getStdt(),poCsvBean.getEnddt());
FileWriter fwriter = new FileWriter(fullPath);
writer = new CSVWriter(fwriter, ',', CSVWriter.NO_QUOTE_CHARACTER);
String[] header = new String[31];
header[0] = "COMPANY_CD";
.......
header[30] = "VENDOR_TYPE";
List<String[]> li = new ArrayList<String[]>();
li.add(header);
for (PoCsvUploadView group : csvDataList)
{
String[] arr = new String[31];
arr[0] = group.getCompany_cd();
.....
arr[30] = group.getVendor_type();
li.add(arr);
}
writer.writeAll(li);
} catch (Exception e) {
e.printStackTrace();
logger.error("Exception >> ", e);
throw new CustomGenericException(
"Error occured while loading report!!");
}finally{
writer.flush();
writer.close();
}
}
Now When I am click on the download button, the csv file is being generated at the specific location ie on fullPath variable. But that file is not downloading through the browser, instead of that browser is downloading some file named downloadPoCsv(which is exactly same as my #RequestMapping in my controller method), which is not desired. Can you guys provides some help on this. Thanx in advance.And yes I am using OpenCsv jar.
To be clear here the issue is spring MVC not openCSV because your problem description is that you are trying to download a file and it is downloading a file with a different name.
CodeJava has a pretty good example of a Spring MVC download. Give that a try.
I want to display pdf file in webpage using iframe with spring framework. Instead of download options i have to show pdf file in my webpage. Pls anyone can help me.
Thanks in advance..
My java code:
Employee employee = employeeManager.getObjectOrNull(
Employee .class, id);
File file = new File(dir,
employee .getFileName());
org.apache.commons.io.FileUtils.writeByteArrayToFile(file,
employee .getfile());
if (employee != null) {
ControllerUtils.openFile(dir,
response, employee.getFileName());
String contentType = Utils.getContentType(employee
.getFileName());
response.setContentType(contentType);
response.setHeader("Cache-Control", "private, max-age=5");
I've got the solution. I used embed tag. My HTML code:
<embed width="900px" height="500px" name="plugin" src="/content/downloadPdf" type="application/pdf">
My java code
response.setContentType("application/pdf");
response.setHeader("Cache-Control", "private, max-age=5");
response.setHeader("Pragma", "");
if (file.length>0) {
response.setContentLength(file.length);
}
ServletOutputStream ouputStream = response.getOutputStream();
InputStream is = new ByteArrayInputStream(file);
try {
int b;
while ((b = is.read()) != -1) {
ouputStream.write(b);
}
} finally {
ouputStream.flush();
ouputStream.close();
is.close();
}
This question already has answers here:
JasperReports: How to call the report in jsp page
(6 answers)
Closed 6 years ago.
I'm new to JasperReports and dont know how to call jasper file from servlet. My report contains the pie chart.
You can prepare the Jasper file and stream it to the client.
bytes[] byteStream = JasperRunManager.runReportToPdf("myJasperReport.jasper",paramMap,databaseConn);
OutputStream outStream = servletResponse.getOutputStream();
response.setHeader("Content-Disposition","inline, filename=myReport.pdf");
response.setContentType("application/pdf");
response.setContentLength(byteStream.length);
outStream.write(bytes,0,bytes.length);
Here is a dummy report created within a Servlet file.
It is the same as it would be in normal Java class.
Just make sure you have the imports for your jasper report classes at the top of the file.
The bellow example builds a report from an XML datasource.
public class JasperServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
try {
String reportFile = "myJasperReport.jrxml";
File outputFile = new File("Report.pdf");
HashMap hm = new HashMap();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory
.newDocumentBuilder();
Document document = documentBuilder.parse(new File("myXml.xml"));
// Compile the report
JasperReport report = JasperCompileManager
.compileReport(reportFile);
JRXmlDataSource xml = new JRXmlDataSource(document, "/xml/root");
// Fill the report
JasperPrint print = JasperFillManager.fillReport(report, hm, xml);
// Create an Exporter
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.OUTPUT_FILE, outputFile);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
// Export the file
exporter.exportReport();
} catch (Exception e) {
e.printStackTrace();
}
}
}
A complete way to do this from the servlet would be:
public void myServletMethod(HttpServletRequest request, HttpServletResponse response) throws IOException{
JasperReport jasperReport = null;
JasperDesign jasperDesign = null;
Map parameters = new HashMap();
String path = getServletContext().getRealPath("/WEB-INF/");
jasperDesign = JRXmlLoader.load(path+"/relative/path/to/MyReport.jrxml");
jasperReport = JasperCompileManager.compileReport(jasperDesign);
byte[] byteStream = JasperRunManager.runReportToPdf(jasperReport, parameters, **new DataSourceOfYourPreference**);
OutputStream outStream = response.getOutputStream();
response.setHeader("Content-Disposition","inline, filename=myReport.pdf");
response.setContentType("application/pdf");
response.setContentLength(byteStream.length);
outStream.write(byteStream,0,byteStream.length);
}