When I try to upload this file to my application, It shows an error in row 4. When I try
int totalRows = worksheet.getPhysicalNumberOfRows(); This shows incorrect number of rows(like 26,306). But this error only occurs in some excel files. I want to add records to my application which contain in excel file. How to delete this empty records?
This is my code
List<NewLocationFile> newLocationList = new ArrayList<>();
StringBuilder columnBuffer = new StringBuilder();
String comma = "";
List<NewLocationFile> updatedLocationList = new ArrayList<>();
try (Workbook workbook = new XSSFWorkbook(inputStream);) {
Sheet worksheet = workbook.getSheetAt(0);
int totalRows = worksheet.getPhysicalNumberOfRows();
worksheet.removeRow(worksheet.getRow(0));// remove header
LOGGER.info("readNewLocationFileRequest:traceId={}|totalRows={}",traceId,totalRows);
if (totalRows <= 1) {
throw new PSException(ErrorCode.INVALID_INPUT_PROVIDED, "Empty excel sheet ");
}
else {
newLocationList.addAll(locationDetails(worksheet, traceId));
}
private List<NewLocationFile> locationDetails(Sheet worksheet String traceId) {
List<NewLocationFile> newLocationList = new ArrayList<>();
int j = 0;
for (Row row : worksheet) {
j++;
int excelSheetRow = j + 1;
newLocationList.add(returnLocations(row, excelSheetRow, userBrn,traceId));
}
String converToString = CommonUtil.convertToString(newLocationList);
return newLocationList;
}
private NewLocationFile returnLocations(Row row,int excelSheetRow,String traceId)
{
String productCategory = null;
//initiate all values to null here
if (dataFormatter.formatCellValue(row.getCell(13)).trim().length() > 0) {
productCategory = CommonUtil.getWorkSheetCellStringValue(row.getCell(13)).toUpperCase();
} else {
throw new PostSaleModificationException(ErrorCode.INVALID_PRODUCT_TYPE,
"Invalid product category in row :" + excelSheetRow);
}
//All validations listed here
newLocation.setComplexProduct(complexProduct);
//set all values here
}
But Error message pop-up is displayed "Invalid product category in row 4" But this sheet has only 3 rows.
I found this solution ;)
List<NewLocationFile> newLocationList = new ArrayList<>();
StringBuilder columnBuffer = new StringBuilder();
String comma = "";
List<NewLocationFile> updatedLocationList = new ArrayList<>();
try (Workbook workbook = new XSSFWorkbook(inputStream);) {
Sheet worksheet = workbook.getSheetAt(0);
int totalRows = worksheet.getPhysicalNumberOfRows();
worksheet.removeRow(worksheet.getRow(0));// remove header
removeEmptyRows(worksheet);
LOGGER.info("readNewLocationFileRequest:traceId={}|totalRows={}",traceId,totalRows);
if (totalRows <= 1) {
throw new PSException(ErrorCode.INVALID_INPUT_PROVIDED, "Empty excel sheet ");
}
else {
newLocationList.addAll(locationDetails(worksheet, traceId));
}
private Sheet removeEmptyRows(Sheet worksheet) {
boolean stop = false;
boolean nonBlankRowFound;
short c;
XSSFRow lastRow = null;
XSSFCell cell = null;
while (!stop) {
nonBlankRowFound = false;
lastRow = (XSSFRow) worksheet.getRow(worksheet.getLastRowNum());
for (c = lastRow.getFirstCellNum(); c <= lastRow.getLastCellNum(); c++) {
cell = lastRow.getCell(c);
if (cell != null && lastRow.getCell(c).getCellType() != CellType.BLANK) {
nonBlankRowFound = true;
}
}
if (nonBlankRowFound == true) {
stop = true;
} else {
worksheet.removeRow(lastRow);
}
}
return worksheet;
}
Related
I want to clone an Excel sheet and all of its contents. I tried the XSSFWorkbook cloneSheet method, but it seems the workbook is corrupted if my sheet contains an Excel table. See the examle workbook below with a simple table:
When I try to open the output workbook, I get a prompt telling me that the file is broken and needs to be repaired. If I recover the workbook, it is clear the table has not been copied correctly; the original totals row is now a data row.
try (InputStream is = Table.class.getResourceAsStream("table.xlsx")) {
XSSFWorkbook workbook = new XSSFWorkbook(is);
workbook.cloneSheet(0, "Test");
try (OutputStream fileOut = new FileOutputStream("table-2.xlsx")) {
workbook.write(fileOut);
}
} catch (IOException e) {
e.printStackTrace();
}
How I would go about copying this sheet? Any help is appreciated!
XSSFWorkbook.cloneSheet clones a sheet. But it does not considering the possible defined tables in it. It simply clones the table references. But two table-ranges in sheets cannot refer to the same table reference. The tables itself needs to be cloned. That's why the corrupted workbook as result.
I've tried to solve this by programming a method cloneTables(XSSFSheet sheet) which simply creates clones of each table in a sheet which then refer to their own table reference each. I consider table styles, auto-filter, a totals-row and calculated column formulas. I hope I have not overlooked something, but I doubt that.
The code its tested and works using current apache poi 5.2.2.
It contains fixes for following bugs too:
XSSFTable.updateHeaders fails in Excel workbooks created using current Excel versions. This is because of the test row.getCTRow().validate() which always will be false because of the usage of new name spaces. See Renaming headers of XSSFTable with Apache Poi leads to corrupt XLSX-file.
XSSFSheet.removeTable does not remove the links to the table part reference from the sheet.
Complete example to test:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
class ExcelCloneSheetHavingTable {
static void updateHeaders(XSSFTable table) {
XSSFSheet sheet = (XSSFSheet)table.getParent();
CellReference ref = table.getStartCellReference();
if (ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
DataFormatter formatter = new DataFormatter();
if (row != null /*&& row.getCTRow().validate()*/) { // see bug: https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
int cellnum = firstHeaderColumn;
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns ctTableColumns = table.getCTTable().getTableColumns();
if(ctTableColumns != null) {
for (org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn col : ctTableColumns.getTableColumnList()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
String colName = formatter.formatCellValue(cell);
colName = colName.replace("\n", "_x000a_");
colName = colName.replace("\r", "_x000d_");
col.setName(colName);
}
cellnum++;
}
}
}
//tableColumns = null;
//columnMap = null;
//xmlColumnPrs = null;
//commonXPath = null;
try {
java.lang.reflect.Field tableColumns = XSSFTable.class.getDeclaredField("tableColumns");
tableColumns.setAccessible(true);
tableColumns.set(table, null);
java.lang.reflect.Field columnMap = XSSFTable.class.getDeclaredField("columnMap");
columnMap.setAccessible(true);
columnMap.set(table, null);
java.lang.reflect.Field xmlColumnPrs = XSSFTable.class.getDeclaredField("xmlColumnPrs");
xmlColumnPrs.setAccessible(true);
xmlColumnPrs.set(table, null);
java.lang.reflect.Field commonXPath = XSSFTable.class.getDeclaredField("commonXPath");
commonXPath.setAccessible(true);
commonXPath.set(table, null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
static String getSubtotalFormulaStartFromTotalsRowFunction(int intTotalsRowFunction) {
final int INT_NONE = 1;
final int INT_SUM = 2;
final int INT_MIN = 3;
final int INT_MAX = 4;
final int INT_AVERAGE = 5;
final int INT_COUNT = 6;
final int INT_COUNT_NUMS = 7;
final int INT_STD_DEV = 8;
final int INT_VAR = 9;
final int INT_CUSTOM = 10;
String subtotalFormulaStart = null;
switch (intTotalsRowFunction) {
case INT_NONE:
subtotalFormulaStart = null;
break;
case INT_SUM:
subtotalFormulaStart = "SUBTOTAL(109";
break;
case INT_MIN:
subtotalFormulaStart = "SUBTOTAL(105";
break;
case INT_MAX:
subtotalFormulaStart = "SUBTOTAL(104";
break;
case INT_AVERAGE:
subtotalFormulaStart = "SUBTOTAL(101";
break;
case INT_COUNT:
subtotalFormulaStart = "SUBTOTAL(103";
break;
case INT_COUNT_NUMS:
subtotalFormulaStart = "SUBTOTAL(102";
break;
case INT_STD_DEV:
subtotalFormulaStart = "SUBTOTAL(107";
break;
case INT_VAR:
subtotalFormulaStart = "SUBTOTAL(110";
break;
case INT_CUSTOM:
subtotalFormulaStart = null;
break;
default:
subtotalFormulaStart = null;
}
return subtotalFormulaStart;
}
static void cloneTables(XSSFSheet sheet) {
for (XSSFTable table : sheet.getTables()) {
// clone table; XSSFTable.setArea fails and throws exception for too small tables
XSSFTable clonedTable = null;
int rowCount = (table.getArea().getLastCell().getRow() - table.getArea().getFirstCell().getRow()) + 1;
int headerRowCount = table.getHeaderRowCount(); if (headerRowCount == 0) headerRowCount = 1;
int minimumRowCount = 1 + headerRowCount + table.getTotalsRowCount();
if (rowCount >= minimumRowCount) {
clonedTable = sheet.createTable(table.getArea());
}
if (clonedTable != null) {
//clonedTable.updateHeaders(); // don't work, see bug: https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
updateHeaders(clonedTable);
// clone style
clonedTable.setStyleName(table.getStyleName());
XSSFTableStyleInfo style = (XSSFTableStyleInfo)table.getStyle();
XSSFTableStyleInfo clonedStyle = (XSSFTableStyleInfo)clonedTable.getStyle();
if (style != null && clonedStyle != null) {
clonedStyle.setShowColumnStripes(style.isShowColumnStripes());
clonedStyle.setShowRowStripes(style.isShowRowStripes());
clonedStyle.setFirstColumn(style.isShowFirstColumn());
clonedStyle.setLastColumn(style.isShowLastColumn());
}
//clone autofilter
clonedTable.getCTTable().setAutoFilter(table.getCTTable().getAutoFilter());
//clone totalsrow
int totalsRowCount = table.getTotalsRowCount();
if (totalsRowCount == 1) { // never seen more than one totals row
XSSFRow totalsRow = sheet.getRow(clonedTable.getEndCellReference().getRow());
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
clonedTableCol.setTotalsRowFunction(tableCol.getTotalsRowFunction());
int intTotalsRowFunction = clonedTableCol.getTotalsRowFunction().intValue();
sheet.getWorkbook().setCellFormulaValidation(false);
if (intTotalsRowFunction == 10) { //custom
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableFormula totalsRowFormula = tableCol.getTotalsRowFormula();
clonedTableCol.setTotalsRowFormula(totalsRowFormula);
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(totalsRowFormula.getStringValue());
} else if (intTotalsRowFunction == 1) { //none
//totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setBlank();
} else {
String subtotalFormulaStart = getSubtotalFormulaStartFromTotalsRowFunction(intTotalsRowFunction);
if (subtotalFormulaStart != null)
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(subtotalFormulaStart + "," + clonedTable.getName() +"[" + clonedTableCol.getName()+ "])");
}
}
}
}
// clone calculated column formulas
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
if (tableCol.getCalculatedColumnFormula() != null) {
clonedTableCol.setCalculatedColumnFormula(tableCol.getCalculatedColumnFormula());
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableFormula calculatedColumnFormula = clonedTableCol.getCalculatedColumnFormula();
String formula = tableCol.getCalculatedColumnFormula().getStringValue();
String clonedFormula = formula.replace(table.getName(), clonedTable.getName());
calculatedColumnFormula.setStringValue(clonedFormula);
int rFirst = clonedTable.getStartCellReference().getRow() + clonedTable.getHeaderRowCount();
int rLast = clonedTable.getEndCellReference().getRow() - clonedTable.getTotalsRowCount();
int c = clonedTable.getStartCellReference().getCol() + i;
sheet.getWorkbook().setCellFormulaValidation(false);
for (int r = rFirst; r <= rLast; r++) {
XSSFRow row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellFormula(clonedFormula);
}
}
}
}
}
// remove old table; do that even if XSSFsheet.createTable failed, because a one-cell-table doesn't make any sense
String rId = sheet.getRelationId(table);
sheet.removeTable(table);
// remove links to the table part reference
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts tblParts = sheet.getCTWorksheet().getTableParts();
if (tblParts != null && tblParts.getTablePartList().size() > 0) {
for (int i = 0; i < tblParts.getTablePartList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart tblPart = tblParts.getTablePartArray​(i);
if(tblPart.getId().equals(rId)) {
tblParts.removeTablePart​(i);
}
}
}
}
}
public static void main(String[] args) throws Exception {
try (Workbook workbook = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));
FileOutputStream out = new FileOutputStream("SAMPLE_NEW.xlsx")) {
XSSFSheet sheet = ((XSSFWorkbook)workbook).cloneSheet(0, "Test");
cloneTables(sheet);
workbook.write(out);
}
}
}
This code needs the full jar of all of the schemas, which is poi-ooxml-full-5.2.2.jar for apache poi 5.2.2, as mentioned in FAQ. Note, since apache poi 5.* the formerly used ooxml-schemas-*.jar cannot be used anymore. There must not be any ooxml-schemas-*.jar in class path when using apache poi 5.*.
Note, you need this additional. The file names poi-ooxml-5.2.2.jar and poi-ooxml-lite-5.2.2.jar respective poi-ooxml-full-5.2.2.jar are misleading. The *-lite*.jar respective *-full*.jar do not replace, but complement the poi-ooxml-5.2.2.jar.
I am trying to read Excel -2*2 matrix through Apache POI. But the first value returned by 2D array is [null,null]. Please check my code and advise for suitable corrections.
public String[][] getDataArray(String sheetName)
{
String value ="";
String[][] data = null;
int rowCount = wb.getSheet(sheetName).getLastRowNum();
int colCount = wb.getSheet(sheetName).getRow(1).getLastCellNum()-1;
data = new String[rowCount][colCount];
for(int i=1; i<=rowCount;i++)
{
Row row = wb.getSheet(sheetName).getRow(i);
for(int j=0;j<colCount;j++)
{
Cell cell = row.getCell(j);
if(cell.getCellType()==Cell.CELL_TYPE_NUMERIC)
{
value = ""+cell.getStringCellValue();
}
else
{
value = cell.getStringCellValue();
}
data[i][j] = value;
}
}
return data;
}
The debug view where we can see that the first value stored in the variable data is null, null
The excel which i am trying to read. I need only the userName and password data(2*2) alone. Not the header and Run mode datas.
Of course the value in the index 0 will be null because the i starts from 1 and not 0
for (int i = 1; i <= rowCount; i++) //i starts from one
...
data[i][j] = value;
either initialize the i from 0 or do like this
data[i-1][j] = value;
public static String[][] getSheetData(final String fileName, final String workSheetName)
throws Exception {
Integer lastRow = null;
short lastCol = 0;
String[][] sheetData = null;
FileInputStream file=new FileInputStream(MettlTest.class.getClass().getResource("/" + fileName).getPath());
workbook = new XSSFWorkbook(file);
sheet = workbook.getSheet(workSheetName);
try {
XSSFRow row;
XSSFCell cell;
lastRow = sheet.getPhysicalNumberOfRows();
lastCol = sheet.getRow(1).getLastCellNum();
sheetData = new String[lastRow - 1][lastCol];
for (int r = 1; r < lastRow; r++) {
row = sheet.getRow(r);
if (row != null) {
for (int c = 0; c < lastCol; c++) {
cell = row.getCell(c);
if (cell == null) {
sheetData[r][c] = null;
} else {
sheetData[r-1][c] = new DataFormatter().formatCellValue(cell);
}
}
}
}
return sheetData;
}
catch (final Exception e) {
throw e;
}
finally {
try {
file.close();
} catch (IOException io) {
Reporter.log("Unable to close File : " + fileName);
throw io;
}
}
I am using APACHE POI 3.0 to add sheets to existing excel sheet. It works fine.
But as APACHE POI has limitations about making charts, I used a template excel file to create charts, which also worked fine, but this always result in new excel file.
If I have an existing excel sheet and I want to add a sheet, having charts, I am not able to do it. As, when I create charts, I use template file and it always makes a new excel file.
so I was wondering if there is any solution of it of adding sheets to excel, where the sheets have charts
public class TagBrowserSelection
{
private static String[] excelBarPlot_Template = { "","barPlot_1Panel_template.xlsx"};
private static String[] excelPieChart_Template = { "","pieChart_1Panel_template.xlsx"};
private static String[] excelPieAndBarPlot_Template = { "","pieAndBarChart_1Panel_template.xlsx"};
private static String REGEX = "";
static public boolean makeTagBrowserSelection(String strOutputFileName, ArrayList<TagBrowserChildPanel> childList, String sheetName, boolean addSheet, ArrayList<Boolean> chartAttributes)
{
// chart attributes
boolean addBarChart = chartAttributes.get(0);
boolean addPieChart = chartAttributes.get(1);
boolean addNoTag = chartAttributes.get(2);
boolean addZeros = chartAttributes.get(3);
REGEX = "^" + sheetName;
Pattern p = Pattern.compile(REGEX);
String[] templateArray = null;
if (addBarChart && addPieChart)
templateArray = excelPieAndBarPlot_Template;
else if (addBarChart)
templateArray = excelBarPlot_Template;
else if (addPieChart)
templateArray = excelPieChart_Template;
try
{
int number = childList.size();
XSSFWorkbook workbook = null;
XSSFWorkbook wb = null;
XSSFSheet sheet = null;
int col_num = 0;
int row_num = 0;
XSSFRow row = null;
XSSFCell cell = null;
// if adding sheet to existing excel file
if (addSheet)
{
FileInputStream fis = new FileInputStream(new File(strOutputFileName));
workbook = new XSSFWorkbook(fis);
fis.close();
// number of existing sheets in excel file
int numberOfSheets = workbook.getNumberOfSheets();
// check is sheetName exists already
if (isSheetExist(sheetName, workbook))
{
int counter = 1;
for (int ii = 0; ii < numberOfSheets; ii++)
{
Matcher m = p.matcher(workbook.getSheetName(ii));
if (m.find())
counter++;
}
sheetName = sheetName + " (" + counter + ")";
}
}
else
{
workbook = new XSSFWorkbook();
}
======================================================================
// if template file needs to be used(if bar chart/pie chart option is selected)
if (templateArray != null)
{
InputStream is = TagBrowserSelection.class.getClassLoader().getResourceAsStream(templateArray[number]);
wb = new XSSFWorkbook(OPCPackage.open(is));
sheet = wb.getSheetAt(0);
// wb.close();
}
else
{
sheet = workbook.createSheet(sheetName);
}
// Freeze top two row
// sheet.createFreezePane(0, 1, 0, 1);
// Filling up the workbook and performing the row/column formatting
for (TagBrowserChildPanel child : childList)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(0);
if (row == null)
row = sheet.createRow(0);
// Adding tag category name as header
String tagCategory = child.getSelectedCategory().getName();
cell = row.createCell(col_num);
cell.setCellValue(tagCategory);
row = sheet.getRow(1);
if (row == null)
row = sheet.createRow(1);
// Adding column headers
cell = row.createCell(col_num);
cell.setCellValue("tag");
cell = row.createCell(col_num + 1);
cell.setCellValue("counts");
row_num = 2;
// Adding tag category document summary(name and counts)
ArrayList<TagSummaryItem> tagSummary = child.getTagChartCounts();
for (int i = 0; i < tagSummary.size(); i++)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(row_num);
if (row == null)
row = sheet.createRow(row_num);
cell = row.createCell(col_num);
if (!addNoTag)
{
if (tagSummary.get(i).m_strTag == "[No Tag]")
continue;
}
if (!addZeros)
{
if (tagSummary.get(i).m_nCount == 0)
continue;
}
cell.setCellValue(tagSummary.get(i).m_strTag);
cell = row.createCell(col_num + 1);
cell.setCellValue(tagSummary.get(i).m_nCount);
row_num++;
}
// auto-size of tag column
sheet.autoSizeColumn(col_num);
col_num = col_num + 3;
}
FileOutputStream out = new FileOutputStream(strOutputFileName);
if (templateArray != null)
{
wb.setSheetName(0, sheetName);
wb.write(out);
wb.close();
}
else
{
workbook.write(out);
workbook.close();
}
out.close();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
Above is my code, its one code. I split into two sections. Section is the one which uses template to make chart excel sheet.
there's the method cloneSheet() in the HSSFWorkbook class. Try it.
I have been working on a highlighting cells in excel sheet after end of execution when i opened the processed file(.xlsx file) using Ms-excel-2007 i am facing two pop up's .here the specified code and images :
HSSFWorkbook xlsWB = new HSSFWorkbook(file1InputStream);
XSSFWorkbook xlsxWB = new XSSFWorkbook(file2InputStream);
CellStyle xlsxStyle = getCellStyle(xlsxWB);
int numbeoOfSheetsFile1 = xlsWB.getNumberOfSheets();
int numbeoOfSheetsFile2 = xlsxWB.getNumberOfSheets();
for (int sheetIndex = 0; sheetIndex < numbeoOfSheetsFile1 && sheetIndex < numbeoOfSheetsFile2; sheetIndex++) {
HSSFSheet sheetFile1 = xlsWB.getSheetAt(sheetIndex);
XSSFSheet sheetFile2 = xlsxWB.getSheetAt(sheetIndex);
int noOfRowsSheetFile1 = sheetFile1.getLastRowNum();
int noOfRowsSheetFile2 = sheetFile2.getLastRowNum();
if (noOfRowsSheetFile1 < noOfRowsSheetFile2) {
for (int vRow = noOfRowsSheetFile1; vRow <= noOfRowsSheetFile2 - 1; vRow++) {
sheetFile2.createRow(vRow).setRowStyle(xlsxStyle);
//sheetFile2.getRow(vRow).setRowStyle(xlsxStyle);
}
}
if (noOfRowsSheetFile1 > noOfRowsSheetFile2) {
for (int vRow = noOfRowsSheetFile2 + 1; vRow <= noOfRowsSheetFile1; vRow++) {
sheetFile2.createRow(vRow).setRowStyle(xlsxStyle);
//sheetFile2.getRow(vRow).setRowStyle(xlsxStyle);
}
}
for (int vRow = 0; vRow <= noOfRowsSheetFile1; vRow++) {
HSSFRow rwFile1 = sheetFile1.getRow(vRow);
XSSFRow rwFile2 = sheetFile2.getRow(vRow);
int noOfColSheetFile1 = sheetFile1.getRow(vRow).getLastCellNum();
int noOfColSheetFile2 = 0;
try {
noOfColSheetFile2 = sheetFile2.getRow(vRow).getLastCellNum();
} catch (NullPointerException e) {
rwFile2 = sheetFile2.createRow(vRow);
noOfColSheetFile2 = 0;
}
// Coloring of mismatch columns
if (noOfColSheetFile1 < noOfColSheetFile2) {
for (int vCol = noOfColSheetFile1 + 1; vCol <= noOfColSheetFile2; vCol++) {
rwFile2.createCell(vCol);
//rwFile2.getCell(vCol).setCellStyle(xlsxStyle);
}
}
if (noOfColSheetFile1 > noOfColSheetFile2) {
for (int vCo2 = noOfColSheetFile2 + 1; vCo2 <= noOfColSheetFile1; vCo2++) {
rwFile2.createCell(vCo2);
//rwFile2.getCell(vCo2).setCellStyle(xlsxStyle);
}
}
for (int vCol = 0; vCol < noOfColSheetFile1; vCol++) {
//System.out.println("vCol>>" + vCol + "--vRow>>" + vRow);
HSSFCell cellFile1 = rwFile1.getCell(vCol);
XSSFCell cellFile2 = rwFile2.getCell(vCol);
String cellFile1Value = null;
if (null != cellFile1) {
cellFile1Value = cellFile1.toString();
}
String cellFile2Value = null;
if (null != cellFile2) {
cellFile2Value = cellFile2.toString();
}
if ((null == cellFile1Value && null != cellFile2Value) || (null != cellFile1Value && null == cellFile2Value) || (null != cellFile1Value && cellFile1Value.compareTo(cellFile2Value) != 0)) {
if ((null != cellFile1Value && !cellFile1Value.isEmpty()) || (null != cellFile2Value && ! cellFile2Value.isEmpty())) {
CellValues cellValues = new CellValues();
cellValues.setValue1(cellFile1Value);
cellValues.setValue2(cellFile2Value);
cellValues.setCellRow(vRow);
cellValues.setCellColumn(vCol);
scenarioResultDetails.addDifference(cellValues);
XSSFCell cellDiff = rwFile2.getCell(vCol);
if (null == cellDiff) {
cellDiff = rwFile2.createCell(vCol);
}
cellDiff.setCellStyle(xlsxStyle);
}
}
}
}
}
String fileDiff = file2.replace(".xls", "_diff.xls");
FileOutputStream fileOut = new FileOutputStream(fileDiff);
xlsxWB.write(fileOut);
if (null != fileOut) {
try {
fileOut.close();
} catch (Exception e) {
}
}
if (scenarioResultDetails.getDifferencesList().size() > 0) {
scenarioResultDetails.setResult(false);
scenarioResultDetails.setResultText("Not Matched");
scenarioResultDetails.setDiffExcel(fileDiff);
} else {
scenarioResultDetails.setResult(true);
scenarioResultDetails.setResultText("Matched");
}
return scenarioResultDetails;
}
public static void openFile(String fileName){
ReportGenerator.getDriver().get("file://"+fileName);
}
private static CellStyle getCellStyle(XSSFWorkbook xssfWorkbook){
CellStyle style = xssfWorkbook.createCellStyle();
Font font = xssfWorkbook.createFont();
font.setColor(IndexedColors.BLACK.getIndex());
style.setFont(font);
style.setFillForegroundColor(HSSFColor.YELLOW.index);
style.setFillBackgroundColor(HSSFColor.YELLOW.index);
style.setFillPattern(CellStyle.ALIGN_RIGHT);
return style;
}
}
This behavior is still (or again) present. I'm using version 2.4.1 of the NuGet NPOI package which apparently has a FontHeight property bugfix, but it also introduced this.
The problem is that the font size the font returned by xssfWorkbook.createFont(); is way small. You have to set it explicitly like so:
IFont font = excel.CreateFont();
font.FontHeightInPoints = 11;
Also I got similar errors when overwriting a file that was previously repaired. Make sure you write to a clean/new file every time you change your code so no previous corruptions get in the way.
Full example:
/// <summary>
/// Return style for header cells.
/// </summary>
/// <returns></returns>
private static ICellStyle GetHeaderStyle(this XSSFWorkbook excel)
{
IFont font = excel.CreateFont();
font.IsBold = true;
//Added this explicitly, initial font size is tiny
font.FontHeightInPoints = 11;
ICellStyle style = excel.CreateCellStyle();
style.FillForegroundColor = IndexedColors.Grey25Percent.Index;
style.FillPattern = FillPattern.SolidForeground;
style.FillBackgroundColor = IndexedColors.Grey25Percent.Index;
style.BorderBottom = style.BorderLeft = style.BorderRight = style.BorderTop = BorderStyle.Thin;
style.BottomBorderColor = style.LeftBorderColor = style.RightBorderColor = style.TopBorderColor = IndexedColors.Black.Index;
style.SetFont(font);
return style;
}
How can I get a string array from a excel column?
Let's say the column is like this
String0
String1
String2
String3
String4
and I want my array to be like: array[0]="String0", array[1]="String1" etc.
This is the code I am currently using but it always returns "null":
public static String[] excelvalue(String columnWanted, int sheet_no, String path) {
int i = 0;
String[] column_content_array = new String[140];
try {
int instindicator = -1;
FileInputStream file = new FileInputStream(new File(path));
HSSFWorkbook filename = new HSSFWorkbook(file);
HSSFSheet sheet = filename.getSheetAt(sheet_no);
Integer columnNo = null;
Integer rowNo = null;
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = sheet.getRow(0);
for (Cell cell : firstRow) {
if (cell.getStringCellValue().equals(columnWanted)) {
columnNo = cell.getColumnIndex();
rowNo = cell.getRowIndex();
}
}
if (columnNo != null) {
for (Row row : sheet) {
Cell c = row.getCell(columnNo);
String cell_value = "" + c;
cell_value = cell_value.trim();
try {
if ((!cell_value.equals("")) && (!cell_value.equals("null")) && (!cell_value.equals(columnWanted))) {
column_content_array[i] = cell_value;
i++;
}
} catch (Exception e) {
}
}
return column_content_array;
}
} catch (Exception ex) {
return column_content_array;
}
return column_content_array;
}
Instead of storing just last reference of row and column, store all of them in a list like:
List<Integer> columnNos = new ArrayList<>();
List<Integer> rowNos = new ArrayList<>();
And in your for loop, just add rows and columns into list like:
if (cell.getStringCellValue().equals(columnWanted)) {
columnNos.add(cell.getColumnIndex());
rowNo.add(cell.getRowIndex());
}
And then you could iterate over rows and columns and continue with your business logic further.