Unable to understand how to merge Rows in POI - java

I'm writing a program where I need to merge rows in Excel sheet. Currently, I'm able to merge the starting rows, but when coming to the end, I'm unable to know where it is going wrong. Below is my code.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class RowsMerge {
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Sample Sheets\\dummy.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int row = sheet.getPhysicalNumberOfRows();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int startIndex = 1, finalIndex = 0, tempNum = 0;
System.out.println(row);
for (int i = 2; i < (row - 1); i++) {
currentAssociate = sheet.getRow(i).getCell(0).toString();
currentLawName = sheet.getRow(i).getCell(1).toString();
currentCountry = sheet.getRow(i).getCell(2).toString();
currentPages = sheet.getRow(i).getCell(3).toString();
previousAssociate = sheet.getRow(i - 1).getCell(0).toString();
previousLawName = sheet.getRow(i - 1).getCell(1).toString();
previousCountry = sheet.getRow(i - 1).getCell(2).toString();
previousPages = sheet.getRow(i - 1).getCell(3).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
finalIndex += 1;
} else {
sendRangeToMergeCells(startIndex, finalIndex, sheet);
startIndex = i;
finalIndex = 0;
}
}
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Sample Sheets\\dummy.xls");
workbook.write(fileOut);
fileOut.close();
}
private static void sendRangeToMergeCells(int startIndex, int finalIndex, HSSFSheet sheet) {
System.out.println(startIndex + "\t" + (startIndex + finalIndex));
CellRangeAddress region = CellRangeAddress
.valueOf("D" + (startIndex + 1) + ":D" + ((startIndex + finalIndex) + 1));
sheet.addMergedRegion(region);
}
}
Below is my Excel Sheet
SourceExcel:
Current output:
Expected output:

