I am using POI to read excel file and convert it to a two-dimensional array. Following is code section:
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XlsxRead_2 {
public XlsxRead_2(){
getvalue_1();
}
public static void getvalue_1(){
XSSFRow row;
XSSFCell cell;
String [][] value =null;
double[][] nums =null;
try {
FileInputStream inputStream = new FileInputStream("TEST.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
//get sheet number
int sheetCn = workbook.getNumberOfSheets();
for(int cn = 0; cn < sheetCn; cn++){
//get 0th sheet data
XSSFSheet sheet = workbook.getSheetAt(cn);
//get number of rows from sheet
int rows = sheet.getPhysicalNumberOfRows();
//get number of cell from row
int cells = sheet.getRow(cn).getPhysicalNumberOfCells();
for (int r = 0; r < rows; r++) {
row = sheet.getRow(r); // bring row
if (row != null) {
for (int c = 0; c < cells; c++) {
cell = row.getCell(c);
value = new String[rows][cells];
nums= new double [rows][cells];
if (cell != null) {
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_FORMULA:
value [r][c]= cell.getCellFormula();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
value [r][c]= "" + cell.getNumericCellValue();
break;
case XSSFCell.CELL_TYPE_STRING:
value [r][c]= "" + cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
value [r][c]= "[BLANK]";
break;
case XSSFCell.CELL_TYPE_ERROR:
value [r][c]= "" + cell.getErrorCellValue();
break;
default:
}
System.out.print(value);
} else {
System.out.print("[null]\t");
}
} // for(c)
System.out.print("\n");
}
} // for(r)
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class Starter {
public static void main(String[] args) {
XlsxRead_2 gv=new XlsxRead_2();
}
}
However, it didn't work properly. Attached is wrong result in JAVA. When i worked it without using array, it work properly. Any suggestions is appreciated.
Result in java:
[[Ljava.lang.String;#167fdd33[[Ljava.lang.String;#1e965684
[[Ljava.lang.String;#4d95d2a2[[Ljava.lang.String;#53f65459
[[Ljava.lang.String;#3b088d51[[Ljava.lang.String;#1786dec2
[[Ljava.lang.String;#74650e52[[Ljava.lang.String;#15d0c81b
[[Ljava.lang.String;#6acdbdf5[[Ljava.lang.String;#4b1c1ea0
[[Ljava.lang.String;#3712b94[[Ljava.lang.String;#2833cc44
[[Ljava.lang.String;#33f88ab[[Ljava.lang.String;#27a8c74e
You should create array after first for loop. And also you should create values array for each sheet. And one more point you should print value[r][c] not value
I hope that helps you.
public class XlsxRead_2 {
public static void main(String[] args) {
XlsxRead_2 xread2 = new XlsxRead_2();
}
public XlsxRead_2() {
getvalue_1();
}
public static void getvalue_1() {
XSSFRow row;
XSSFCell cell;
String[][] value = null;
double[][] nums = null;
try {
FileInputStream inputStream = new FileInputStream("TEST.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
// get sheet number
int sheetCn = workbook.getNumberOfSheets();
for (int cn = 0; cn < sheetCn; cn++) {
// get 0th sheet data
XSSFSheet sheet = workbook.getSheetAt(cn);
// get number of rows from sheet
int rows = sheet.getPhysicalNumberOfRows();
// get number of cell from row
int cells = sheet.getRow(cn).getPhysicalNumberOfCells();
value = new String[rows][cells];
for (int r = 0; r < rows; r++) {
row = sheet.getRow(r); // bring row
if (row != null) {
for (int c = 0; c < cells; c++) {
cell = row.getCell(c);
nums = new double[rows][cells];
if (cell != null) {
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_FORMULA:
value[r][c] = cell.getCellFormula();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
value[r][c] = ""
+ cell.getNumericCellValue();
break;
case XSSFCell.CELL_TYPE_STRING:
value[r][c] = ""
+ cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
value[r][c] = "[BLANK]";
break;
case XSSFCell.CELL_TYPE_ERROR:
value[r][c] = ""+cell.getErrorCellValue();
break;
default:
}
System.out.print(value[r][c]);
} else {
System.out.print("[null]\t");
}
} // for(c)
System.out.print("\n");
}
} // for(r)
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Related
I'm here to ask for help in my java project in Netbeans.
I'm using Apache POI to import/export excel data. To make you understand what is the problem in my application, I'm showing you a print of the debug.
In the print, you can see 2 sheets. The first header "aiai" and the data from that sheet.
My problem is: How do i insert the data from "aiai2" which is the second sheet from my excel file, in its proper place, below the header "aiai2"
On other words, I want to separate the sheets vertically.
Below, I will show my code:
Workbook wb;
public String Importar(File archivo, JTable tablaD) {
String answer = "Unable to import";
DefaultTableModel modeloT = new DefaultTableModel();
tablaD.setModel(modeloT);
tablaD.getModel();
tablaD.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
try {
wb = WorkbookFactory.create(new FileInputStream(archivo));
int nsheets = wb.getNumberOfSheets();
for (int i = 0; i < nsheets; i++) {
Sheet sheet = wb.getSheetAt(i);
Iterator filaIterator = sheet.rowIterator();
int rownum = -1;
while (filaIterator.hasNext()) {
rownum++;
Row fila = (Row) filaIterator.next();
/*if (i > 0) {//se o nr da ficha atual for maior que 0, começa a escrever as linhas apartir da row 0 da tabela
modeloT.moveRow(modeloT.getRowCount() -1, modeloT.getRowCount() - 1, 0);
}*/
Iterator columnaIterator = fila.cellIterator();
Object[] listaColumna = new Object[1000];
int columnnum = -1;
while (columnaIterator.hasNext()) {
columnnum++;
Cell celda = (Cell) columnaIterator.next();
if (rownum == 0) {
modeloT.addColumn(celda.getStringCellValue());
} else {
if (celda != null) {
switch (celda.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
listaColumna[columnnum] = (int) Math.round(celda.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
listaColumna[columnnum] = celda.getStringCellValue();
break;
case Cell.CELL_TYPE_BOOLEAN:
listaColumna[columnnum] = celda.getBooleanCellValue();
break;
default:
listaColumna[columnnum] = celda.getDateCellValue();
break;
}//end switch case
System.out.println("Column:" + columnnum + " Row:" + rownum + " value:" + celda + ".");
}
}
}//end while column Iterator
if (rownum != 0) {
modeloT.addRow(listaColumna);
}
}//end while row iterator
}//end for
answer = "Imported with success";
} catch (IOException | InvalidFormatException | EncryptedDocumentException e) {
System.err.println(e.getMessage());
}
return answer;
}
public String Exportar(File archivo, JTable tablaD) {
String answer = "Unable to export";
int numFila = tablaD.getRowCount(), numColumna = tablaD.getColumnCount();
if (archivo.getName().endsWith("xls")) {
wb = new HSSFWorkbook();
} else {
wb = new XSSFWorkbook();
}
Sheet hoja = wb.createSheet("Default");
try {
for (int i = -1; i < numFila; i++) {
Row fila = hoja.createRow(i + 1);
for (int j = 0; j < numColumna; j++) {
Cell celda = fila.createCell(j);
if (i == -1) {
celda.setCellValue(String.valueOf(tablaD.getColumnName(j)));
} else {
celda.setCellValue(String.valueOf(tablaD.getValueAt(i, j)));
}
wb.write(new FileOutputStream(archivo));
}
}
answer = "Exported with success";
} catch (Exception e) {
System.err.println(e.getMessage());
}
return answer;
}
As I understand your question, I assume you want to create a separate table for each sheet, one below other. In that case you need to create a new table everytime you read a new sheet. If you use only one table, you will get only one header.
Try this :
Create a new method Importar that takes a new table and a Sheet parameter
public String Importar(JTable tablaD, Sheet sheet) {
String answer = "Unable to import";
DefaultTableModel modeloT = new DefaultTableModel();
tablaD.setModel(modeloT);
tablaD.getModel();
tablaD.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
try {
Iterator filaIterator = sheet.rowIterator();
int rownum = -1;
....
....
So the calling method would be :
try {
Workbook wb = WorkbookFactory.create(new FileInputStream(archivo));
int nsheets = wb.getNumberOfSheets();
for (int i = 0; i < nsheets; i++) {
//You have to make sure your JTable gets rendered.
JTable tablaD = new JTable();
Importar( tablaD, wb.getSheetAt(i) );
}
} catch ( Exception e ) {
e.printStackTrace();
}
Important point is that your new table needs to get rendered or added to frame each time before you call Importar
I am new to apache poi, I wanted to split a excel file into multiple files based on row count.
E.g data.xlsx has 15k rows, new files should be like data_1.xlsx with 5k rows,data_2.xlsx should be 5-10k and data_3.xlsx should be 10-15k.
I've got you.
package com.industries.seanimus;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReportSplitter {
private final String fileName;
private final int maxRows;
public ReportSplitter(String fileName, final int maxRows) {
ZipSecureFile.setMinInflateRatio(0);
this.fileName = fileName;
this.maxRows = maxRows;
try {
/* Read in the original Excel file. */
OPCPackage pkg = OPCPackage.open(new File(fileName));
XSSFWorkbook workbook = new XSSFWorkbook(pkg);
XSSFSheet sheet = workbook.getSheetAt(0);
/* Only split if there are more rows than the desired amount. */
if (sheet.getPhysicalNumberOfRows() >= maxRows) {
List<SXSSFWorkbook> wbs = splitWorkbook(workbook);
writeWorkBooks(wbs);
}
pkg.close();
}
catch (EncryptedDocumentException | IOException | InvalidFormatException e) {
e.printStackTrace();
}
}
private List<SXSSFWorkbook> splitWorkbook(XSSFWorkbook workbook) {
List<SXSSFWorkbook> workbooks = new ArrayList<SXSSFWorkbook>();
SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sh = wb.createSheet();
SXSSFRow newRow;
SXSSFCell newCell;
int rowCount = 0;
int colCount = 0;
XSSFSheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
newRow = sh.createRow(rowCount++);
/* Time to create a new workbook? */
if (rowCount == maxRows) {
workbooks.add(wb);
wb = new SXSSFWorkbook();
sh = wb.createSheet();
rowCount = 0;
}
for (Cell cell : row) {
newCell = newRow.createCell(colCount++);
newCell = setValue(newCell, cell);
CellStyle newStyle = wb.createCellStyle();
newStyle.cloneStyleFrom(cell.getCellStyle());
newCell.setCellStyle(newStyle);
}
colCount = 0;
}
/* Only add the last workbook if it has content */
if (wb.getSheetAt(0).getPhysicalNumberOfRows() > 0) {
workbooks.add(wb);
}
return workbooks;
}
/*
* Grabbing cell contents can be tricky. We first need to determine what
* type of cell it is.
*/
private SXSSFCell setValue(SXSSFCell newCell, Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
newCell.setCellValue(cell.getDateCellValue());
} else {
newCell.setCellValue(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(cell.getCellFormula());
break;
default:
System.out.println("Could not determine cell type");
}
return newCell;
}
/* Write all the workbooks to disk. */
private void writeWorkBooks(List<SXSSFWorkbook> wbs) {
FileOutputStream out;
try {
for (int i = 0; i < wbs.size(); i++) {
String newFileName = fileName.substring(0, fileName.length() - 5);
out = new FileOutputStream(new File(newFileName + "_" + (i + 1) + ".xlsx"));
wbs.get(i).write(out);
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
/* This will create a new workbook every 1000 rows. */
new ReportSplitter("Data.xlsx", 1000);
}
}
A few notes:
For writing the workbooks, I use
SXSSFWorkbook. It's a lot
faster than HSSF or XSSF, as it doesn't hold everything in memory
before writing (which causes a horrible gc mess).
The Busy Developer's Guide is your friend for learning Apache POI ;)
ENJOY!
EDIT: I've updated the code to copy cell styles as well. Two things to note about this:
Copying styles will SLOW things down considerably.
POI creates a template file that may become too big to be uncompressed, throwing a Zip bomb detected error. You can fix this by changing the minimum inflation ratio via ZipSecureFile.setMinInflateRatio(0).
Thanks for your code. Just two cent from my side
The code above does not copy the time Hence I modified it for having Time Columns which is a small modification in setValue Code.
Basically I'm checking using format part if it is a time column for which the year would be 1899
Hope it helps :)
private static SXSSFCell setValue(SXSSFCell newCell, Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
//System.out.println("The Cell Type is numeric ");
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue());
Date c = cell.getDateCellValue();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
String strTime = simpleDateFormat.format(c);
String strYear=year.format(c);
if(strYear.equals("1899"))
{
System.out.println(strTime);
newCell.setCellValue(DateUtil.convertTime(strTime));
}
else
{
newCell.setCellValue(c);
}
} else {
newCell.setCellValue(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(cell.getCellFormula());
break;
default:
System.out.println("Could not determine cell type");
}
return newCell;
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class SplitFile {
private final String fileName;
private final int maxRows;
private final String path;
private final String userfilename="";
public static int filecount;
public static String taskname;
public static int rowcounter;
public SplitFile(String fileName, final int maxRows, String filepath, String userfilename) throws FileNotFoundException {
path = filepath;
taskname = userfilename;
this.fileName = fileName;
this.maxRows = maxRows;
System.out.println("In Constructor");
File file = new File(fileName);
FileInputStream inputStream = new FileInputStream(file);
try {
/* Read in the original Excel file. */
//OPCPackage pkg = OPCPackage.open(new File(fileName));
Workbook workbook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
System.out.println("Got Sheet");
/* Only split if there are more rows than the desired amount. */
if (sheet.getPhysicalNumberOfRows() >= maxRows) {
List<SXSSFWorkbook> wbs = splitWorkbook(workbook);
writeWorkBooks(wbs);
}
}
catch (EncryptedDocumentException | IOException e) {
e.printStackTrace();
}
}
private List<SXSSFWorkbook> splitWorkbook(Workbook workbook) {
List<SXSSFWorkbook> workbooks = new ArrayList<SXSSFWorkbook>();
SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sh = (SXSSFSheet) wb.createSheet();
SXSSFRow newRow,headRow = null;
SXSSFCell newCell;
String headCellarr[] = new String[50];
int rowCount = 0;
int colCount = 0;
int headflag = 0;
int rcountflag = 0;
int cols = 0;
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
//sheet.createFreezePane(0, 1);
int i = 0;
rowcounter++;
for (Row row : sheet) {
if(i==0)
{
//headRow = sh.createRow(rowCount++);
/* Time to create a new workbook? */
int j = 0;
for (Cell cell : row) {
//newCell = headRow.createCell(colCount++);
headCellarr[j] = cell.toString();
j++;
}
cols = j;
colCount = 0;
i++;
}
else
{
break;
}
}
for (Row row : sheet) {
//newRow = sh.createRow(rowCount++);
/* Time to create a new workbook? */
if (rowCount == maxRows) {
headflag = 1;
workbooks.add(wb);
wb = new SXSSFWorkbook();
sh = (SXSSFSheet) wb.createSheet();
rowCount = 0;
}
if(headflag == 1)
{
newRow = (SXSSFRow) sh.createRow(rowCount++);
headflag = 0;
for(int k=0;k<cols;k++)
{
newCell = (SXSSFCell) newRow.createCell(colCount++);
newCell.setCellValue(headCellarr[k]);
}
colCount = 0;
newRow = (SXSSFRow) sh.createRow(rowCount++);
for (Cell cell : row) {
newCell = (SXSSFCell) newRow.createCell(colCount++);
if(cell.getCellType() == Cell.CELL_TYPE_BLANK)
{
newCell.setCellValue("-");
}
else
{
newCell = setValue(newCell, cell);
}
}
colCount = 0;
}
else
{
rowcounter++;
newRow = (SXSSFRow) sh.createRow(rowCount++);
for(int cn=0; cn<row.getLastCellNum(); cn++) {
// If the cell is missing from the file, generate a blank one
// (Works by specifying a MissingCellPolicy)
Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
// Print the cell for debugging
//System.out.println("CELL: " + cn + " --> " + cell.toString());
newCell = (SXSSFCell) newRow.createCell(cn);
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC)
{
newCell.setCellValue(cell.getNumericCellValue());
}
else
{
newCell.setCellValue(cell.toString());
}
}
}
}
/* Only add the last workbook if it has content */
if (wb.getSheetAt(0).getPhysicalNumberOfRows() > 0) {
workbooks.add(wb);
}
return workbooks;
}
/*
* Grabbing cell contents can be tricky. We first need to determine what
* type of cell it is.
*/
private SXSSFCell setValue(SXSSFCell newCell, Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
newCell.setCellValue(cell.getDateCellValue());
} else {
//newCell.setCellValue(cell.getNumericCellValue());
newCell.setCellValue(cell.toString());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK:
newCell.setCellValue("-");
break;
default:
System.out.println("Could not determine cell type");
newCell.setCellValue(cell.toString());
}
return newCell;
}
/* Write all the workbooks to disk. */
private void writeWorkBooks(List<SXSSFWorkbook> wbs) {
FileOutputStream out;
boolean mdir = new File(path + "/split").mkdir();
try {
for (int i = 0; i < wbs.size(); i++) {
String newFileName = fileName.substring(0, fileName.length() - 5);
//out = new FileOutputStream(new File(newFileName + "_" + (i + 1) + ".xlsx"));
out = new FileOutputStream(new File(path + "/split/" + taskname + "_" + (i + 1) + ".xlsx"));
wbs.get(i).write(out);
out.close();
System.out.println("Written" + i);
filecount++;
}
System.out.println(userfilename);
} catch (IOException e) {
e.printStackTrace();
}
}
public int sendtotalrows()
{
return rowcounter;
}
public static void main(String[] args) throws FileNotFoundException{
// This will create a new workbook every 1000 rows.
// new Splitter(filename.xlsx, No of split rows, filepath, newfilename);
new SplitFile("filepath/filename.xlsx", 10000, "filepath", "newfilename"); //No of rows to split: 10 K
}
}
I'm currently trying to merge two Excel files with each other. But there is a catch, I need to add between files the name of the file each file and an empty row. When I tried that, it added the name of the file and empty row but overwrote the first two rows of each file. How can I do it without losing first two rows of the file ?
public static void main(String[] args) {
try {
File firstFile = new File("/Users/TLQ/Desktop/report-12689-M2398-1.xlsx");
File secondFile = new File("/Users/TLQ/Desktop/report-12695-M2390-1.xlsx");
FileInputStream excellFile1 = new FileInputStream(firstFile);
FileInputStream excellFile2 = new FileInputStream(secondFile);
org.apache.poi.ss.usermodel.Workbook workbook1 = WorkbookFactory.create(excellFile1);
org.apache.poi.ss.usermodel.Workbook workbook2 = WorkbookFactory.create(excellFile2);
org.apache.poi.ss.usermodel.Sheet sheet1a = workbook1.getSheetAt(0);
org.apache.poi.ss.usermodel.Sheet sheet2a = workbook2.getSheetAt(0);
addSheet(sheet1a, sheet2a,secondFile.getAbsolutePath().substring(secondFile.getAbsolutePath().lastIndexOf("/")+1, secondFile.getAbsolutePath().indexOf(".")));
excellFile1.close();
// save merged file
File mergedFile = new File(
"/Users/TLQ/Desktop/Albert_1.xlsx");
if (!mergedFile.exists()) {
mergedFile.createNewFile();
}
FileOutputStream out = new FileOutputStream(mergedFile);
workbook1.write(out);
out.close();
System.out.println(firstFile.getAbsolutePath().substring(firstFile.getAbsolutePath().lastIndexOf("/")+1, firstFile.getAbsolutePath().indexOf(".")));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void addSheet(org.apache.poi.ss.usermodel.Sheet mergedSheet, org.apache.poi.ss.usermodel.Sheet sheet,String name) {
// map for cell styles
Map<Integer, org.apache.poi.ss.usermodel.CellStyle> styleMap = new HashMap<Integer, org.apache.poi.ss.usermodel.CellStyle>();
org.apache.poi.ss.usermodel.Row row2 = mergedSheet.createRow((short) 0);
org.apache.poi.ss.usermodel.Cell mcell2 = row2.createCell((short) 0);
mcell2.setCellValue("report-12689-M2398-1.xlsx");
// This parameter is for appending sheet rows to mergedSheet in the end
org.apache.poi.ss.usermodel.Row row1 = sheet.createRow((short) 0);
org.apache.poi.ss.usermodel.Cell mcell = row1.createCell((short) 0);
mcell.setCellValue(name);
org.apache.poi.ss.usermodel.Row row1Empty = sheet.createRow((short) 0);
org.apache.poi.ss.usermodel.Cell mcellEmpty = row1.createCell((short) 0);
int len = mergedSheet.getLastRowNum();
for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
org.apache.poi.ss.usermodel.Row row = sheet.getRow(j);
org.apache.poi.ss.usermodel.Row mrow = mergedSheet.createRow(len + j + 1);
try {
for (int k = row.getFirstCellNum(); k < row.getLastCellNum(); k++) {
org.apache.poi.ss.usermodel.Cell cell=null;
if(row.getCell(k)!=null){
cell = row.getCell(k);
}else{
cell= row.createCell(k);
}
mcell = mrow.createCell(k);
if (cell.getSheet().getWorkbook() == mcell.getSheet()
.getWorkbook()) {
mcell.setCellStyle(cell.getCellStyle());
} else {
int stHashCode = cell.getCellStyle().hashCode();
org.apache.poi.ss.usermodel.CellStyle newCellStyle = styleMap.get(stHashCode);
if (newCellStyle == null) {
newCellStyle = mcell.getSheet().getWorkbook()
.createCellStyle();
newCellStyle.cloneStyleFrom(cell.getCellStyle());
styleMap.put(stHashCode, newCellStyle);
}
mcell.setCellStyle(newCellStyle);
}
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
mcell.setCellFormula(cell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
mcell.setCellValue(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
mcell.setCellValue(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
mcell.setCellType(HSSFCell.CELL_TYPE_BLANK);
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
mcell.setCellValue(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
mcell.setCellErrorValue(cell.getErrorCellValue());
break;
default:
mcell.setCellValue(cell.getStringCellValue());
break;
}
}
} catch (Exception e) {
}
}
}
no sure which one the good but try
workbook1.write(out,true);
or workbook1.write(out,false);
it should set the fact to delete what was before or not.(true should be not erase what you got)
hope it help ;)
I'm trying to read the empty cells of an xls file and port them to my object xls as null entries. But I'm not identifying these cells as blank. Can someone can tell me what I'm doing wrong?
private boolean lerArquivo(String dir) throws IOException {
HSSFWorkbook wb = null;
HSSFRow row = null;
HSSFCell cell = null;
String path = dir;
boolean flag = false;
InputStream inp = new FileInputStream(path);
wb = new HSSFWorkbook(inp);
HSSFSheet sheet = wb.getSheetAt(0);
for (Iterator rit = (Iterator) sheet.rowIterator(); rit.hasNext();) {
row = (HSSFRow) rit.next();
for (Iterator cit = (Iterator) row.cellIterator(); cit.hasNext();) {
cell = (HSSFCell) cit.next();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
xls.add(cell.getRichStringCellValue().getString());
break;
case HSSFCell.CELL_TYPE_BLANK:
xls.add(null);
break;
case HSSFCell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
xls.add(cell.getDateCellValue().toString());
} else {
xls.add(String.valueOf(cell.getNumericCellValue()));
}
break;
default:
}
}
}
EDIT 01 -
Hello Gagravarr, thanks for your help.
I Tried your suggest, and read the documentation.
following what i understood, i changed my code, reaching this:
even this way, the code isn't reading the blank cell. any guess ?
for (int rowNum = 0; rowNum < 4; rowNum++) {
row = sheet.getRow(rowNum);
for (int celNum = 0; celNum < row.getLastCellNum(); celNum++) {
cell = row.getCell(celNum, org.apache.poi.ss.usermodel.Row.RETURN_BLANK_AS_NULL);
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
xls.add(cell.getRichStringCellValue().getString());
break;
case HSSFCell.CELL_TYPE_BLANK: {
xls.add("");
break;
}
case HSSFCell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
xls.add(cell.getDateCellValue().toString());
} else {
xls.add(String.valueOf(cell.getNumericCellValue()));
}
break;
default:
}
}
}
Apache POI has pretty detailed and explicit documentation on iterating over rows and cells, you'd be very well advised to read it!
Copying and pasting the example from there, you can see how to handle / detect missing rows and cells, along with blank cells:
// Decide which rows to process
int rowStart = Math.min(15, sheet.getFirstRowNum());
int rowEnd = Math.max(1400, sheet.getLastRowNum());
for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
Row r = sheet.getRow(rowNum);
int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);
for (int cn = 0; cn < lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
// The spreadsheet is empty in this cell
} else {
// Do something useful with the cell's contents
}
}
}
i am using APACHE POI to read the data from excel files. I would like to store them in lists (like list in c) the result because afterwards I will try to store them in mysql database calling only list[0], list[1] for example. What i will try to do is make this list and after i will use jdbc driver and giving this list to make the tables in mysql.
The code for reading excel file is the above:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
public class readexcel{
#SuppressWarnings({ "unchecked", "unchecked" })
public static void main(String[] args) throws Exception {
//
// An excel file name. You can create a file name with a full
// path information.
//
String filename = "C:\\Users\\xxx\\Documents\\test.xls";
//
// Create an ArrayList to store the data read from excel sheet.
//
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
//
// Create a FileInputStream that will be use to read the
// excel file.
//
fis = new FileInputStream(filename);
//
// Create an excel workbook from the file system.
//
HSSFWorkbook workbook = new HSSFWorkbook(fis);
//
// Get the first sheet on the workbook.
//
HSSFSheet sheet = workbook.getSheetAt(0);
//
// When we have a sheet object in hand we can iterator on
// each sheet's rows and on each row's cells. We store the
// data read on an ArrayList so that we can printed the
// content of the excel to the console.
//
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
showExcelData(sheetData);
}
private static void showExcelData(List sheetData) {
//
// Iterates the data and print it out to the console.
//
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
Cell cell = (Cell) list.get(j);
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
}
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
}
What i have to add to do what i explain you?
initialize the array list way before starting to iterate the sheet,
the array list must have a scope to persist anywhere in the row and column iteration of the excel sheet .
ArrayList myList = new ArrayList()
the put these line inside the cell iteration loop which is being performed n row basis
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC)
{
System.out.print(cell.getNumericCellValue());
myList.add(cell.getNumericCellValue());
}
else if (cell.getCellType() == Cell.CELL_TYPE_STRING)
{
System.out.print(cell.getRichStringCellValue());
myList.add(cell.getRichStringCellValue());
}
else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN)
{
System.out.print(cell.getBooleanCellValue());
myList.add(cell.getBooleanCellValue());
}
now you process this list to insert data in to your DataBase
I found this function usable
public static ArrayList<ArrayList<String>> GetExcelTableInto2DArrayListString(String excelFile, boolean debug){
ArrayList<ArrayList<String>> OUT = new ArrayList<ArrayList<String>>();
File myFile = new File(excelFile);
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Finds the workbook instance for XLSX file
XSSFWorkbook myWorkBook = null;
try {
myWorkBook = new XSSFWorkbook (fis);
} catch (IOException e) {
e.printStackTrace();
}
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
Iterator<Row> rowIterator = mySheet.iterator();
// Traversing over each row of XLSX file
int count=1;
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
ArrayList<String> InnerArray = new ArrayList<String>() ;
if(debug)System.out.print(count + ". \t");
// For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
String c = cell.getStringCellValue();
if(debug)System.out.print(c + "\t");
InnerArray.add(c);
break;
case Cell.CELL_TYPE_NUMERIC:
int n = (int) cell.getNumericCellValue();
if(debug)System.out.print(n + "\t");
InnerArray.add(String.valueOf(n));
break;
case Cell.CELL_TYPE_BOOLEAN:
boolean b = cell.getBooleanCellValue();
if(debug)System.out.print(b + "\t");
InnerArray.add(String.valueOf(b));
break;
default :
}
}
if(debug)System.out.println("");
OUT.add(InnerArray);
count++;
}
return OUT;
}
Look the code below
public List<ArrayList<String>> readExcelData2(String excelFile) throws IOException {
List<ArrayList<String>> depts = new ArrayList<ArrayList<String>>();
FileInputStream excelFileToRead = new FileInputStream(new File(excelFile));
XSSFWorkbook wb = new XSSFWorkbook(excelFileToRead);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
int maxDataCount = 0;
Iterator<Row> rows = sheet.rowIterator();
while (rows.hasNext()) {
row = (XSSFRow) rows.next();
// skip the first row because it will be header
if (row.getRowNum() == 0) {
maxDataCount = row.getLastCellNum();
continue;
}
// if the row is empty stop the loop, do not go further
if (this.isRowEmpty(row, maxDataCount)) {
// exit processing
break;
}
// define arraylist object to store list of departments of each row
ArrayList<String> innerArrayList = new ArrayList<String>();
for (int cn = 0; cn < maxDataCount; cn++) {
cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
innerArrayList.add(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
innerArrayList.add(String.valueOf(cell.getNumericCellValue()));
break;
default:
innerArrayList.add(cell.getStringCellValue());
break;
}
}
depts.add(innerArrayList);
}
return depts;
}
public boolean isRowEmpty(Row row, int lastCellNo) {
for (int c = row.getFirstCellNum(); c < lastCellNo; c++) {
Cell cell = row.getCell(c, Row.CREATE_NULL_AS_BLANK);
if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
return false;
}
}
return true;
}
change your conditions part to this should be work :
if (cell.getCellType() == NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
}