I am trying to generate Excel reports using Apache POI 3.6 (latest).
Since POI has limited support for header and footer generation (text only), I decided to start from a blank excel file with the header already prepared and fill the Excel cells using POI (cf. question 714172).
Unfortunately, when opening the workbook with POI and writing it immediately to disk (without any cell manpulation), the header seems to be lost.
Here is the code I used to test this behavior:
public final class ExcelWorkbookCreator {
public static void main(String[] args) {
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(new File("dump.xls"));
InputStream inputStream = ExcelWorkbookCreator.class.getResourceAsStream("report_template.xls");
HSSFWorkbook workbook = new HSSFWorkbook(inputStream, true);
workbook.write(outputStream);
} catch (Exception exception) {
throw new RuntimeException(exception);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException exception) {
// Nothing much to do
}
}
}
}
}
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = new HSSFSheet();
Header header = sheet.getHeader() //get header from workbook's sheet
header.setCenter(HSSFHeader.font("COURIER", "Normal")+ HSSFHeader.fontSize((short) 15) + "Hello world" +new Date()); // set header with desire font style
FileOutputStream fileOut = new FileOutputStream("C:\\book.xls");
workbook.write(fileOut);
The headers of the Excel file are preserved as long as those headers are supported in Excel 97-2003. For example, images are supported (I just tried it), but colored text is not.
The tricky part of this is that your Excel template file "dump.xls" must be in Excel 97-2003 format. Please note: this is not the file extension, but the actual contents of the file. The newest Excel will happily save the newest formatting in a .xls file, which POI cannot read.
To test this, save your Excel file as an .xls file. Important - If you receive a compatibility warning, then you must click the "Correct" link in the dialog to correct the Excel. Just clicking Proceed makes the Excel file invalid to POI.
Once you have a real .xls file (with compatible contents) then your code works. I just tested it myself:
public static void main(String[] args) throws Exception {
try (FileInputStream fis = new FileInputStream("./report_template.xls");
FileOutputStream fos = new FileOutputStream("./dump.xls")) {
HSSFWorkbook wb = new HSSFWorkbook(fis);
wb.write(fos);
}
}
Related
I'm writing a program which should put some date into an Excel sheet (.xls). The Excel sheet is a given template which I have to use.
My problem now is that when I change a cell value with the code below the format of the sheet is completely lost. The backround colour, buttons, pictures, ... are gone and also the size of the cells is changed.
I have tried to use createCell() instead of getCell() but this didn't help.
public static void write() throws IOException {
File file = new File(...);
FileInputStream fis = new FileInputStream(file);
HSSFWorkbook workbook = new HSSFWorkbook(fis);
HSSFSheet sheet = workbook.getSheetAt(1);
HSSFCell cell = null;
cell=sheet.getRow(4).getCell(2);
cell.setCellValue(55);
fis.close();
FileOutputStream outFile = new FileOutputStream(file);
workbook.write(outFile);
workbook.close();
outFile.close();
}
I hope someone can give me a hint what I am doing wrong here.
I am trying to write data to excel sheet using Apache POI.I am using TestNG framerwork and eclipse IDE. Program is executing successfully without any error.But when I click refresh on my project source, excel sheet is not coming. Please tell me how will I see my generated excel sheet.
My code is as below:
public class Test {
public static void main(String args[]) {
try {
FileOutputStream fos = new FileOutputStream("User.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet worksheet = workbook.createSheet("worksheet");
HSSFRow row1 = worksheet.createRow((short) 0);
HSSFCell cell1 = row1.createCell((short) 0);
cell1.setCellValue("abc");
HSSFCell cell2 = row1.createCell((short) 1);
cell2.setCellValue("123");
workbook.write(fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please check your project's root directory. It should be there by default. If you have specified the working directory in your run configuration -> arguments, you should check that folder. Besides, you can always get the complete file path in Java.
System.out.println(new File("User.xls").getAbsolutePath());
try this way to create file
FileOutputStream out =
new FileOutputStream(new File("User.xls"));
This file will be stored in your class directory folder.
Ex: (Test.java is stored in (c://Workspace//src//Test.java) , the file also will store in same path c://Workspace//src//User.xls")
While trying to open an excel using ApachePOI I get
org.apache.poi.openxml4j.exceptions.InvalidOperationException: Can't open the specified file: 'C:\Users\mdwaipay\AppData\Local\Temp\poifiles\poi-ooxml-1570030023.tmp'
I checked. No such folder is being created. I am using Apache POI version 3.6.
Any help? A similar code was running fine in a different workspace. At loss of thoughts here.
Code:
public Xls_Reader(String path) {
this.path=path;
try {
fis = new FileInputStream(path);
workbook = new XSSFWorkbook(fis);
sheet = workbook.getSheetAt(0);
fis.close();
}
catch (Exception e)
{ e.printStackTrace();
}
}
Why are you taking a perfectly good file, wrapping it in an InputStream, then asking POI to have to buffer the whole lot for you so it can do random access? Life is much better if you just pass the File to POI directly, so it can skip about as needed!
If you want to work with both XSSF (.xlsx) and HSSF (.xls), change your code to be
public Xls_Reader(String path) {
this.path = path;
try {
File f = new File(path);
workbook = WorkbookFactory.create(f);
sheet = workbook.getSheetAt(0);
} catch (Exception e) {
e.printStackTrace();
}
}
If you only want XSSF support, and/or you need full control of when the resources get closed, instead do something like
OPCPackage pkg = OPCPackage.open(path);
Workbook wb = new XSSFWorkbook(pkg);
// use the workbook
// When you no longer needed it, immediately close and release the file resources
pkg.close();
I constructed a new Workbook using WorkbookFactory.create(new File("path/to/xlsx")). However, when I try to edit the File in Excel after starting the application, I get an error message that the file is in use. Do I have to free the file up, and if so, how? (I could not find anything like Workbook.close() in the api docs) Or do I have to look in other places?
I have no clue where else to look; the application does not cause these issues with csv and for excel files I simply call the converter (xls => csv) which is the only difference.
(I am using POI 3.8)
It seems to work just fine to maintain a handle on the InputStream passed to WorkbookFactory.create(), and to simply close the InputStream when you're done with the Workbook. For example:
InputStream is = // initialize
try {
Workbook wb = WorkbookFactory.create(is);
// use the workbook
} finally {
if (is != null) is.close()
}
If you need full control of when the resources get closed, you should create the OPCPackage yourself up front, and pass that into WorkbookFactory. OPCPackage provides the close method you're after. A Workbook will remain open until garbage collection
Your code would look something like:
File f = new File("/path/to/excel/file");
Workbook wb = null;
NPOIFSFileSystem npoifs = null;
OPCPackage pkg = null;
try {
npoifs = new NPOIFSFileSystem(f);
wb = WorkbookFactory.create(npoifs);
} catch(OfficeXmlFileException ofe) {
pkg = OPCPackage.open(f);
wb = WorkbookFactory.create(pkg);
}
// Use it
if (npoifs != null) { npoifs.close(); }
if (pkg != null) { pkg.close(); }
How to close an instance of a POI workbook in Java:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
try{
File workbookFile = new File("C:\\repo\\yourfile.xslx");
FileInputStream file = new FileInputStream(workbookFile);
Workbook wb = WorkbookFactory.create(file);
Sheet sheet = wb.getSheetAt(0);
//use the instance of wb.
file.close();
}
catch(Exception e){
System.out.println("Fail");
}
First you need to close the stream which is written to the workBook:
workBook.write(outputStream);
outputStream.close();
After that u should close the workBook (for no further operations) and dispose the temporary files:
//Close the workBook
workBook.close();
//deleting the temporary files
workBook.dispose();
I am using poi api version 5.0.0. The Workbook in this version has a close() method which as per the API document says:
"Close the underlying input resource (File or Stream),from which the Workbook was read."
//Using try-catch-finally:
Workbook workbook = null;
try {
workbook = WorkbookFactory.create(inputStream);
//....
} catch (IOException ex) {
//...
}finally {
workbook.close();
}
//Using try-with-resources:
try(Workbook workbook = WorkbookFactory.create(fileStream)) {
//....
} catch (IOException ex) {
//...
}
Just suffer from the same problem, as of 2021. :(, when using poi version 3.9.
I just find that if we upgrade the poi version to 3.17 (in case you are still using Java 7, which poi version 4 or above only Support Java 8 or above),
Then the Workbook will implement AutoCloseable.
Therefore one can use Try-With-Resources block to auto close the File.
Here is the demo code.
try (Workbook workbook = WorkbookFactory.create(new File(fileLocation))) {
// operate on the workbook here...
}
Which I think the above code is better than #Gagravarr solution, as it is copying what the create method do outside, which developer not familiar with poi library does not know what is it.
P.S.
Indeed this question is placed in bugzilla as a bug, see https://bz.apache.org/bugzilla/show_bug.cgi?id=56537, and is resolved and the code is merged in poi 3.11 or later. Therefore anyone having the same issue as we do, can have a look at it, and close the resources when finish using it.
I am using Apache POI for writing into .xlsx file. I can write into .xlsx file but I am unable to append new content. How can I append new content in the .xlsx file?
My Code is:
public static void write(){
try {
Workbook[] wbs = new Workbook[]{new XSSFWorkbook()};
Workbook workbook=wbs[0];
org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet();
System.out.println(sheet.getSheetName());
Row row = sheet.createRow(2);
for(int i=0;i<10;i++){
Cell cell=row.createCell(i);
cell.setCellValue("Sun System");
}
FileOutputStream fout=new FileOutputStream("D:/Test.Xlsx");
workbook.write(fout);
fout.close();
} catch (Exception e) {
}
}
The first thing U've to do :
When you're working with Excel 2007 format, its more wise to use XSSF-Implementations, because you've used abstract implementations. Always remember this when using any implementation.
To append to an existing file you need to reach the end of the rows in that particular workbook sheet. This can be achieved by:
int rows = sheet.getPhysicalNumberOfRows(); // or sheet.getLastRowNum();
After that you can create new cells with the XSSF- Implementation classes. For more information refer to this page
You should open the existing file instead of creating a new one if you want to append, see also this stackoverflow question:
Edit existing excel files using jxl api / Apache POI
You are creating a new workbook each time this is run youd want to create a FileInputStream with a file path to the excel file and then use that input stream to get the XSSF workbook you want to edit
FileInputStream fis = new FileInputStream(filePath);
XSSFWorkbook workBook = new XSSFWorkbook(fis);
then in order to get a specific sheet you simply just use the .getSheet or getSheetAt methods that are apart of workBook. then create and set cells