Actually your merge logic is fine, it is your break logic (the logic which determines when to merge the rows) that is missing a bit.
If the last row in your spreadsheet matches the previous row, no merge will be performed because execution will follow the first branch of if (currentAssociate.equals(previousAssociate) && ... and the loop ends. You have to test for and execute the merge logic if necessary one last time after the for loop completes.
Add the following after your for loop:
if (finalIndex > 0) {
sendRangeToMergeCells(startIndex, finalIndex, sheet);
}
this will merge the last rows if necessary.

Related

iText set cell height to height set in Excel row

I am using iText 7.1.15 in combination with Apache POI 4.1.1 to create a PDF from an Excel sheet.
The rows in the sheet are set to a specific height in centimeters to fit correctly on an A4 page when printed.
However when I set the cell height via iText and have a look at the result the row in the PDF table isn't exactly as high as in Excel.
I am using org.apache.poi.ss.usermodel.Row.getHeightInPoints() and set this value to my PDF table cell using com.itextpdf.layout.element.Cell.setHeight().
Inspecting the result however the row height in my PDF is slightly different than expected.
And some content (the last row in my sample) event gets truncated (I guess because the cell isn't high enough)...
What am I doing wrong here?
You can find the complete sample here at Github
PDF:
Excel:
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
float heightInPoints = row.getHeightInPoints();
System.out.println("Row: " + (rowNum + 1) + ": " + heightInPoints + "pt = " + heightInPoints * PT_TO_CM + "cm");
for (int cellNum = 0; cellNum < numCols; cellNum++) {
Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
pdfCell.add(new Paragraph(cell.getStringCellValue()));
pdfCell.setHeight(heightInPoints);
pdfCell.setBorder(new SolidBorder(0.5f));
table.addCell(pdfCell);
}
}
package com.gi.itext;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.AreaBreakType;
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;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class App {
private static final String OUTPUT = "./target/output.pdf";
private static final String INPUT = "/input.xlsx";
private static final float PT_TO_CM = 0.0352778f;
public static void main(String[] args) {
new App().run();
}
public void run() {
File file = new File(OUTPUT);
file.getParentFile().mkdirs();
try (InputStream is = getClass().getResourceAsStream(INPUT);
Workbook workbook = new XSSFWorkbook(is)) {
PdfDocument pdfDoc;
try {
pdfDoc = new PdfDocument(new PdfWriter(OUTPUT));
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
pdfDoc.addNewPage();
Document doc = new Document(pdfDoc, PageSize.A4);
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
Sheet sheet = workbook.getSheetAt(sheetNum);
if (sheetNum > 0) {
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
int numCols = getNumberOfColumns(sheet);
float[] columnWidth = new float[numCols];
for (int j = 0; j < numCols; j++) {
float columnWidthInPixels = sheet.getColumnWidthInPixels(j);
double columnWidthInPoints = columnWidthInPixels * 0.75d;
columnWidth[j] = (float) columnWidthInPoints;
}
Table table = new Table(columnWidth);
table.useAllAvailableWidth();
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
float heightInPoints = row.getHeightInPoints();
System.out.println("Row: " + (rowNum + 1) + ": " + heightInPoints + "pt = " + heightInPoints * PT_TO_CM + "cm");
for (int cellNum = 0; cellNum < numCols; cellNum++) {
Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
pdfCell.add(new Paragraph(cell.getStringCellValue()));
pdfCell.setHeight(heightInPoints);
pdfCell.setBorder(new SolidBorder(0.5f));
table.addCell(pdfCell);
}
}
doc.add(table);
}
doc.close();
pdfDoc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private int getNumberOfColumns(Sheet sheet) {
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
for (int rowNum = firstRowNum; rowNum < lastRowNum; rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
if (row.getLastCellNum() > -1) {
return row.getLastCellNum();
}
}
return -1;
}
}

Confusion with merge using POI

I'm writing a program in POI to merge cells and I'm able to merge them. there is a column with number content, and when I merge this column and when I open my sheet and select this column to my surprise this shows the count and sum as if it is not merged.
Below is my Excel.
Here the count should be 5 and sum should be 530 but this shows this as 25 and 2650
Below is my code.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class RowsMerge {
// public static void main(String[] args)
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Quality Sheet\\Quality_template.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int row = sheet.getPhysicalNumberOfRows();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int startIndex = 1, finalIndex = 0;
System.out.println(row);
for (int i = 2; i < row; i++) {
currentAssociate = sheet.getRow(i).getCell(1).toString();
currentLawName = sheet.getRow(i).getCell(3).toString();
currentCountry = sheet.getRow(i).getCell(4).toString();
currentPages = sheet.getRow(i).getCell(5).toString();
previousAssociate = sheet.getRow(i - 1).getCell(1).toString();
previousLawName = sheet.getRow(i - 1).getCell(3).toString();
previousCountry = sheet.getRow(i - 1).getCell(4).toString();
previousPages = sheet.getRow(i - 1).getCell(5).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
finalIndex += 1;
if (((i + 1) == row)) {
System.out.println("yes");
finalIndex += 1;
sendRangeToMergeCells(startIndex + 1, finalIndex - 1, sheet, workbook);
}
} else {
sendRangeToMergeCells(startIndex + 1, finalIndex, sheet, workbook);
startIndex = i;
finalIndex = 0;
}
}
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Quality Sheet\\new.xls");
workbook.write(fileOut);
fileOut.close();
}
private static void sendRangeToMergeCells(int startIndex, int finalIndex, HSSFSheet sheet, HSSFWorkbook workbook) {
System.out.println(startIndex + "\t" + (startIndex + finalIndex));
CellRangeAddress region = CellRangeAddress.valueOf("F" + (startIndex) + ":F" + ((startIndex + finalIndex)));
sheet.addMergedRegion(region);
}
}
How can I fix this?
This may be the result of a bug, but a workaround may be to shift the rows up instead of merging them.
public class RowsMerge {
// public static void main(String[] args)
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Quality Sheet\\Quality_template.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int lastRow = sheet.getLastRowNum();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int rowCount = 0;
System.out.println(row);
for (int i = 2; i <= lastRow; i++) {
currentAssociate = sheet.getRow(i).getCell(1).toString();
currentLawName = sheet.getRow(i).getCell(3).toString();
currentCountry = sheet.getRow(i).getCell(4).toString();
currentPages = sheet.getRow(i).getCell(5).toString();
previousAssociate = sheet.getRow(i - 1).getCell(1).toString();
previousLawName = sheet.getRow(i - 1).getCell(3).toString();
previousCountry = sheet.getRow(i - 1).getCell(4).toString();
previousPages = sheet.getRow(i - 1).getCell(5).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
rowCount += 1;
}
} else {
shiftRowsUp(sheet, i, rowCount);
i -= rowCount;
rowCount = 0;
}
}
shiftRowsUp(sheet, i, rowCount);
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Quality Sheet\\new.xls");
workbook.write(fileOut);
fileOut.close();
}
private void shiftRowsUp(Sheet sheet, int startRow, int rowCount) {
if (rowCount > 0) {
int lastRow = sheet.getLastRowNum();
if (lastRow - startRow < rowCount) {
for (int i = startRow - rowCount; i < startRow: i++) {
sheet.removeRow(sheet.getRow(i));
}
}
sheet.shiftRows(startRow, lastRow, -rowCount);
}
}
}
Note, this looping assumes that there are no gaps in the rows of the spreadsheet.

