I am working on a Java function which is expected to return a protected Excel file (xlsx) in byte array.
public byte[] genProtectedExcel() {
SXSSFWorkbook workbook = new SXSSFWorkbook();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//Code of cells fill in...
//Should be code of workbook encryption...
workbook.write(baos);
return baos.toByteArray();
}
I found a solution which used the Encryption support of Apache POI: How to Protect Excel Workbook Via SXSSF?
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("foobaa");
InputStream is = <open the SXSSF workbook as stream>
OutputStream os = enc.getDataStream(fs);
IOUtils.copy(is, os);
However, OutputStream cannot be cast into ByteArrayOutputStream. I tried to find a way to convert the OutputStream into ByteArray but all failed.
Is there anyway to create a protect excel byte array?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
fs.writeFilesystem(baos );
return baos.toByteArray();
Related
If I got the OutputStream from the response , can you write the contents of the OutputStream to the response which will be sent back to the browser?
In my scenario i want to set a password to Excel file while downloading the sheet.
So that wrote the code like that.
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=TestFile.xls");
XSSFWorkbook wb = new XSSFWorkbook();
Sheet s = wb.createSheet("Demo");
Row row1 = s.createRow(0);
Row row2 = s.createRow(1);
// create cells in the row
Cell row1col1 = row1.createCell(0);
Cell row1col2 = row1.createCell(1);
Cell row1col3 = row2.createCell(0);
Cell row1col4 = row2.createCell(1);
// add data to the cells
row1col1.setCellValue("City Name");
row1col2.setCellValue("University");
row1col3.setCellValue("Hyderabad");
row1col4.setCellValue("JNTU");
// Add password protection and encrypt the file
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
// set the password
enc.confirmPassword("123");
// encrypt the file
OPCPackage opc = wb.getPackage();
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
fs.writeFilesystem(response.getOutputStream());
Here password was set to the excel sheet but the data was not able to open while getting the below error.
please check and provide your answers why am not getting the data. Thanks in advance.
Apache POI uses HSSFWorkbook object for creating xls files and XSSFWorkbook object for xlsx files. Please check what object you used for creating xls.
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename="TestFile.xlsx");
File fileVal = new File("TestFile.xlsx");
XSSFWorkbook wb = new XSSFWorkbook();
Sheet s = wb.createSheet("Demo");
//Add data to your sheet
// write the excel to a file
try {
FileOutputStream fileOut = new FileOutputStream(fileVal);
wb.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
// Add password protection and encrypt the file
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
// set the password
enc.confirmPassword("123");
// encrypt the file
OPCPackage opc = OPCPackage.open(fileVal, PackageAccess.READ_WRITE);
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
// save the file back to the filesystem
FileOutputStream fos = new FileOutputStream(fileVal);
fs.writeFilesystem(response.getOutputStream());
fos.close();
I have a requirement to store the uploaded spreadsheet to the disk. I am using the below code to do the same and receiving the file is corrupted error from the excel.
byte[] bytes = null;
File uploadedFile = new File("D://xlsxTest//BNG Issue.xlsx");
File file = new File("D://xlsxTest//sample1.xlsx");
FileOutputStream outStream = null;
InputStream inputStream = null;
try{
if(!file.exists()){
file.createNewFile();
}
outStream = new FileOutputStream(file);
if (uploadedFile != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
inputStream = new FileInputStream(uploadedFile);;
int c = 0;
while (c != -1) {
c = inputStream.read();
byteArrayOutputStream.write((char) c);
}
bytes = byteArrayOutputStream.toByteArray();
}
outStream.write(bytes);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
outStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
I tried using a file of 83KB size and the resultant file is 82.5KB.
Any help would be appreciated.
Thanks.
Try using Apace POI, Convert .xls or .xlsx file to byte array using OPCPackage and XSSFWorkbook with below code.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OPCPackage pkg = OPCPackage.open(new File(fullFileName));
XSSFWorkbook wb = new XSSFWorkbook(pkg);
wb.write(baos);
byte[] fileContent = baos.toByteArray();
Apache POI takes care to extract all information of the excel file while converting to byte array.
I'm trying to decrypt a large file using
https://github.com/martinwithaar/Encryptor4j/blob/master/src/main/java/org/encryptor4j/util/FileEncryptor.java
the following is part of decrypt method that i modified
//the following does not work
FileInputStream fis=new FileInputStream(src);
fis.skip(83);
is = encryptor.wrapInputStream(fis);
os = new FileOutputStream(dest);
//the copy method is a default method from FileEncryptor.java
copy(is, os);
the following works fine.(i have to decrypt entire file and then read/save part of file to another file then delete the old one and rename the new one to the old file name.
is = encryptor.wrapInputStream(new FileInputStream(src));
os = new FileOutputStream(dest);
copy(is, os);
FileInputStream fis=new FileInputStream(dest);
fis.skip(67);
FileOutputStream fos=new FileOutputStream(dest+".2");
copy(fis,fos);
new File(dest).delete();
new File(dest+".2").renameTo(new File(dest));
fis.close();
fos.close();
my question is, why the code on top does not work?
I followed http://www.tutorialspoint.com/java/io/fileinputstream_skip.htm on how to skip some bytes.
Because the encrypted stream has state. The encryption of the 84th byte depends on the prior encryption history. Try this:
FileInputStream fis=new FileInputStream(src);
is = encryptor.wrapInputStream(fis);
is.skip(83);
os = new FileOutputStream(dest);
// ...
in a java-class i just created workbook like this
XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(fis);
and filled cells with its corresponding celltype.
now i need to write it as a xxx.xlsx file same time return a BuyteArrayOutputStream.
to do so,
FileOutputStream fos = new FileOutputStream(tempFile);
workbook.write(fos);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
return outputStream;
here writing xxx.xlsx fils done successfully but same time it returns outputStream as null?
How do achieve it both?
first i write it into the outputstream and get byte[]. after that through IOUtils.write() from Apache Commons IO writing as a file later.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] b = outputStream.toByteArray();
FileOutputStream fos = new FileOutputStream(tempFile);
IOUtils.write(b, fos);
return outputStream;
5i need to convert a HSSFWorkbook (Apache's POI) to an ByteArray and later to convert the ByteArray back to the HSSFWorkbook. The following TestCase illustrates my problem:
#Test
public void testXLSExportImport(){
try {
InputStream is = new FileInputStream(FILEPATH);
HSSFWorkbook wb = new HSSFWorkbook(is);
byte[] exported = wb.getBytes();
HSSFWorkbook wb2 = new HSSFWorkbook(new ByteArrayInputStream(exported));
//in the line above the exception is thrown
} catch (Exception e) {
assertTrue(false);
}
}
the testcase fails with the exception: java.io.IOException: Invalid header signature; read 0x0005060000100809, expected 0xE11AB1A1E011CFD0
(I am using Apaches POI 3.5-beta3)
I hope somebody can help me... how can I get it work?!
You're not writing the workbook correctly! You need to use the write(Outputstream) call.
As shown in the various examples on the website, your code should instead be:
InputStream is = new FileInputStream(FILEPATH);
HSSFWorkbook wb = new HSSFWorkbook(is);
ByteArrayOutputStream out = new ByteArrayOutputStream();
wb.write(out);
HSSFWorkbook wb2 = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
Also, don't open a Workbook from a FileInputStream, if you have a File use that directly. Opening from a File uses less memory than from a Stream.