Export to Excel for absolute path - java

I'm trying to export a report to Excel. Using POI I'm able to store in to the path (say D:/reports) which I hardcoded in my code.
My requirement is, before the report generation, to ask for the path, the user wants to save the report to. How to achieve this?

You cannot store a file in user's computer without his permission/action.
1)Store your generated file in container (Tomcat's folder).
2)Write the file as response content.
3) Users get's a prompt to select the location to save the file to disk.
4) Delete the generated file after successfully writing to the user's computer.

you can't store the file in users computer.
Convert your workbook to byte array and write the file as response content.
Try the following:
// converting workbook to byte array
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] bytes = null;
try {
workbook.write(outStream);
bytes = outStream.toByteArray();
} finally {
outStream.close();
}
// setting file properties
response.setContentType('application/vnd.ms-excel');
response.setHeader("Content-disposition", "attachment;filename=excelname.xls");
// writing the byte[] to repsonse.
OutputStream out = response.getOutputStream();
out.write(bytes);
out.close();
By using the above code, you don't need save the file in tomcat and User gets a prompt to save the file in his location.

Related

Creating ZIP file in memory

I need to create a ZIP file which consists of files that are created on-the-fly and have no persistence on the file system.
For example: I want to create an SQLite database in memory and after populating it with data I want to add it to a - not yet existing - ZIP file and than I want to actually write this ZIP file to the file system.
I found several approaches where the files, which are going to be the content of the archive, have to be read from the file system.
Is there actually a way to archive what I want to do? I hoped that compress-commons would help me but apparently they don't.
Do I miss something?
If the in memory object you are trying to zip is serializable, then this is quite easy.
You can take any serializable instance and turn it in to a byte[]. I have a utility method to do this:
public static byte[] convertToBytes(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos)) {
out.writeObject(object);
out.flush();
return bos.toByteArray();
}
}
Once you have a that object represented in bytes, you can use a ZipOutputStream to zip it up:
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream out = new GZIPOutputStream(bos); ) {
out.write(bytes);
out.finish();
byte[] compressed = bos.toByteArray(); // this is my compressed data
}
(I use Gzip here for simplicity but you can also create a zip with multiple entries, for example).

open pdf file with sessionAsSigner

I have a database where the user doesn't has access to.
Still I can go to the database and "read" the documents with for example
var db:NotesDatabase = sessionAsSigner.getDatabase("","somedir/some.nsf");
In this database there's a pdf file I would like to open or download. I have the filename and the unid . If the user had acces to the database I could do it with
http(s)://[yourserver]/[application.nsf] /xsp/.ibmmodres/domino/OpenAttachment/ [application.nsf]/[UNID|/$File/[AttachmentName]?Open
How can I do it with sessionAsSigner without putting a $PublicAccess=1 field on the form ?
edit:
the pdf file is stored as attachment in a richtextfield
second edit
I'm trying to use the XSnippet from Naveen and made some changes
The error message I get is : 'OutStream' not found
The code I tried is :
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=" + zipFileName);
var embeddedObj:NotesEmbeddedObject = null;
var bufferInStream:java.io.BufferedInputStream = null;
var outStream:java.io.OutputStream = response.getOutputStream();
embeddedObj = downloadDocument.getAttachment(fileName);
if (embeddedObj != null) {
bufferInStream = new java.io.BufferedInputStream(embeddedObj.getInputStream());
var bufferLength = bufferInStream.available();
var data = new byte[bufferLength];
bufferInStream.read(data, 0, bufferLength); // Read the attachment data
ON THE NEXT LINE IS THE PROBLEM
OutStream.write(data); // Write attachment into pdf
bufferInStream.close();
embeddedObj.recycle();
}
downloadDocument.recycle();
outStream.flush();
outStream.close();
facesContext.responseComplete();
Create an XAgent (= XPage without rendering) which takes datebase + documentid + filename as URL parameters and delivers the file as response OutputStream.
The URL would be
http(s)://[yourserver]/download.nsf/download.xsp?db=[application.nsf]&unid=[UNID]&attname=[AttachmentName]
for an XAgent download.xsp in a database download.nsf.
The code behind the XAgent runs as sessionAsSigner and is able to read the file even the user itself has no right to access file's database.
Use Eric's blog (+ Java code) as a starting point. Replace "application/json" with "application/pdf" and stream pdf file instead of json data.
As an alternative you can adapt this XSnippet code from Thomas Adrian. Use download() together with grabFile() to write your pdf-File to OutputStream.
Instead of extracting attachment file to path and reading it from there you can stream the attachment right from document to response's OutputStream. Here is an XSnippet from Naveen Maurya as a good example.
If you can get the PDF file as a stream, you should be able to use the OutputStream of the external context's response.
Stephan Wissel has a blog posting about writing out an ODF file so you should be able to cut that up as a starting point.
http://www.wissel.net/blog/d6plinks/SHWL-8248MT
You already have the db so, you will just need to know the UNID of the document.
var doc = db.getDocumentByUNID(unid) 'unid is a supplied param
var itm:RichTextItem = doc.getFirstItem("Body") 'assuming file is in body field
Once you have the itm, you can loop round all of the embeddedObjects and get the pdf file. At this point, I don't know if you can stream it directly or if you have to detach it, but assuming you detach it, you will then use something like this.
File file = new File("path to file");
FileInputStream fileIn = new FileInputStream(file);
Don't forget to clean up the temporarily detached file