How to read first n lines of a HUGE excel file

So I'm trying to write a program that scans for a specific pattern in a row of an excel file. Namely for an N followed by any letter, then an S or a T (with each letter occupying a single cell).
The problem is, the excel file that I'm using is absolutely massive, with roughly 3000 rows and nearly 1000 columns. I'm trying to search for this pattern only in the first 60 rows in order to reduce java heap space. How can I suit my algorithm to do this? I'm still getting out of memory exceptions.
My code is as follows:
import java.awt.List;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
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 ExcelReader {
public int Reader(File file) throws IOException, EncryptedDocumentException, InvalidFormatException {
FileInputStream fis = new FileInputStream(file);
String filepath = file.getPath();
Workbook wb = WorkbookFactory.create(new File(filepath));
XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
ArrayList<Integer> list = new ArrayList<Integer>();
int rows;
int cols = 0;
int temp = 0;
rows = sheet.getPhysicalNumberOfRows();
for (int i = 0; i < 10 || i < 60; i++) {
row = sheet.getRow(i);
if (row != null) {
temp = sheet.getRow(i).getPhysicalNumberOfCells();
if (temp > cols)
cols = temp;
}
}
for (int r = 0; r <= 60; r++) {
row = sheet.getRow(r);
if (row != null) {
for (int c = 0; c <= cols; c++) {
int numblanks = 0;
cell = row.getCell((short) c);
if (cell != null) {
//System.out.print(cell + "\t\t");
} else {
//System.out.print("\t\t");
}
if (cell != null && cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
if ("N".equals(cell.getStringCellValue())) {
for (int k = c; k <= cols; k++) {
if ("-".equals(row.getCell(k).getStringCellValue())) {
numblanks++;
continue;
}
if ("S".equals(row.getCell(c + 2 + numblanks).getStringCellValue())
|| "T".equals(row.getCell(c + 2 + numblanks).getStringCellValue())) {
list.add((int) sheet.getRow(1).getCell(c).getNumericCellValue());
break;
}
}
}
}
}
System.out.println();
}
}
System.out.println();
System.out.println("Rows: " + rows);
System.out.println("Columns: " + cols);
System.out.println(list);
return temp;
}
}
Convert to CSV file which is easy enough to do.
If possible I would do an insert of the data into a database table and use a procedure to search and find what you're looking for.
This can be done using Spring Batch and Java

Getting specific data from an excel sheet JAVA

