Spring + GWTP: Excel file download from OutputStream not working - java

I have a GWTP application to export some data to an .xlsx file using Apache POI. Here is my presenter code.
protected void exportTable(String selectedPublisher, String selectedTarget, Drilldown drilldown) {
this.excelServiceAsync.generateDataEnrichmentExport(selectedPublisher, new AsyncCallback<Void>() {
#Override
public void onSuccess(Void result) {
Window.open(GWT.getModuleBaseURL() + "rpc/excelDownload", "_blank", "");
}
#Override
public void onFailure(Throwable caught) {
Window.alert("Error!");
}
});
}
Here is my excel generation code which is asynchronously called by the presenter.
workbook = new XSSFWorkbook();
sheetOne = workbook.createSheet("Export One");
// TODO Typical POI coding stuff
FileOutputStream out = null;
try {
out = new FileOutputStream(new File("file.xlsx"));
workbook.write(out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And here is my controller which I use to download the excel file.
#ResponseBody
#RequestMapping(value = "/excelDownload")
public String downloadExcel(HttpServletRequest request, HttpServletResponse response){
File file = new File("file.xlsx");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename="
+ "file.xlsx");
response.setHeader("Content-Length", String.valueOf(file.length()));
FileInputStream is = null;
try {
is = new FileInputStream(file);
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
response.getOutputStream().close();
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e.getCause());
} catch (IOException e) {
logger.error(e.getMessage(), e.getCause());
} finally {
try {
is.close();
} catch (Exception ex) {
return "redirect:/error/internal";
}
}
return "";
}
I'm generating the excel file and putting on the output stream. Then in the controller I get the data from the output stream to download as an .xlsx file. This isn't working. The working file is generated and saved on the server. But the file that is downloaded by the browser is a corrupted file. I'm not really sure why. Please help!

You forgot to close your FileOutputStream out. Maybe try using the try (resource) {...} syntax of Java7?

Try set response.setContentLength((int) file.length());

Related

Generate doc use docx4j, it gose different on windows and linux server

when I use docx4j to generate doc from HTML and output through java servlet, it works well on Windows system, I can download and open the doc file normally.
When I put the project on Linux server, I can also download the doc file, but when openging file, it alert that the file is broken. I must click the confirm and restore the file.then open it normally.
my core code is like this.
how can i get the same result as windows?
code in jsp:
String vhtml = DownHtml2DocUtil.replaceSvgData2Base64(request);
response.reset();
response.setContentType("application/octet-stream");//设置为字节流
OutputStream output = null;
try {
output = response.getOutputStream();
response.addHeader("Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".doc");
DownHtml2DocUtil.genDocFromHtml(vhtml, output);
} catch (Exception e) {
} finally {
try {
if (output != null) {
output.close();
}
} catch (Exception e) {
}
}
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
code in java like this:
public static void genDocFromHtml(String html, OutputStream out)
throws EMPException {
try {
WordprocessingMLPackage wordMLPackage;
wordMLPackage = WordprocessingMLPackage.createPackage();
XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(
wordMLPackage);
wordMLPackage.getMainDocumentPart().getContent()
.addAll(XHTMLImporter.convert(html, "utf-8"));
// wordMLPackage.save(out); -- i tried both method
new Save(wordMLPackage).save(out);
} catch (InvalidFormatException e) {
throw new EMPException(e);
} catch (Docx4JException e) {
throw new EMPException(e);
} catch (Exception e) {
e.printStackTrace();
}
}
any suggestion will be appreciate , thanks anyway;

Spring MVC Safe way to Upload, generate and download a file

I´m working on a WebApp with Spring MVC and Maven. I have the following process: First of all the User has to upload a file. Afterwards the uploaded file will be edited. Last but not least I want to create a download which contains the edited file.
The first step "Upload File" works well. I have a controller which contains the following POST method:
#RequestMapping(value = "/CircleUp", method = RequestMethod.POST)
public String circleUpPost(HttpServletRequest request, Model model, //
#ModelAttribute("circleUpForm") CircleUpForm circleUpForm) {
return this.doUpload(request, model, circleUpForm);
}
private String doUpload(HttpServletRequest request, Model model, //
CircleUpForm circleUpForm) {
File file = circleUpForm.getFile();
if (file != null) {
try {
//Some edit stuff
serialize(file, SerializationModeEnum.Standard);
} catch (Exception e) {
e.printStackTrace();
}
}
model.addAttribute("uploadedFiles", file);
return "uploadResult";
}
protected static String serialize(File file, SerializationModeEnum serializationMode) {
java.io.File test = null;
try {
test = java.io.File.createTempFile("Test", ".pdf");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
file.save(test, serializationMode);
} catch (Exception e) {
e.printStackTrace();
}
// test.deleteOnExit();
return test.getPath();
}
In the "serialize" Method my PDFClown File will be saved to a temp folder.
Afterwards the "uploadResult" page will be appear which contains the folloing code:
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta charset="UTF-8">
<title>Download</title>
</head>
<body>
<h3>Download Files:</h3>
CircleUp
</body>
</html>
When the User clicks on the link another Controller will be called which handles the download. I dont know how to design the controller so that it can works with the edited file which I saved in my temp folder. I think it should look like that :
#RequestMapping(value = "/Download")
public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
final String temperotyFilePath = ???
String fileName = "Test.pdf";
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = convertPDFToByteArrayOutputStream(temperotyFilePath + "\\" + fileName);
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
} catch (Exception e1) {
e1.printStackTrace();
}
}
private ByteArrayOutputStream convertPDFToByteArrayOutputStream(String fileName) {
InputStream inputStream = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
inputStream = new FileInputStream(fileName);
byte [] buffer = new byte [1024];
baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return baos;
}
I have two questions now:
How can the DownloadController attain the temp path to the file?
Is this process of Uploading,Generating and Downloading a File safe? Or is there a better way to handle this process?
I´m new to Spring MVC and WebApp Development and I´m thankful for every suggestion :)
You can use the same approach you use in the upload
test = java.io.File.createTempFile("Test", ".pdf");
All you need is to point to the same file and then read it.
If you need a custom dir for the files saving you can either define a property - my.file.path=some path here or
use system temp dir
public class Main {
public static void main(String[] args) {
String property = "java.io.tmpdir";
String tempDir = System.getProperty(property);
System.out.println("OS current temporary directory is " + tempDir);
}
}
Got the code from the link
Actually the approach is not safe. What to do if 2 different users upload files with the same name& What if one is uploaded and another user tries to download it? What is amount of files is millions? etc. etc.
It's better to use independent file storage but for test project it's fine

