I'm trying to do my first tests of reading large xlsx file with POI, but to do a simple test with a small file I fail to show the value of a cell.
Someone can tell me what is my mistake. All the suggestions are welcome. Thanks.
Test.java:
import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class Test {
public static void main(String[] args) throws Throwable {
File file = new File("/tmp/test.xlsx");
OPCPackage pkg = OPCPackage.open(new FileInputStream(file.getAbsolutePath()));
XSSFWorkbook xssfwb = new XSSFWorkbook(pkg);
SXSSFWorkbook wb = new SXSSFWorkbook(xssfwb, 100);
Sheet sh = wb.getSheet("Hola");
System.out.println("Name: "+sh.getSheetName()); // Line 19
System.out.println("Val: "+sh.getRow(1).getCell(1).getStringCellValue()); // Line 20
}
}
Result:
Name: Hola
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:20)
test.xlsx:
Please consult: similar question SXSSFWorkBook is write only, it doesn't support reading.
For low memory reading of .xlsx files, you should look at the XSSF and SAX EventModel documentation : Gagravarr
If memory wouldn't be an issue you could use a XSSFSheet instead e.g.
File file = new File("D:/temp/test.xlsx");
FileInputStream fis = new FileInputStream(file);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sh = wb.getSheet("Hola");
System.out.println(sh.getLastRowNum());
System.out.println("Name: "+sh.getSheetName());
Row row = sh.getRow(1);
System.out.println(row.getRowNum());
System.out.println("Val: "+sh.getRow(1).getCell(1).getStringCellValue());
I too faced the same issue of OOM while parsing xlsx file...after two days of struggle, I finally found out the below code that was really perfect;
This code is based on sjxlsx. It reads the xlsx and stores in a HSSF sheet.
// read the xlsx file
SimpleXLSXWorkbook = new SimpleXLSXWorkbook(new File("C:/test.xlsx"));
HSSFWorkbook hsfWorkbook = new HSSFWorkbook();
org.apache.poi.ss.usermodel.Sheet hsfSheet = hsfWorkbook.createSheet();
Sheet sheetToRead = workbook.getSheet(0, false);
SheetRowReader reader = sheetToRead.newReader();
Cell[] row;
int rowPos = 0;
while ((row = reader.readRow()) != null) {
org.apache.poi.ss.usermodel.Row hfsRow = hsfSheet.createRow(rowPos);
int cellPos = 0;
for (Cell cell : row) {
if(cell != null){
org.apache.poi.ss.usermodel.Cell hfsCell = hfsRow.createCell(cellPos);
hfsCell.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING);
hfsCell.setCellValue(cell.getValue());
}
cellPos++;
}
rowPos++;
}
return hsfSheet;
Related
I have a code which writes to the excel file using apache poi api. The problem is it everytime writes the new data to the file and not append the data. can you please help me here. Here is my code.
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExcelWrite {
public static void write(AddExcel addExcel){
try {
XSSFWorkbook workbook = new XSSFWorkbook("NG.xlsx");
XSSFSheet worksheet = workbook.createSheet("Scrap Data");
int lastRow = worksheet.getLastRowNum();
System.out.println(lastRow);
Row row = worksheet.createRow(++lastRow);
row.createCell(2).setCellValue(addExcel.getArtistName());
row.createCell(3).setCellValue(addExcel.getItemName());
row.createCell(6).setCellValue(addExcel.getOriginalPrimaryMarket());
row.createCell(7).setCellValue(addExcel.getAvgResalePrice());
row.createCell(8).setCellValue(addExcel.getPriceChangedFromPrimaryMarket());
row.createCell(9).setCellValue(addExcel.getHighestAvgBid());
row.createCell(10).setCellValue(addExcel.getLastSoldPrice());
row.createCell(11).setCellValue(addExcel.getSecondayMarketVolume());
row.createCell(12).setCellValue(addExcel.getSecondarySales());
row.createCell(13).setCellValue(addExcel.getPrimarySales());
row.createCell(14).setCellValue(addExcel.getDateCreated());
row.createCell(16).setCellValue(addExcel.getInstagramURl());
row.createCell(17).setCellValue(addExcel.getTwitterURL());
FileOutputStream out = new FileOutputStream(new File("NG.xlsx"));
workbook.write(out);
out.close();
System.out.println("Write Successfully.");
}
catch(IOException io){
System.out.println(io.getMessage());
System.out.println(io.getStackTrace());
}
}
}
The problem is that each time you run your code, you always create a brand new XSSFWorkbook and so a brand new excel file, deleting and overriding the existing one.
It doesn't matters you're calling worksheet.getLastRowNum(); it will always return -1 because your XSSFWorkbook will always be empty.
If you want to update an existing excel file (appending new rows to it), you MUST create your XSSFWorkbook by loading that existing excel file. You're code is broken because with the line
workbook = new XSSFWorkbook();
you're creating a brand new XSSFWorkbook which is totally unrelated to the excel file you want to update. You HAVE TO use instead:
Workbook workbook = WorkbookFactory.create(new FileInputStream(toUpdateExcelFilePath));
You might want to have a look at this post for more details: how to update an existing excel file in Java.
According to my test (I used 4.1.2 version from maven repository) when you use createSheet it produce an exception:
java.lang.IllegalArgumentException: The workbook already contains a sheet named 'Scrap Data'
With the getSheet() method you can grab the existing sheet. If it does not exist you will be get a null then you can create a new sheet with the required name.
XSSFWorkbook workbook;
try {
File file = new File("NG.xlsx");
workbook = new XSSFWorkbook();
if(file.exists()) {
FileInputStream fs = new FileInputStream(file);
workbook = new XSSFWorkbook(fs);
}
String sheetName = "Scrap Data";
XSSFSheet worksheet = workbook.getSheet(sheetName);
if(worksheet == null) {
worksheet = workbook.createSheet(sheetName);
}
... //other code unchanged
} catch(Exception io){
io.printStackTrace();
}
NOTE: I changed the file reading code a little bit because I got errors and the documentation says the following:
* Note - if the Document was opened from a {#link File} rather
* than an {#link InputStream}, you <b>must</b> write out to
* a different file, overwriting via an OutputStream isn't possible.
package demo;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class Readwrite {
public static void main(String[] args) throws Exception
{
//Get the excel file and create an input stream for excel
FileInputStream fis = new FileInputStream("D:\\Testing_Team\\Age_Validation.xlsx");
//load the input stream to a workbook object
//Use XSSF for (.xlsx) excel file and HSSF for (.xls) excel file
XSSFWorkbook wb = new XSSFWorkbook(fis);
//get the sheet from the workbook by index
XSSFSheet sheet = wb.getSheet("Age");
//Count the total number of rows present in the sheet
int rowcount = sheet.getLastRowNum();
System.out.println(" Total number of rows present in the sheet : "+rowcount);
//get column count present in the sheet
int colcount = sheet.getRow(1).getLastCellNum();
System.out.println(" Total number of columns present in the sheet : "+colcount);
//get the data from sheet by iterating through cells
//by using for loop
for(int i = 1; i<=rowcount; i++)
{
XSSFCell cell = sheet.getRow(i).getCell(1);
String celltext="";
//Get celltype values
if(cell.getCellType()==Cell.CELL_TYPE_STRING)
{
celltext=cell.getStringCellValue();
}
else if(cell.getCellType()==Cell.CELL_TYPE_NUMERIC)
{
celltext=String.valueOf(cell.getNumericCellValue());
}
else if(cell.getCellType()==Cell.CELL_TYPE_BLANK)
{
celltext="";
}
//Check the age and set the Cell value into excel
if(Double.parseDouble(celltext)>=18)
{
sheet.getRow(i).getCell(2).setCellValue("Major");
}
else
{
sheet.getRow(i).getCell(2).setCellValue("Minor");
}
}//End of for loop
//close the file input stream
fis.close();
//Open an excel to write the data into workbook
FileOutputStream fos = new FileOutputStream("D:\\Testing_Team\\Age_Validation.xlsx");
//Write into workbook
wb.write(fos);
//close fileoutstream
fos.close();
}
}
*I am getting error like [ Exception in thread "main" java.lang.NullPointerException
at demo.Readwrite.main(Readwrite.java:31) ] .
Can Someone please guide me for the same.
I have watched this video for reference https://www.youtube.com/watch?v=orYZB_RUgNc
I have added two poi dependency also poi-ooxml and poi.
Waiting for your valuable response.*
As you comment shows that, you should send index number rather than column name,
I think 'Age' is a column name of you sheet.
//get the sheet from the workbook by index
XSSFSheet sheet = wb.getSheetAt(0);
please replace above line in you code and run it.
Im having difficulty with using Apache POI API. Im trying to import an excel them only select certain rows and cells to extract from the import. Im currently able to import, but i cant extract certain cell. Here is code:
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import java.io.File;
import java.io.IOException;
public class ExcelReader {
public static final String path = "C:/Users/xxxx/Documents/import testing.xlsx";
public static void main(String[] args) throws IOException, InvalidFormatException {
// Create a workbook with data from excel file
Workbook workbook = WorkbookFactory.create(new File(path));
// Save sheets from workbook
Sheet sheet = workbook.getSheetAt(0);
// Make sure the data is saved in string format using a data formatter
DataFormatter dataFormatter = new DataFormatter();
// Iterate through cells and columns, printing their content
System.out.println("\n\nThe content of the excel file: " + path + "\n");
String cellContent;
for (Row row: sheet) {
for(Cell cell: row) {
cellContent = dataFormatter.formatCellValue(cell);
if(cellContent == null || cellContent.trim().isEmpty()){
// Give the empty cells the content "empty", to make it easy to filter out later on
cellContent = "empty";
}
System.out.print(cellContent + "\t");
}
CellReference cellReference = new CellReference("A11");
XSSFRow rowT = sheet.getRow(cellReference.getRow());
if (rowT != null) {
XSSFCell cell = rowT.getCell(cellReference.getCol());
}
System.out.println();
}
// Close the connection to the workbook
workbook.close();
}
}
Changing Workbook to XSSFWorkbook and Sheet to XSSFSheet seems to fix the compilation issue.
XSSFWorkbook workbook = new XSSFWorkbook(new File(path));
and
XSSFSheet sheet = workbook.getSheetAt(0);
try with this for get "A11" cell
XSSFCell cell = sheet.getRow(10).getCell(0); // 10 = id of the 11th row, 0 = id of the 1st (A) column
or
XSSFCell cell = sheet.getRow(10).getCell(CellReference.convertColStringToIndex("A"));
create cell reference for B12
CellReference cr = new CellReference("B12");
row = mySheet.getRow(cr.getRow());
cell = row.getCell(cr.getCol());
Please find the attached code snippet and please help me to proceed with this. I am trying to read data from one excel and then write the same to another excel , while trying to write the file it's stopping the code. When I tried debugging I could see that value is properly fetched but write is not working.
package Export;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TestExport
{
XSSFWorkbook xlsxworkbook;
HSSFWorkbook xlsworkbook;
XSSFWorkbook xlsxworkbook1;
HSSFWorkbook xlsworkbook1;
Sheet sheet;
Sheet sheet1;
TestExport(){
xlsxworkbook=null;
xlsworkbook=null;
sheet=null;
xlsxworkbook1=null;
xlsworkbook1=null;
sheet1=null;
}
public void readExcel(String filePath,String fileName,String sheetName,String filePath1,String fileName1,String sheetName1)
{
try{
FileInputStream fs=new FileInputStream(new File("C:\\Users\\Susmitha-Phases\\Desktop\\TestWorkbook.xlsx"));
FileOutputStream fi=new FileOutputStream(new File("C:\\Users\\Susmitha-Phases\\Desktop\\TestWorkbook1.xlsx"));
fs.toString();
if(fileName.toLowerCase().endsWith("xlsx")){
xlsxworkbook = new XSSFWorkbook(fs);
sheet=xlsxworkbook.getSheet(sheetName);
xlsxworkbook1 = new XSSFWorkbook();
sheet1=xlsxworkbook.getSheet(sheetName1);
}
else{
xlsworkbook=new HSSFWorkbook(fs);
sheet=xlsworkbook.getSheet(sheetName);
xlsworkbook1=new HSSFWorkbook();
sheet1=xlsworkbook.getSheet(sheetName1);
}
int rowCount = sheet.getLastRowNum()-sheet.getFirstRowNum();
//Create a loop over all the rows of excel file to read it
for (int i = 0; i < rowCount+1; i++)
{
Row row = sheet.getRow(i);
Row row1=sheet1.getRow(i);
//Create a loop to print cell values in a row
for (int j = 0; j < row.getLastCellNum(); j++)
{
String temp= row.getCell(j).getStringCellValue();
row1.createCell(i).setCellValue(temp);
//Print Excel data in console
System.out.print(row1.getCell(j).getStringCellValue()+"|| ");
xlsworkbook.write(fi);
//System.out.print(row.getCell(j).getStringCellValue()+"|| ");
}
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws IOException{
//Create an object of ReadGuru99ExcelFile class
TestExport objExcelFile = new TestExport();
//Prepare the path of excel file
String filePath = System.getProperty("C:\\Users\\Susmitha-Phases\\Desktop\\TestWorkbook.xlsx");
String filePath1 = System.getProperty("C:\\Users\\Susmitha-Phases\\Desktop\\TestWorkbook1.xlsx");
//Call read file method of the class to read data
objExcelFile.readExcel(filePath,"TestWorkbook.xlsx","Sheet1",filePath1,"TestWorkbook1.xlsx","Sheet1");
}
}
There are some problem with your code it possible throw null pointer exception
You never created the instance for xlsworkbook in your class when the file type xlsx and trying to write the file . which is wrong will throw definitely null pointer exception. so You must change the logic while writing which file type should be write . Probably you can check file type and write the file.
import java.io.*;
import jxl.*;
import jxl.write.*;
class Exc
{
public static void main(String args[])
{
InputStream input = new FileInputStream("sample.xls");
POIFSFileSystem fs = new POIFSFileSystem(input);
Workbook wb = WorkbookFactory.create(input);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(2);
Cell cell = row.getCell(10);
if (cell == null)
cell = row.createCell(10);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Data");
FileOutputStream fileOut = new FileOutputStream("sample.xls");
wb.write(fileOut);
fileOut.close();
}
}
This is simple code where I am just replacing the data in a cell. When i execute it I get this error:
Exc.java:13: error: cannot find symbol Workbook wb = WorkbookFactory.create(input);
What does the error mean? I have placed the jxl.jar file in the correct path and executed. Thanks in advance.
WorkbookFactory is not a JExcel API class. It belongs to Apache POI.
So, instead of this
InputStream input = new FileInputStream("sample.xls");
POIFSFileSystem fs = new POIFSFileSystem(input);
Workbook wb = WorkbookFactory.create(input);
Use JExcel API's Workbook.getWorkbook() method as
Workbook wb = Workbook.getWorkbook(new File("sample.xls"));