Why the last empty row has been pulled as an additional test with null values in selenium apache POI - selenium

I have four rows in an excel, first row is for the heading and rest of the three rows has values in it. I have entered the code in a way to avoid the header and read the rows which contains values only. However instead of fetching only three rows it comes with one additional null value rows as below, Why it is fetching the null values did I miss anything? Find the code and error message.
Message
PASSED: testShipment("Mumbai", "New York", "18000", "10000", "20000")
PASSED: testShipment("Mumbai", "Cochin", "2000", "30000", "5000")
PASSED: testShipment("Cochin", "Farah", "16000", "18000", "19000")
FAILED: testShipment(null, null, null, null, null)
Code
int TotalCol = sh.getRow(0).getLastCellNum();
int Totalrows = sh.getLastRowNum()+1;
String[][] data = new String[Totalrows][TotalCol];
DataFormatter formatter = new DataFormatter(); // creating formatter using the default locale
for (int i = 1; i < Totalrows; i++) {
Row r = sh.getRow(i);
for (int j = 0; j < TotalCol; j++) {
Cell c = r.getCell(j);
try {
if (c.getCellType() == Cell.CELL_TYPE_STRING) {
String j_username = formatter.formatCellValue(c);
data[i][j] = j_username;
System.out.println("data[i][j]" + data[i][j]);
} else {
data[i][j] = String.valueOf(c.getNumericCellValue());
String j_username = formatter.formatCellValue(c);
data[i][j] = j_username;
System.out.println("data[i][j] numeric val" + data[i][j]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Try with the below code like checking null condition
for (int k = 1; k <= totalRows; k++) {
String testCaseID = sheet.getRow(k).getCell(0).getStringCellValue();
if (testCaseID.equalsIgnoreCase(tcID)) {
for (int l = 1; l < totalCols; l++) {
String testData_FieldName = sheet.getRow(0).getCell(l).getStringCellValue();
if (testData_FieldName.equalsIgnoreCase(header)) {
cell = sheet.getRow(k).getCell(l);
if (cell != null) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:// numeric value in excel
result = cell.getNumericCellValue();
break;
case Cell.CELL_TYPE_STRING: // string value in excel
result = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_BOOLEAN: // boolean value in excel
result = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_BLANK: // blank value in excel
result = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_ERROR: // Error value in excel
result = cell.getErrorCellValue() + "";
break;
default:
throw new CustomException("The cell data type is invalid");
}
}
}
}
k = totalRows + 1;
}
}

You need to change either the data array declaration part or Totalrows calculation part. Currently, you have created 4 rows object and only 3 rows values are assigned and hence 4th row values are holding null value.
String[][] data = new String[Totalrows][TotalCol];
In your string array, you are not persisting the header value and storing only values. So, please modify your code with any one of the below options (I would suggest you to use option 1)
Option 1:
Remove the +1 from Totalrows variable and add the equal condition in your first for loop
//Removed the +1
int Totalrows = sh.getLastRowNum();
String[][] data = new String[Totalrows][TotalCol];
DataFormatter formatter = new DataFormatter(); // creating formatter using the default locale
//Condition is modified as i <= Totalrows
for (int i = 1; i <= Totalrows; i++) {
Option 2:
Change the data[][] declaration part
int Totalrows = sh.getLastRowNum()+1;
String[][] data = new String[Totalrows-1][TotalCol];

Here is the code that works, thanks to everyone for helping on this!
int TotalCol = sh.getRow(0).getLastCellNum();
int Totalrows = sh.getLastRowNum()+1;
//Entering minus one(-1) during data declaration ignores the first row as first row is a header
String[][] data = new String[Totalrows-1][TotalCol];
DataFormatter formatter = new DataFormatter(); // creating formatter using the default locale
for (int i = 1; i <Totalrows; i++) {
Row r = sh.getRow(i);
for (int j = 0; j < TotalCol; j++) {
Cell c = r.getCell(j);
try {
if (c.getCellType() == Cell.CELL_TYPE_STRING) {
String j_username = formatter.formatCellValue(c);
//Adding minus on(data[i-1]) helps to read the first cell which is (0,1), in this case (0,1) would not read the header since we have skipping the header from the table in the previous step on top, therefore the actual table starts from the second row.
data[i-1][j] = j_username;
System.out.println("data[i-1][j]" + data[i-1][j]);
} else {
data[i-1][j] = String.valueOf(c.getNumericCellValue());
String j_username = formatter.formatCellValue(c);
data[i-1][j] = j_username;
System.out.println("data[i-1][j] numeric val" + data[i-1][j]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
"

Related

How to find empty rows from excel sheet given by user and delete them in asp.net

public async Task<List<IndiaCIT>> Import(IFormFile file)
{
var list = new List<IndiaCIT>();
using (var stream = new MemoryStream())
{
await file.CopyToAsync(stream);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (var package=new ExcelPackage(stream))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
var rowcount = worksheet.Dimension.Rows;
for (int row = 1; row <= rowcount; row++)
{
list.Add(new IndiaCIT {
NameCH = worksheet.Cells[row, 1].Value.ToString().Trim(),
City= worksheet.Cells[row, 2].Value.ToString().Trim(),
Age = worksheet.Cells[row, 3].Value.ToString().Trim(),
});
}
}
}
return list;
}
this is controller code and in model class declared the columns name and used it as IndiaCIT list in controller,. I want empty rows to get deleted
This could help:
For each row in the sheet, check if the cell in each column is empty. If so delete it.
var rowcount = worksheet.Dimension.Rows;
var maxColums = worksheet.Dimension.Columns;
for(int row = rowcount; row > 0; row--)
{
bool isRowEmpty = true;
for(int column = 1; column <= maxColumns; column++)
{
var cellEntry = worksheet.Cells[row, column].Value.ToString();
if(!string.IsNullOrEmpty(cellEntry)
{
isRowEmpty = false;
break;
}
}
if(!isRowEmpty)
continue;
else
worksheet.DeleteRow(row);
}
I generally use Spire.Xls to handle such problems. It works for me.
public IActionResult Test() {
//init workbook
Workbook workbook = new Workbook();
// load file
workbook.LoadFromFile("11.xlsx");
// get the first sheet
Worksheet sheet = workbook.Worksheets[0];
//delete blank row
for (int i = sheet.Rows.Count() - 1; i >= 0; i--)
{
if (sheet.Rows[i].IsBlank)
{
sheet.DeleteRow(i + 1);
}
}
//delete blank column
for (int j = sheet.Columns.Count() - 1; j >= 0; j--)
{
if (sheet.Columns[j].IsBlank)
{
sheet.DeleteColumn(j + 1);
}
}
//save as a new xls file
workbook.SaveToFile("new.xlsx", ExcelVersion.Version2016);
return Ok();
}

EPPlus two color conditional date format

I have a column with dates and I want to conditionally color any cell that is older that 2 week yellow, and any that is older than 90 days red. I can't figure out how to do that.
Should be able to just add the conditions like any other. You can use the TODAY() function in excel and subtract:
[TestMethod]
public void Conditional_Formatting_Date()
{
//https://stackoverflow.com/questions/56741642/epplus-two-color-conditional-date-format
var file = new FileInfo(#"c:\temp\Conditional_Formatting_Date.xlsx");
if (file.Exists)
file.Delete();
//Throw in some data
var dataTable = new DataTable("tblData");
dataTable.Columns.AddRange(new[] {
new DataColumn("Col1", typeof(DateTime)),
new DataColumn("Col3", typeof(string))
});
var rnd = new Random();
for (var i = 0; i < 100; i++)
{
var row = dataTable.NewRow();
row[0] = DateTime.Now.AddDays(-rnd.Next(1, 100));
row[1] = $"=TODAY() - A{i +1}";
dataTable.Rows.Add(row);
}
//Create a test file
using (var package = new ExcelPackage(file))
{
//Make the stylesheet
var ws = package.Workbook.Worksheets.Add("table");
var range = ws.Cells[1, 1].LoadFromDataTable(dataTable, false);
ws.Column(1).Style.Numberformat.Format = "mm-dd-yy";
ws.Column(1).AutoFit();
//Add the calc check
var count = 0;
foreach (DataRow row in dataTable.Rows)
ws.Cells[++count, 2].Formula = row[1].ToString();
//Add the conditions - order matters
var rangeA = range.Offset(0, 0, count, 1);
var condition90 = ws.ConditionalFormatting.AddExpression(rangeA);
condition90.Style.Font.Color.Color = Color.White;
condition90.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition90.Style.Fill.BackgroundColor.Color = Color.Red;
condition90.Formula = "TODAY() - A1> 90";
condition90.StopIfTrue = true;
var condition14 = ws.ConditionalFormatting.AddExpression(rangeA);
condition14.Style.Font.Color.Color = Color.Black;
condition14.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition14.Style.Fill.BackgroundColor.Color = Color.Yellow;
condition14.Formula = "TODAY() - A1> 14";
package.Save();
}
}
Which gives this in the output:
I am assuming that you have the column number of the date column and number of rows in your records. Also, the following loop is under assumption that the first row is your column header and records begin from second row. Change the loop counter's initialization and assignment accordingly.
int rowsCount; //get your no of rows
int dateColNumber; //Assign column number in excel file of your date column
string cellValue;
DateTime dateValue;
DateTime today = DateTime.Now;
double daysCount;
for(int i=1;i<rowsCount;i++)
{
cellValue = ws.Cells[i + 1, dateColNumber].Text.ToString(); //First row is header start from second
if(DateTime.TryParse(cellValue,out dateValue))
{
daysCount = (today - dateValue).Days;
if(daysCount>90)
{
ws.Cells[i + 1,dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1,dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Red);
}
else if(daysCount>14)
{
ws.Cells[i + 1, dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1, dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Yellow);
}
}
}

Store cell values to Object

I'm currently new to TestNG using java. I'm trying to read the values from an excel using poi apache 4.0
public static void read2dRowExcelFile2(String filePath) throws IOException {
try {
FileInputStream fis = new FileInputStream(new File(filePath));
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheet("PerLocation");
Object[][] tableArr = new String[sheet.getLastRowNum() + 1][];
int arrNo1 = 0;
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
int arrNo2 = 0;
for (int j = 0; j < row.getLastCellNum(); j++) {
String cellValue = row.getCell(j).getStringCellValue();
System.out.println(acellValue);
//tableArr[arrNo1][arrNo2] = cellValue;
System.out.println("test");
arrNo2++;
}
arrNo1++;
}
wb.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Code above displays the values on the console. My goal is to store those values to an Object. Something like [{London, Blue},{Tokyo,Yellow},{Manila,Red}] so I can pass them to a dataProvider
If I run the code above, it displays :
London
BLue
Tokyo
Yellow
Manila
Red
But If i uncomment this line :
//tableArr[arrNo1][arrNo2] = cellValue;
The output is only :
London
03-08-19 : After I enabled stacktrace, it says : java.lang.NullPointerException
which pertains to this code :
tableArr[arrNo1][arrNo2] = cellValue;
From your code,
Object[][] tableArr = new String[sheet.getLastRowNum() + 1][];
At the time of initialization of array, your are setting size of first dimension but not the second . You need to initialize array for second dimension before you access it.
Refer below example:
public static void main(String[] args) {
//read rows size
int numOfRows = 3;
String[][] tableArr = new String[numOfRows][];
for (int row = 0; row <3; row++) {
//read columns size
int numOfColsInRow = 3;
tableArr[row]=new String[numOfColsInRow];
for (int col = 0; col < 3; col++) {
String cellValue = "cell-" + row+""+col;//read cell value
tableArr[row][col] = cellValue;
}
}
for(String[] row: tableArr) {
System.out.println(Arrays.toString(row));
}
}
Running above code with generate expected output:
[cell-00, cell-01, cell-02]
[cell-10, cell-11, cell-12]
[cell-20, cell-21, cell-22]
To reproduce your problem you can try commenting line which initialize array for second dimension in the code and you will see Exception in thread "main" java.lang.NullPointerException
.
//tableArr[row]=new String[numOfColsInRow];
To avoid all such issues you also can check if any exiting TestNG data-provider extension satisfies your need.

parser.getTokens() gives out junk data and singlecharacters PDFBox-1.8.9 version

I am new to pdfbox. I am using pdfbox-app-2.0.0-RC1 version to fetch the entire text from the pdf using PDFTextStripperByArea. Is it possible for me to get each string separately?
For Example,
In the following text,
Nomination : Name&Address
Shipper : shipper name
I need Nomination as seperate string and "Name&Address" as separate string. Instead I am getting each character separately. I have tried with different Pdfs. For most pdfs I am able to get the exact string but for few pdfs I don't.
I am using the following code to get the separate string.
for (PDPage page : doc.getPages()) {
PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List<Object> tokens = parser.getTokens();
for (int j = 0; j < tokens.size(); j++) {
Object next = tokens.get(j);
if (next instanceof Operator) {
Operator op = (Operator) next;
if (op.getName().equals("Tj")) {
COSString previous = (COSString) tokens.get(j - 1);
String string = previous.getString();
System.out.println("string1===" + string);
if (string.contains("Plant")) {
int size = al.size();
al.add(string);
stop = false;
continue;
}
if (!string.contains("_") && !stop) {
if (string.contains("Nomination")) {
stop = true;
} else {
al.add(string);
}
}
} else if (op.getName().equals("TJ")) {
COSArray previous = (COSArray) tokens.get(j - 1);
for (int k = 0; k < previous.size(); k++) {
Object arrElement = previous.getObject(k);
if (arrElement instanceof COSString) {
COSString cosString = (COSString)arrElement;
String string = cosString.getString();
System.out.println("string2====>>"+string);
al.add(string);
}
}
}
}
}
}
I am getting the following output:
string2====>>Nom
string2====>>i
string2====>>na
string2====>>t
string2====>>i
string2====>>on
string1===
string2====>>(
string2====>>T
string2====>>o
string1===
string2====>>Loa
string2====>>di
string2====>>ng
string1===
string2====>>Fa
string2====>>c
string2====>>i
string2====>>l
string2====>>i
string2====>>t
string2====>>y
string2====>>)

Sending emails from a spreadsheet

I grabbed this script from: https://developers.google.com/apps-script/articles/sending_emails
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 3)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var emailSent = row[2]; // Third column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
I'm wondering if I would be able to make a dynamic subject line (per email). Is that possible?
Thank you!
James
Sure. Assuming that you put the value of the subject in the next column (D from you example), just do something like the following:
// This constant is written in column C for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 3)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var emailSent = row[2]; // Third column
var subject = row[3];
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 3).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}