get a csv file as a http download - java

I have to create a CSV file on a nightly process and avail those files to client as an http download.
I have created a CSV with the help PLSQL block as:
DECLARE
F UTL_FILE.FILE_TYPE;
CURSOR C1 IS SELECT emp_id, name FROM employee;
C1_R C1%ROWTYPE;
BEGIN
F := UTL_FILE.FOPEN('EXPORT_DIR','employee.csv','w',32767);
FOR C1_R IN C1
LOOP
UTL_FILE.PUT(F,C1_R.emp_id);
UTL_FILE.PUT(F,','||C1_R.name);
UTL_FILE.NEW_LINE(F);
END LOOP;
UTL_FILE.FCLOSE(F);
END;
/
this will create a CSV file "employee.csv" on the database server. Now I have to avail this file to the clients as a HTTP downloadable file. How to do that ?

You can provide one Servlet to download your file as a csv format.
DoanloadServlet.java :
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
//set content type to csv and response as attachment
response.setHeader("Content-Type", "text/csv");
response.setHeader("Content-Disposition", "attachment; filename=Myfile.csv");
OutputStream out = response.getOutputStream();
//read your file from database in outputstream
FileInputStream in = new FileInputStream(my_file);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
catch(Exception e)
{
//Exception handling
}
}
Give user a link and call this servelet with required parameter to find file from database.
You link look like this
http://serveraddress.com/DoanloadServlet?fileName=name_of_file

I found it easy to copy the generated file web server. we can just use SCP or FTP to the generated file on webserver. e.g.
scp /mnt/csv_dir/feed.csv root#server:/home/stackoverflow/www/csv
Add this command in a nightly process to run
The above command will move the feed.csv from csv_dir to csv folder of web server.
now we will be able to access the file using the web url.

Related

Is there a way to provide file download without reading the file from path in Java?