I am trying to get specific data from an excel sheet, The data is dynamic. It can be anything really. The column headers are the only things i can use for placeholders, but the column header positions can vary in the sheet.
For example i have a sheet like this :
|Name| Surname| Value|
|bar | poo | 5|
|baz | foo | 7|
But for example i need to traverse the sheet to get the surname column and then if i find surname = 'poo' i must then pull its corresponding value which in the sheet is in the next colum but this is dynamic. The surname and value column arent always next to each other, they can be in any position at the top. But if i find a specific 'thing' in the surname column i need to pull its value.
I have managed to traverse through the sheet and store all the data in a 2d array And display that data. from the research ive done , this isnt an efficient approach as traversing and storing large data from sheets can use alot of memory. Ive read that you can read through an excel sheet and instead of storing those values in an array you can write them immediately to another sheet, if they match a certain condition. EG: (pseudo) If(columnheader == surname && surname == foo )then get corresponding value, then write that value to a new sheet.
Okay so my questions are :
1.How do i achieve iterating through the sheet not storing it in an array and writing it straight to another sheet if it matches a condition?
2.From the code i have below, how do i achieve sorting through the data in the array and finding if surname = foo get its corresponding value?
Like i said the data in the sheet is dynamic except for the column headers, but there positions as headers are dynamic.
Sorry for the long post , any help will be greatly appreciated.
package demo.poi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
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.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class test {
public static void main(String[] args) throws Exception {
File excel = new File("test.xlsx");
FileInputStream fis = new FileInputStream(excel);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet ws = wb.getSheetAt(0);
ws.setForceFormulaRecalculation(true);
int rowNum = ws.getLastRowNum() + 1;
int colNum = ws.getRow(0).getLastCellNum();
int surnameHeaderIndex = -1, valueHeaderIndex = -1;
//Read the headers first. Locate the ones you need
XSSFRow rowHeader = ws.getRow(0);
for (int j = 0; j < colNum; j++) {
XSSFCell cell = rowHeader.getCell(j);
String cellValue = cellToString(cell);
if("SURNAME".equalsIgnoreCase(cellValue)) {
surnameHeaderIndex = j;
} else if("VALUE".equalsIgnoreCase(cellValue)) {
valueHeaderIndex = j;
}
}
if(surnameHeaderIndex == -1 || valueHeaderIndex == -1) {
throw new Exception("Could not find header indexes\nSurname : " + surnameHeaderIndex + " | Value : " + valueHeaderIndex);
}
//createnew workbook
XSSFWorkbook workbook = new XSSFWorkbook();
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("data");
for (int i = 1; i < rowNum; i++) {
XSSFRow row = ws.getRow(i);
row = sheet.createRow(rowNum++);
String surname = cellToString(row.getCell(surnameHeaderIndex));
String value = cellToString(row.getCell(valueHeaderIndex));
int cellIndex = 0;
row.createCell(cellIndex++).setCellValue(surname);
row.createCell(cellIndex++).setCellValue(value);
}
FileOutputStream fos = new FileOutputStream(new File("test1.xlsx"));
workbook.write(fos);
fos.close();
}
public static String cellToString(XSSFCell cell) {
int type;
Object result = null;
type = cell.getCellType();
switch (type) {
case XSSFCell.CELL_TYPE_NUMERIC:
result = BigDecimal.valueOf(cell.getNumericCellValue())
.toPlainString();
break;
case XSSFCell.CELL_TYPE_STRING:
result = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
result = "";
break;
case XSSFCell.CELL_TYPE_FORMULA:
result = cell.getCellFormula();
}
return result.toString();
}
}
Something like this should be a good starting point.
Basically you parse the first row, where the headers are located.
You find the position of the headers you want and keep them.
In this example there are only two headers (surname, value) that are needed so I just keep two variables. If there are more, then the solution would be to keep the position of those headers in a HashMap, where the key is the name of the header. After that an iteration of the rows begins. The program parses the values of the columns that are needed (row.getCell(index)). Now you have the values that you need, and only them. You can do whatever you want, you can print them or write a file or whatnot.
Here is an example. The error handling is up to you. This is only an example.
package POIParser;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
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 MainPoi {
public static void main(String[] args) throws Exception {
File excel = new File("test.xlsx");
FileInputStream fis = new FileInputStream(excel);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet ws = wb.getSheetAt(0);
ws.setForceFormulaRecalculation(true);
int rowNum = ws.getLastRowNum() + 1;
int colNum = ws.getRow(0).getLastCellNum();
int surnameHeaderIndex = -1, valueHeaderIndex = -1;
// Read the headers first. Locate the ones you need
XSSFRow rowHeader = ws.getRow(0);
for (int j = 0; j < colNum; j++) {
XSSFCell cell = rowHeader.getCell(j);
String cellValue = cellToString(cell);
if ("SURNAME".equalsIgnoreCase(cellValue)) {
surnameHeaderIndex = j;
} else if ("VALUE".equalsIgnoreCase(cellValue)) {
valueHeaderIndex = j;
}
}
if (surnameHeaderIndex == -1 || valueHeaderIndex == -1) {
throw new Exception("Could not find header indexes\nSurname : "
+ surnameHeaderIndex + " | Value : " + valueHeaderIndex);
}
// createnew workbook
XSSFWorkbook workbook = new XSSFWorkbook();
// Create a blank sheet
XSSFSheet sheet = workbook.createSheet("data");
for (int i = 1; i < rowNum; i++) {
XSSFRow row = ws.getRow(i);
String surname = cellToString(row.getCell(surnameHeaderIndex));
String value = cellToString(row.getCell(valueHeaderIndex));
int cellIndex = 0;
//Create a newRow object for the output excel.
//We begin for i = 1, because of the headers from the input excel, so we go minus 1 in the new (no headers).
//If for the output we need headers, add them outside this for loop, and go with i, not i-1
XSSFRow newRow = sheet.createRow(i-1);
newRow.createCell(cellIndex++).setCellValue(surname);
newRow.createCell(cellIndex++).setCellValue(value);
}
FileOutputStream fos = new FileOutputStream(new File("test1.xlsx"));
workbook.write(fos);
fos.close();
}
public static String cellToString(XSSFCell cell) {
int type;
Object result = null;
type = cell.getCellType();
switch (type) {
case XSSFCell.CELL_TYPE_NUMERIC:
result = BigDecimal.valueOf(cell.getNumericCellValue())
.toPlainString();
break;
case XSSFCell.CELL_TYPE_STRING:
result = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
result = "";
break;
case XSSFCell.CELL_TYPE_FORMULA:
result = cell.getCellFormula();
}
return result.toString();
}
}

