How to create new excel document in java - java

Here I am using poi-jar to export data from database to excel it working fine . But here I want change instead of creating manual path. I wanted make that as to download automatically with out creating any manual path like this:
OutputStream file = new FileOutputStream(new File("D:\\venki1213.xls"));
And this is my code:
Session ses = HibernateUtil.getSessionFactory().openSession();
String query;
query = "from LibraryImportEntity ";
List<LibraryImportEntity> list = ses.createQuery(query).list();
ses.close();
System.out.println("list size" + list.size());
String filename = "D://ranjith//ranjith1213.xls";
OutputStream file = new FileOutputStream(new File("D:\\venki1213.xls"));
HSSFWorkbook hwb = new HSSFWorkbook();
HSSFSheet sheet = hwb.createSheet("new sheet");
HSSFRow rowhead = sheet.createRow((short) 0);
rowhead.createCell(0).setCellValue("Sl.No");
rowhead.createCell(1).setCellValue("Magazine Name");
rowhead.createCell(2).setCellValue("Volume No");
rowhead.createCell(3).setCellValue("Issue No");
rowhead.createCell(4).setCellValue("Cost");
int i = 1;
for (LibraryImportEntity l1 : list) {
System.out.println("sl_no" + l1.getSl_no());
System.out.println("Magazinename" + l1.getMagazinename());
System.out.println("sl_no" + l1.getVolumeno());
System.out.println("sl_no" + l1.getCost());
HSSFRow row = sheet.createRow((short) i);
row.createCell(0).setCellValue(l1.getSl_no());
row.createCell(1).setCellValue(l1.getMagazinename());
row.createCell(2).setCellValue(l1.getVolumeno());
row.createCell(3).setCellValue(l1.getIssueno());
row.createCell(4).setCellValue(l1.getCost());
i++;
}
try {
FileOutputStream fileOut = new FileOutputStream(filename);
hwb.write(file);
fileOut.close();
} catch (IOException ex) {
Logger.getLogger(LibraryExportDAO.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Your excel file has been generated!");
return "success";
}

If you are generating the excel in a browser just call the method you want to generate the excel file based on a url and set the response properties like this,
//1.Fill the data from db
//2.Set the response properties
String fileName = "Excel.xls";
response.setHeader("Content-Disposition", "inline; filename=" + fileName);
// Make sure to set the correct content type(the below content type is ok)
response.setContentType("application/vnd.ms-excel");
//3.Write to the output stream
Writer.write();//call write method of Writer class to write the data to o/p stream
Writer Class:
public class Writer {
private static Logger logger = Logger.getLogger("service");
/**
* Writes the report to the output stream
*/
public static void write(HttpServletResponse response, HSSFSheet worksheet) {
logger.debug("Writing excel data to the stream");
try {
// Retrieve the output stream
ServletOutputStream outputStream = response.getOutputStream();
// Write to the output stream
worksheet.getWorkbook().write(outputStream);
// Flush the stream
outputStream.flush();
}
catch (Exception e) {
logger.error("Unable to write excel data to the output stream");
}
}
}
In the response receiving end you'll be prompted to download the file in the browser window..
LINK

Instead of this code,
OutputStream file = new FileOutputStream(new File("D:\\venki1213.xls"));
Use,
OutputStream file = new FileOutputStream(new File("venki1213.xls"));
This will create a file in project folder.
Cheers ...... !

You have to write the file to response
ByteArrayOutputStream bos = null;
try {
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
bos = new ByteArrayOutputStream();
if (fis != null) {
byte[] buf = new byte[(int) file.length()];
for (int num; (num = fis.read(buf)) != -1;) {
bos.write(buf, 0, num);
}
}
byte[] bytes = bos.toByteArray();
response.setContentType("application/vnd.ms-excel");
final OutputStream fileOutputStream = response.getOutputStream();
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
}

Related

Creating a download for zip file containing text/csv from string variables

I currently need to create a zip file for downloading. This should contain two (2) csv files that are to be created from string variables. I'm at a loss on how I should do this. My draft is below.
public #ResponseBody Object getFileV1(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=Reassigned Tickets Report " + new Date().toString() + ".zip");
String stringValue1 = "This is a test value for csv1";
String stringValue2 = "This is a test value for csv2";
InputStream is1 = new ByteArrayInputStream(stringValue1.getBytes("UTF-8"));
InputStream is2 = new ByteArrayInputStream(stringValue2.getBytes("UTF-8"));
ZipInputStream zin;
ZipEntry entry;
ZipOutputStream zout= new ZipOutputStream(response.getOutputStream());
zin = new ZipInputStream(is1);
entry = zin.getNextEntry();
zout.putNextEntry(entry);
zin = new ZipInputStream(is2);
entry = zin.getNextEntry();
zout.putNextEntry(entry);
zout.closeEntry();
zin.close();
zout.close();
response.flushBuffer();
return null;
} catch (Exception e) {
e.printStackTrace();
return e;
}
}
Obviously this is not working. Probably because I'm still a novice at this. Please bear with me.
I get a "java.lang.NullPointerException" at the line where "zout.putNextEntry" is called. Would appreciate your advice. Thank you in advance.
I solved my problem after a day of looking around. This works for me. But I'm not sure if this is the most efficient way.
public #ResponseBody Object getFileV1(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=Test Report " + new Date().toString() + ".zip");
String stringValue1 = "This is a test value for csv1";
String stringValue2 = "This is a test value for csv2";
PrintWriter writer1 = new PrintWriter(new OutputStreamWriter(new FileOutputStream("stringValue1.csv"), "UTF-8"));
writer1.print(stringValue1);
writer1.close();
PrintWriter writer2 = new PrintWriter(new OutputStreamWriter(new FileOutputStream("stringValue2.csv"), "UTF-8"));
writer2.print(stringValue2);
writer2.close();
File file1 = new File("stringValue1.csv");
File file2 = new File("stringValue2.csv");
filesToZip(response, file1, file2);
file1.delete();
file2.delete();
response.flushBuffer();
return null;
} catch (Exception e) {
e.printStackTrace();
return e;
}
}
This is the method I got from another thread with a few edits.
public static void filesToZip(HttpServletResponse response, File... files) throws IOException {
// Create a buffer for reading the files
byte[] buf = new byte[1024];
// create the ZIP file
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
// compress the files
for(int i=0; i<files.length; i++) {
FileInputStream in = new FileInputStream(files[i].getName());
// add ZIP entry to output stream
out.putNextEntry(new ZipEntry(files[i].getName()));
// transfer bytes from the file to the ZIP file
int len;
while((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// complete the entry
out.closeEntry();
in.close();
}
// complete the ZIP file
out.close();
}
The only thing I don't love is that I had to create temporary files and delete them after processing.

Download dynamically created zip files in play framework

Hi i am trying to write a play framework service where i can download multiple files. I create zip of multiple file on the fly but i am not sure how to send it as a response in Play Framework i will show what i have done so far.
public Result download() {
String[] items = request().queryString().get("items[]");
String toFilename = request().getQueryString("toFilename");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos))) {
for (String item : items) {
Path path = Paths.get(REPOSITORY_BASE_PATH, item);
if (Files.exists(path)) {
ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
zos.putNextEntry(zipEntry);
byte buffer[] = new byte[2048];
try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(path))) {
int bytesRead = 0;
while ((bytesRead = bis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
} finally {
zos.closeEntry();
}
}
}
response().setHeader("Content-Type", "application/zip");
response().setHeader("Content-Disposition", "inline; filename=\"" + MimeUtility.encodeWord(toFilename) + "\"");
//I am confused here how to output the response of zip file i have created
//I tried with the `baos` and with `zos` streams but not working
return ok(baos.toByteArray());
} catch (IOException e) {
LOG.error("copy:" + e.getMessage(), e);
return ok(error(e.getMessage()).toJSONString());
}
return null;
}
i tried sending response with return ok(baos.toByteArray()); i was able to download file but when i open the downloaded file it give me error An error occurred while loading the archive.
You need to close the zip file. After adding all entries, do: zos.close()
On a side note, I would recommend writing the zip file to disk rather than keeping it in a memory buffer. You could then use return ok(File content, String filename) to send its content to the client.
I am adding this answer if someone wants to know what was the final code:
String[] items = request().queryString().get("items[]");
String toFilename = request().getQueryString("toFilename");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos))) {
for (String item : items) {
Path path = Paths.get(REPOSITORY_BASE_PATH, item);
if (Files.exists(path)) {
ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
zos.putNextEntry(zipEntry);
byte buffer[] = new byte[2048];
try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(path))) {
int bytesRead = 0;
while ((bytesRead = bis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
} finally {
zos.closeEntry();
}
}
}
zos.close(); //closing the Zip
response().setHeader("Content-Type", "application/zip");
response().setHeader("Content-Disposition", "attachment; filename=\"" + MimeUtility.encodeWord(toFilename) + "\"");
return ok(baos.toByteArray());
} catch (IOException e) {
LOG.error("copy:" + e.getMessage(), e);
return ok(error(e.getMessage()).toJSONString());
}
Thank you for the help! There are two extra changes I made so it works for me in scala playframework 2.5.x
instead of return ok(baos.toByteArray()) ,
use Ok.chunked(StreamConverters.fromInputStream(fileByteData))
Instead of reading byte to byte the file,FileUtils.readFileToByteArray(file) can be very helpful here.
Attached is the complete version of my code.
import java.io.{BufferedOutputStream, ByteArrayInputStream, ByteArrayOutputStream}
import java.util.zip.{ZipEntry, ZipOutputStream}
import akka.stream.scaladsl.{StreamConverters}
import org.apache.commons.io.FileUtils
import play.api.mvc.{Action, Controller}
class HomeController extends Controller {
def single() = Action {
Ok.sendFile(
content = new java.io.File("C:\\Users\\a.csv"),
fileName = _ => "a.csv"
)
}
def zip() = Action {
Ok.chunked(StreamConverters.fromInputStream(fileByteData)).withHeaders(
CONTENT_TYPE -> "application/zip",
CONTENT_DISPOSITION -> s"attachment; filename = test.zip"
)
}
def fileByteData(): ByteArrayInputStream = {
val fileList = List(
new java.io.File("C:\\Users\\a.csv"),
new java.io.File("C:\\Users\\b.csv")
)
val baos = new ByteArrayOutputStream()
val zos = new ZipOutputStream(new BufferedOutputStream(baos))
try {
fileList.map(file => {
zos.putNextEntry(new ZipEntry(file.toPath.getFileName.toString))
zos.write(FileUtils.readFileToByteArray(file))
zos.closeEntry()
})
} finally {
zos.close()
}
new ByteArrayInputStream(baos.toByteArray)
}
}