data being written to file is not appearing

in one of the activities when a button is pressed i want to create a file on the extran storage. so i wrote
the below code to do so.
but in the end the file is created but empty..why?
code:
public void tx(byte[] data) {
Log.w(TAG, CSubTag.bullet("tx"));
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "test.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
OutputStream os = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(os);
try {
bos.write("data_stream".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Please close the OutputStream and BufferedOutputStream inside finally block. Otherwise, the data will not be written.

How to create KMZ file from KML on the fly using Java

I am trying to create kmz file from kml file on the fly and render it as a stream of bytes in web application.
But when I downloaded generated kmz file, I couldn't open it using archive manager on Ubuntu.
I view similar questions on this site, but it don't work.
Can someone help me and explain what I do wrong?!
This is my code.
#Public public void retrieveKmlInOldFormat() {
File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
String kmlFileContent = null;
try {
String kmlUrl = file.toURI().toURL().toString();
kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(
kmlParserLocal.load(kmlUrl));
} catch (MalformedURLException e) {
e.printStackTrace();
}
String zippedFileName = "old_fmt_map.kmz";
String zippedKml = compressKmlFile(kmlFileContent,zippedFileName);
response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
renderBinary(new ByteArrayInputStream(zippedKml.getBytes()),zippedFileName);
return;
}
Compress method code:
private String compressKmlFile(String kmlFileContent,String zipEntryName){
String zippedContent = null;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ZipOutputStream zipStream = new ZipOutputStream(new
BufferedOutputStream(byteStream));
ZipEntry zipEntry = null;
zipEntry = new ZipEntry("doc.kml");
try {
zipEntry.setSize(kmlFileContent.getBytes("UTF-8").length);
zipStream.putNextEntry(zipEntry);
zipStream.write(kmlFileContent.getBytes("UTF-8"));
zipStream.closeEntry();
zippedContent = new String(byteStream.toByteArray(),"UTF-8");
} catch (IOException e) {
logger.error("Error while zipping kml file content");
}
finally {
try {
byteStream.close();
zipStream.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return zippedContent;
}
The problem is about downloaded corrupted kmz archive. This problem can be resolved by using output stream of http response as constructor argument for ZipOutputStream class.
Solution is in this code.
#Public public void retrieveKmlInOldFormat(){
File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
String kmlFileContent = null;
try {
String kmlUrl = file.toURI().toURL().toString();
kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(kmlParserLocal.load(kmlUrl));
} catch (MalformedURLException e) {
e.printStackTrace();
}
response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
response.setHeader("Content-Disposition", "attachment; filename=\"old_fmt_map.kmz\"");
renderAsKmz(response, kmlFileContent,"old_fmt_map.kml");
return;
}
private void renderAsKmz(Response response,String kmlFileContent,String zipEntryName){
ZipOutputStream zipStream = new ZipOutputStream(response.out);
ZipEntry zipEntry = new ZipEntry(zipEntryName);
try {
zipStream.putNextEntry(zipEntry);
zipStream.write(kmlFileContent.getBytes());
} catch (IOException e) {
logger.error("Error while zipping kml file content : " + e.getMessage());
}
finally {
try {
zipStream.closeEntry();
zipStream.close();
} catch (IOException e) {
logger.error("Error while closing zipped stream : " + e.getMessage());
}
}

Strange issue when creating a new file

I have the below 2 methods, supposed to read and write to a file:
/* Write content to a file */
private void writeToFile(ArrayList<String> list) {
#SuppressWarnings("unused")
File file = new File("jokesBody1.bjk");
FileOutputStream fos;
if(list != null){
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject("");
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* Read file's content */
private ArrayList<String> readFromFile() {
File file = new File("jokesBody1.bjk");
ArrayList<String> list = new ArrayList<String>();
try {
ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
try {
list = (ArrayList)ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (IOException e) {
Log.e("log activity", "Can not read file: " + e.toString());
}
return list;
}
When I'm calling the above methods I'm getting this error:
02-15 10:28:48.165: E/log activity(1743): Can not read file: java.io.FileNotFoundException: /jokesBody1.bjk: open failed: ENOENT (No such file or directory)
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
File file = new File("jokesBody1.bjk");
Why I'm getting this error? I know that I'm missing something small - probably a piece of code that creates the file(I'm not sure), but as a beginner, I'm not able to spot the issue.
File file = new File("jokesBody1.bjk");
Just creates a File objects that points to that path, but no actual file.
Use
file.createNewFile();
To actually create the file.
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
Actually, no. It only creates a File object, an then java assumes that file to exist.

Categories