In my program I have a getRequest (JavaSpark) that offers me an Excel file created in Java for download.
To do this, I create the Excel file, save it in a folder and then read the file via the path.
Works.
Code - ExcelCreation:
public void createPlanWorkbook() throws Exception {
...
...
do something with workbook...
workBook.write("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
}
Code - request:
get("/excelfile", ((request, response) -> {
response.header("Content-disposition", "attachment; filename=Excel.xlsm;");
File file = new File("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
OutputStream outputStream = response.raw().getOutputStream();
outputStream.write(Files.readAllBytes(file.toPath()));
outputStream.flush();
return response;
}));
I wonder if there is another way to implement this. Is the step of saving and then reading the file necessary? Or is there a way to put the file directly from Javaobject into the request.
For example:
outputStream.write(ExcelCreaterObject().getWorkbook());
It seems that you are using Apache POI SmartXls to create an Excel workbook. Looking at its Javadoc, it seems that the Workbook.write method accepts an outputstream to write to.
So, you should be able to do write to the response stream directly, something like:
get("/excelfile", ((request, response) -> {
response.header("Content-disposition", "attachment; filename=Excel.xlsm;");
File file = new File("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
OutputStream outputStream = response.raw().getOutputStream();
// do some stuff with the workbook
workbook.write(outputStream);
return response;
}));

SmartGWT ~ DSRequest download file

I am writing a server side class in smartGWT that fetches a record from a table and downloads a binary blob as a file from the database. The goal is to get the binary file attachment to download to local computer.
I was told that I could use DSRequest.getUploadedFile(attachment) to download the file but looking into it, it looks as though this method does not get an uploaded file from the database to download but gets a file to upload to the database.
Is there a way that I can get a file from the database and return it to the user as a download in server side code? We know we can do this in client side code but we would like to be able to do it on the server.
Here is how I am getting the record that contains the file I want to send to the user.
DSRequest dsReq = new DSRequest("table", "fetch");
dsReq.setCriteria("criteria", processFlowData.getVariableMap().get("critera"));
DataSource ds = dsReq.getDataSource();
DSResponse dsResp = ds.execute(dsReq);
if (dsResp.getStatus() < 0) {
//Handle Errors
} else {
if (!dsResp.getRecord().isEmpty()) {
//Download File Here
}
}
I am using Eclipse Kepler, SmartGWT, Java EE.
you could do something like this:
public static void downloadFile(DSRequest dsRequest, RPCManager rpcManager, HttpServletResponse servletResponse) throws Exception {
rpcManager.doCustomResponse();
ServletOutputStream outputStream = servletResponse.getOutputStream();
servletResponse.addHeader("Content-disposition", "attachment; filename=test.pdf");
servletResponse.setContentType("application/x-www-form-urlencoded");
OutputStream responseOutputStream = servletResponse.getOutputStream();
// write file to responseOutputStream
responseOutputStream.flush();
responseOutputStream.close();
}

Open file from network drive

I'm trying to create hyperlinks to open files from network drive G:
This is part of my testing servlet:
#WebServlet(name="fileHandler", urlPatterns={"/fileHandler/*"})
public class FileServlet extends HttpServlet
{
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String requestedFile = request.getPathInfo();
...
File file = new File("G:/test_dir", URLDecoder.decode(requestedFile, "UTF-8")); // cesta se nacita v kazdem doGet
String contentType = getServletContext().getMimeType(file.getName());
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try
{
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
}
finally
{
close(output);
close(input);
}
}
}
My HTML component:
TEST FILE
Network drive is mapped on application server as G:\
Everything is working fine on my localhost application server. I'm able to open file from local drive C: and even from the same network drive G:.
When I start the JSF application on real server, I'm able to open files from local drive only. Not from G: drive.
I've tried to simple JAVA application (to find if java instance has an access to network drive) and it works on both (server and dev.PC):
public class Test
{
static void main(String[] args)
{
String path = "G:/test_dir/test.txt";
File file = new File(path);
System.err.println(file.exists() ? "OK" : "NOK");
}
}
I've tried different URI schemes:
G:/test_dir
G:\\test_dir
And following doesn't work at all:
file://server/g:/test_dir
///server/g:/test_dir
\\\\server\\g\\test_dir ---> in fact, this should work
Where should be a difference between my develop PC and application server?
SOLUTION:
I've found that links to network drive doesn't work in standalone Tomcat, but works in Eclipse + Tomcat, so I have to use complete URI:
Case Eclipse + Tomcat: Path G:/test_dir/test.txt works
Case Standalone Tomcat: Path \\\\server\\g\\test_dir\\test.txt works
If you can debug your server and look at the logs, try this:
String requestedFile = request.getPathInfo();
log.debug('requestedFile='+requestedFile);
String decodedFilename = URLDecoder.decode(requestedFile, "UTF-8");
log.debug('decodedFilename='+decodedFilename);
File dir = new File("G:/test_dir");
log.debug('File g:/test_dir is a dir:'+dir.isDirectory());
File file = new File(dir, decodedFilename);
log.debug('requested file = '+file.getAbsolutePath());
log.debug('file exists = '+file.isFile());
If you do not have a logging framework set up, you can use System.out.println() instead of log.debug(), but that's not recommended for production use.
This won't solve your problem, but you'll be able to see what's going on.
I've found that links to network drive doesn't work in standalone Tomcat, but works in Eclipse + Tomcat, so I have to use complete URI:
Case Eclipse + Tomcat: Path G:/test_dir/test.txt works
Case Standalone Tomcat: Path \\\\server\\g\\test_dir\\test.txt works

java.io.FileNotFoundException: /u01/app/webapps/out/pj/Create.xlsx

I am trying to Compare last modified date of two excel files and replace the old file with new file.
In Scenario : When there is no file in the first place, so the code copies the file to that location and later reads it.
Issue is : It throws a FileNotFound exception when the excel file is not present on the server,even after writing the file to the
server(via code),but the file is not seen on the server. It works on
my machine(windows),but fails when deployed on server.
Again, it works like charm when the file is present on the server,while the old is being replaced by the new file.
Can you please help and explain on why its failing in the above scenario,and only on server ?
if(row.getValue("fileType").toString().equals("xlsx")&&checkindatefolder.after(localdate))
{
messagelist.add("we are going to get the replace file in the server");
InputStream inp=folder.getFile();
ZipInputStream izs = new ZipInputStream(inp);
ZipEntry e = null;
while ((e = izs.getNextEntry()) != null) {
System.out.println("e.isDirectory(): "+e.isDirectory());
if (!e.isDirectory()) {
filename=e.getName();
System.out.println("filename: "+filename);
FileOutputStream os=new FileOutputStream("path"+e.getName());
byte[] buffer = new byte[4096];
int read=0;
System.out.println("writing to file");
while ((read=izs.read(buffer))> 0) {
System.out.println("1111");
os.write(buffer,0,read);
}
System.out.println("writing to file complete");
inp.close();
os.flush();
os.close();
}
}
Do all parts of the path exist?
So in your example:
/u01/app/webapps/out/pj/Create.xlsx
Do all subdirectories exist?
/u01/app/webapps/out/pj
If not, than trying to write there might fail with a FileNotFoundException.
You should create the directories with Files.creatDirectories(Path) first.

Create and download CSV file in a Java servlet

I am working on Java ExtJS application in which I need to create and download a CSV file.
On clicking a button I want a CSV file to be downloaded to a client's
machine.
On buttons listener I am calling a servlet using AJAX. There I am
creating a CSV file.
I don't want the CSV file to be saved in the server. I want the file should be created dynamically with a download option. I want the contents of a file to be created as a string and then I will serve the content as file in which it will open as download mode in browser (this I have achieved in other language, but not sure how to achieve it in Java).
Here is my code only to create a CSV file, but I really don't want to create or save CSV file if I can only download the file as CSV.
public String createCSV() {
try {
String filename = "c:\\test.csv";
FileWriter fw = new FileWriter(filename);
fw.append("XXXX");
fw.append(',');
fw.append("YYYY");
fw.append(',');
fw.append("ZZZZ");
fw.append(',');
fw.append("AAAA");
fw.append(',');
fw.append("BBBB");
fw.append('\n');
CSVResult.close();
return "Csv file Successfully created";
} catch(Exception e) {
return e.toString();
}
}
Can any one help me on this.
Thanks
I got the solution and I am posting it below.
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=\"userDirectory.csv\"");
try
{
OutputStream outputStream = response.getOutputStream();
String outputResult = "xxxx, yyyy, zzzz, aaaa, bbbb, ccccc, dddd, eeee, ffff, gggg\n";
outputStream.write(outputResult.getBytes());
outputStream.flush();
outputStream.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
Here we don't need to save / store the file in the server.
Thanks
First of all you need to get the HttpServletResponse object so that you can stream a file into it.
Note : This example is something I Wrote for one of my projects and it works.Works on Java 7.
Assuming you got the HttpServletResponse you can do something like this to stream a file. This way the file will be saved into clients' machine.
public void downloadFile(HttpServletResponse response){
String sourceFile = "c:\\source.csv";
try {
FileInputStream inputStream = new FileInputStream(sourceFile);
String disposition = "attachment; fileName=outputfile.csv";
response.setContentType("text/csv");
response.setHeader("Content-Disposition", disposition);
response.setHeader("content-Length", String.valueOf(stream(inputStream, response.getOutputStream())));
} catch (IOException e) {
logger.error("Error occurred while downloading file {}",e);
}
}
And the stream method should be like this.
private long stream(InputStream input, OutputStream output) throws IOException {
try (ReadableByteChannel inputChannel = Channels.newChannel(input); WritableByteChannel outputChannel = Channels.newChannel(output)) {
ByteBuffer buffer = ByteBuffer.allocate(10240);
long size = 0;
while (inputChannel.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
return size;
}
}
What this does is, get an inputstream from your source file and write that stream into the outputstream of the HttpServletResponse. This should work since it works perfectly for me. Hope this helps. Sorry for my bad English.
I would like add something to the answer by gaurav. I recently had to implment this functionality in a project of mine and using javascript was out of the question becuase we had to support IE 9. What is the problem with IE 9?
(Export to CSV using jQuery and html), see the second answer in the link.
I needed an easy way to convert a ResultSet of a database query to a string which represent the the same data in CSV format. For that I used http://opencsv.sourceforge.net/ which provided an easy way to get a String ot of the ResultSet, and the rest is as above answer did it.
THe examples in the project soruce folder give good examples.

Categories

Resources