encoding xlsx as base64 and send it as an attachment

I have an assignment where i need to create a .xlsx and convert it to base64 and this file will sent as an attachment in an email webservice.The code for conversion of .xlsx to base64 is as below:
import java.io.*;
import org.apache.commons.codec.binary.Base64;
public class Test {
public static void main(String [] args) {
String fileName = "C:/Users/kk.txt";
try {
byte[] buffer = new byte[1000];
FileInputStream inputStream =
new FileInputStream(fileName);
int total = 0;
int nRead = 0;
String reference=null;
while((nRead = inputStream.read(buffer)) != -1) {
String name=(new String(buffer));
byte[] encodedBytes = Base64.encodeBase64(name.getBytes());
System.out.println(new String(encodedBytes));
}
inputStream.close();
System.out.println("Read " + total + " bytes");
}
catch(FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
fileName + "'");
}
catch(IOException ex) {
System.out.println(
"Error reading file '"
+ fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}
}
}
but when i send it as a mail using BPEL and when i open the file it shows general input/output error.But when i send it as a text it works fine. Should i not use this code for excel or where am i wrong.Am totally new to java.
Okay - my guess is that you're not changing the mimetype etc features of the email you're creating for the attachment ( and that it's default is text/html ).
Take a look here - which is for a word doc instead - but outlines what I think you should be doing ( assuming I found the right kind of BPEL )
For your file type ".xlsx", this table shows the appropriate mime-type is like
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
package com.denemeler;
import java.io.*;
import java.util.Base64;
public class test {
public static void main(String[] args) throws IOException {
String filePath = "D:\\test.xls";
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
fis.read(bytes);
String base64 = new sun.misc.BASE64Encoder().encode(bytes);
String destinationPath = "D:\\Destination\\donusmusHali.xls";
//decode Base64 String to image
FileOutputStream fos = new FileOutputStream(destinationPath);
bytes = new sun.misc.BASE64Decoder().decodeBuffer(base64);
fos.write(bytes);
fis.close();
fos.close();
}
}
this code works for encoding and decoding excel files.
Generally, we use filename.xls in outputStream to write our excel workbook.
But if need to send it over network in base64 format then ByteArrayOutputStream is the option to go for it:
Workbook workbook = new HSSFWorkbook();
ByteArrayOutputStream b = new ByteArrayOutputStream();
try {
workbook.write(b);
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
byte[] bytes = bos.toByteArray(
);
Base64.encodeBase64String(bytes);
This solution worked for me, As first excel was created using Apache POI then applied above code and converted it to base64, which when decoded over network then encoded file was getting opened in a excel application as expected. :)
You can follow same on https://nupur28ag.blogspot.com/2020/01/get-base64-from-excel-created-using.html

How to convert MultipartFile into byte stream

//Or any other solution to saving multipartfile into DB.
I tried with this way but getting error.
File fileOne = new File("file.getOrignalFileName");//what should be kept inside this method
byte[] bFile = new byte[(int) fileOne.length()];
try {
FileInputStream fileInputStream = new FileInputStream(fileOne);
//convert file into array of bytes
fileInputStream.read(bFile);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
questionDao.saveImage(bFile);
MultipartFile file;
byte [] byteArr=file.getBytes();
InputStream inputStream = new ByteArrayInputStream(byteArr);
//Start Photo Upload with Adhaar No//
if (simpleLoanDto.getPic() != null && simpleLoanDto.getAdharNo() != null) {
String ServerDirPath = globalVeriables.getAPath() + "\\";
File ServerDir = new File(ServerDirPath);
if (!ServerDir.exists()) {
ServerDir.mkdirs();
}
// Giving File operation permission for LINUX//
IOperation.setFileFolderPermission(ServerDirPath);
MultipartFile originalPic = simpleLoanDto.getPic();
byte[] ImageInByte = originalPic.getBytes();
FileOutputStream fosFor = new FileOutputStream(
new File(ServerDirPath + "\\" + simpleLoanDto.getAdharNo() + "_"+simpleLoanDto.getApplicantName()+"_.jpg"));
fosFor.write(ImageInByte);
fosFor.close();
}
//End Photo Upload with Adhaar No//

rename file after file upload

public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
// File result = new File("D:\\Netbeans Project\\mcGrawLibPro\\mcGrawLibPro-war\\web\\item", event.getFile().getFileName());
File bg = new File(extContext.getRealPath("//admin//images")+"//macback.png");
try {
bg.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
File f1 = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
result.renameTo(f1);
//System.out.println(f1);
System.out.println(result);
FileOutputStream fileOutputStream = new FileOutputStream(result);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
my problem is when i upload a picture type png such as aaa.png, it can upload on server but it not rename, after upload aaa.png and i re-upload this picture(aaa.png) it can change name but it have 2 file one is aaa.png and one is macback.png
What's wrong in my code?
Thank you !
Here's what I think you are trying to do:
When you upload a file, you want to call it macback.png, not its original file name.
When you upload a second file, you want to rename macback.png to bg.png first, then save the uploaded file as macback.png.
If that is the case, first you need to test for the existence of the macback.png file and rename it if it exists. Then you create a File object for the macback.png file and open a FileOutputStream to that file to write the uploaded file to.
Something like this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//macback.png");
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
Ok, so let's see if I got it this time:
You want the first A.png to save as A.png.
The second time A.png is uploaded, you want the first A.png to be renamed to macback.png and the second A.png to be stored as A.png.
If that's the case, try this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//mackback.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName() );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
I believe the issue is you are trying to rename result to f1 too early. At the point where you are calling result.renameTo(f1) you have not yet created the file referenced by result so the rename has no effect. You cannot rename a file before it exists on disk.
Now, you don't really need to rename result. Since you have not created the file, you can simply use f1 as the argument to FileOutputStream instead of result.

Categories