reading specific column of excel into java program

I need to read specific column of an excel sheet and then declare the variables in java. The program that I have done reads the entire content of excel sheet. But I need to read a fixed column like C.
This is what I have done:
import java.io.File;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
public class JavaApplication4
{
private String inputFile;
String[][] data = null;
public void setInputFile(String inputFile)
{
this.inputFile = inputFile;
}
public String[][] read() throws IOException
{
File inputWorkbook = new File(inputFile);
Workbook w;
try
{
w = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet sheet = w.getSheet(0);
data = new String[sheet.getColumns()][sheet.getRows()];
// Loop over first 10 column and lines
// System.out.println(sheet.getColumns() + " " +sheet.getRows());
for (int j = 0; j <sheet.getColumns(); j++)
{
for (int i = 0; i < sheet.getRows(); i++)
{
Cell cell = sheet.getCell(j, i);
data[j][i] = cell.getContents();
// System.out.println(cell.getContents());
}
}
for (int j = 0; j < data.length; j++)
{
for (int i = 0; i <data[j].length; i++)
{
System.out.println(data[j][i]);
}
}
}
catch (BiffException e)
{
e.printStackTrace();
}
return data;
}
public static void main(String[] args) throws IOException
{
JavaApplication4 test = new JavaApplication4();
test.setInputFile("C://users/admin/Desktop/Content.xls");
test.read();
}
}
Here is my excel sheet,
From a bowl of chits numbered /#v1#/ to /#v2#/ , a single chit is randomly drawn. Find the probability that the chit drawn is a number that is a multiple of /#v3#/ or /# v4#/?
I need to read this data and by matching the pattern /#v1#1, I need to declare the variables. How can I do this?
What you can do, you should first get all the columns from the sheet by using sheet.getColumns() and store all columns in a list . Then you can match get all values based on columns. or you can get for only column "C".try using below code. let me know if this works.
int masterSheetColumnIndex = sheet.getColumns();
List<String> ExpectedColumns = new ArrayList<String>();
for (int x = 0; x < masterSheetColumnIndex; x++) {
Cell celll = sheet.getCell(x, 0);
String d = celll.getContents();
ExpectedColumns.add(d);
}
LinkedHashMap<String, List<String>> columnDataValues = new LinkedHashMap<String, List<String>>();
List<String> column1 = new ArrayList<String>();
// read values from driver sheet for each column
for (int j = 0; j < masterSheetColumnIndex; j++) {
column1 = new ArrayList<String>();
for (int i = 1; i < sheet.getRows(); i++) {
Cell cell = sheet.getCell(j, i);
column1.add(cell.getContents());
}
columnDataValues.put(ExpectedColumns.get(j), column1);
}
This is the very simple and efficient code and Working as expected
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;
public class TestExcelFile {
public static void main(String[] args) {
String envFilePath = System.getenv("AZURE_FILE_PATH");
// upload list of files/directory to blob storage
File folder = new File(envFilePath);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
Workbook workbook;
//int masterSheetColumnIndex = 0;
try {
workbook = WorkbookFactory.create(new FileInputStream(envFilePath + "\\"+ listOfFiles[i].getName()));
// Get the first sheet.
Sheet sheet = workbook.getSheetAt(0);
//we will search for column index containing string "Your Column Name" in the row 0 (which is first row of a worksheet
String columnWanted = "Column_Name";
Integer columnNo = null;
//output all not null values to the list
List<Cell> cells = new ArrayList<Cell>();
// Get the first cell.
Row row = sheet.getRow(0);
//Cell cell = row.getCell(0);
for (Cell cell : row) {
// Column header names.
//System.out.println(cell.toString());
if (cell.getStringCellValue().equals(columnWanted)){
columnNo = cell.getColumnIndex();
}
}
if (columnNo != null){
for (Row row1 : sheet) {
Cell c = row1.getCell(columnNo);
if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
//System.out.println(c);
}
}
}else{
System.out.println("could not find column " + columnWanted + " in first row of " + listOfFiles[i].getName());
}
} catch (InvalidFormatException | IOException e) {
e.printStackTrace();
}
}
}
}
}
Reading Particular column from excel file
File myFile = new File(path);
FileInputStream fis = new FileInputStream(myFile);
// Finds the workbook instance for XLSX file
XSSFWorkbook myWorkBook = new XSSFWorkbook (fis);
//XSSFWorkbook workBook = new XSSFWorkbook();
//Reading sheet at number 0 in spreadsheet(image attached for reference
Sheet sheet = myWorkBook.getSheetAt(0);
//creating a Sheet object to retrieve object
Iterator<Row> itr = sheet.iterator();//iterating over excel file
while (itr.hasNext())
{
Row row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator();//iterating over each column
//Reading cell in my case column name is ppm
Cell ppmEx= row.getCell(0);
//Cell cell = cellIterator.next();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
//System.out.println(cell.getNumericCellValue() + " ");
al.add(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
//System.out.println(cell.getStringCellValue()+" ");
al.add(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
//System.out.println(cell.getBooleanCellValue()+" ");
al.add(cell.getBooleanCellValue());
case Cell.CELL_TYPE_BLANK:
//System.out.println("blank");
al.add("blank");
}
}
System.out.println("-");
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package xlsxreader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
/**
*
* #author khaled
*/
public class XlsxReader {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException, InvalidFormatException {
File file = new File("C:\\Users\\khaled\\Desktop\\myXLSX file.xlsx");
Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
Sheet sheet = workbook.getSheetAt(0);
int column_index_1 = 0;
int column_index_2 = 0;
int column_index_3 = 0;
Row row = sheet.getRow(0);
for (Cell cell : row) {
// Column header names.
switch (cell.getStringCellValue()) {
case "MyFirst Column":
column_index_1 = cell.getColumnIndex();
break;
case "3rd Column":
column_index_2 = cell.getColumnIndex();
break;
case "forth Column":
column_index_3 = cell.getColumnIndex();
break;
}
}
for (Row r : sheet) {
if (r.getRowNum()==0) continue;//hearders
Cell c_1 = r.getCell(column_index_1);
Cell c_2 = r.getCell(column_index_2);
Cell c_3 = r.getCell(column_index_3);
if (c_1 != null && c_1.getCellType() != Cell.CELL_TYPE_BLANK
&&c_2 != null && c_2.getCellType() != Cell.CELL_TYPE_BLANK
&&c_3 != null && c_3.getCellType() != Cell.CELL_TYPE_BLANK) {
System.out.print(" "+c_1 + " " + c_2+" "+c_3+"\n");
}
}
}
}

Categories

Resources