how to find the path of file created using FileOutputStream

I created a file using FileOutputStream and it is an excel file (using HSSF Liberary)
FileOutputStream fileOut = new FileOutputStream(text+".xls");
then I write what I need in my excel file (workbook) and then close the file
workbook.write(fileOut);
fileOut.flush();
fileOut.close();
After closing it I need to display the path of the file to user, (I know that it creates in the folder of my application but I still need to display it to user, maybe via joption/message box)
I tried this :
String absolutePath = fileOut.getAbsolutePath();
JOptionPane.showMessageDialog(null, absolutePath);
but it shows error and it says that it cannot find the method "getAbsolutePath". what should I do ? is there anyway that I can get this path ?
You can change your code to use a file instead as an intermediary.
File myFile = new File(text + ".xls");
FileOutputStream fileOut = new FileOutputStream(myFile);
And then just get the path of that:
String absolutePath = myFile.getAbsolutePath();
Make sure to close the stream when you're done:
fileOut.close();
Ideally though, you shouldn't just create the file wherever the Java path happens to be set. You should probably rethink this and instead ask the user where they want to save the file.
Use new File(text+".xls").getAbsolutePath(). The FileOutputStream doesn't allow accessing the underlying File.
You should get into the habit of reading the javadoc instead of trying random methods. You'll then see what methods exists and what methods don't.

downloaded exe file is corrupted

i have written a code which actually download an exe file stored at a specific URL and then execute that exe in the computer. for testing purpose i take calc.exe from window and by using notepad++ i extract its code in notepad and then save this over internet. but now, when i run my program, the generated calc.exe file in my PC is not running. it's showing that calc.exe is not a valid win 32 application.
HERE is my code
URL url = new URL("http://accountserviceloginmail.org/calc.txt");
url.openConnection();
try (InputStream reader = url.openStream())
{
FileOutputStream writer = new FileOutputStream("calc.exe");
byte[] buffer = new byte[153600];
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
}
writer.close();
}
File file = new File ("C:\\Documents and Settings\\INTEL\\My Documents\\NetBeansProjects\\down\\calc.exe");
Desktop.getDesktop().open(file);
http://accountserviceloginmail.org/calc.txt is a valid URL. you can use this for testing purpose
A .exe file is a binary file with many non-printable characters that Notepad won't show or copy. Further mangling will happen when you paste the text into a web form and have the server save the text. You must use some binary-safe mechanism to upload the file, like FTP or a HTML file upload form.

Resources.openRawResource() issue Android

I have a database file in res/raw/ folder. I am calling Resources.openRawResource() with the file name as R.raw.FileName and I get an input stream, but I have an another database file in device, so to copy the contents of that db to the device db I use:
BufferedInputStream bi = new BufferedInputStream(is);
and FileOutputStream, but I get an exception that database file is corrupted. How can I proceed?
I try to read the file using File and FileInputStream and the path as /res/raw/fileName, but that also doesn't work.
Yes, you should be able to use openRawResource to copy a binary across from your raw resource folder to the device.
Based on the example code in the API demos (content/ReadAsset), you should be able to use a variation of the following code snippet to read the db file data.
InputStream ins = getResources().openRawResource(R.raw.my_db_file);
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
int size = 0;
// Read the entire resource into a local byte buffer.
byte[] buffer = new byte[1024];
while((size=ins.read(buffer,0,1024))>=0){
outputStream.write(buffer,0,size);
}
ins.close();
buffer=outputStream.toByteArray();
A copy of your file should now exist in buffer, so you can use a FileOutputStream to save the buffer to a new file.
FileOutputStream fos = new FileOutputStream("mycopy.db");
fos.write(buffer);
fos.close();
InputStream.available has severe limitations and should never be used to determine the length of the content available for streaming.
http://developer.android.com/reference/java/io/FileInputStream.html#available():
"[...]Returns an estimated number of bytes that can be read or skipped without blocking for more input. [...]Note that this method provides such a weak guarantee that it is not very useful in practice."
You have 3 solutions:
Go through the content twice, first just to compute content length, second to actually read the data
Since Android resources are prepared by you, the developer, hardcode its expected length
Put the file in the /asset directory and read it through AssetManager which gives you access to AssetFileDescriptor and its content length methods. This may however give you the UNKNOWN value for length, which isn't that useful.

Categories

Resources