How can I append the existing table? - apache-poi

As I'm working on an automated data-collector and writer, I am using POI (4.1) to append an existing Excel-File .xlsx
Everything is fine so far, until I realized that the Excel I'm writing to and reading from includes a "Table" from the automated data Import. That means the last Line where I have to append is the last line of the imported table but i want to append the table.
I heared sth about spreadsheets but I'm not concerend that this will solve my problem as I didn't understand it that well.
I tried to enlarge the Table in Excel to write to it but I found out, that the Last line of the table, wether it contains sth or not, is used as the last existing line.
/**This Method is is building the XSSFRow out of the String[] array. It works fine, as the Stream
* is just in another method*/
private void schreibeInWorkbook(String[] zuSchreiben)
{
XSSFSheet worksheet = workbook.getSheetAt(findSheet(zuSchreiben[1]));
int lastRow = worksheet.getLastRowNum();
XSSFRow row = worksheet.createRow(++lastRow);
int cellnum = 0;
for (Object obj : zuSchreiben)
{
try
{
obj = Double.parseDouble((String) obj);
}
catch (NumberFormatException e)
{
}
Cell cell = row.createCell(cellnum++);
if (obj instanceof String)
{
obj = ((String) obj).replaceAll("\"", "");
cell.setCellValue((String) obj);
}
else if (obj instanceof Double)
{
cell.setCellValue((Double) obj);
}
else if (obj instanceof Integer)
{
cell.setCellValue((Integer) obj);
}
}
int r = row.getRowNum();
Cell c2 = row.createCell(cellnum++);
c2.setCellFormula(formulaXYZ);
Cell c3 = row.createCell(cellnum++);
c3.setCellFormula(formulaXYZ);
}
I thought I could just expand the Excel Table by Hand and add it in there but it always appears in the next line right after the end of it although there are tons of empty lines.
This is what my JavaCode is adding to Excel

Related

How to read specific column one by one till the defined column number?

I have existing codes that work to get a particular cell from an excel sheet.
I have input data in excel sheet from cell C2 till cell T2.
Current codes allowed me to read cell C2 once.
I wanted to make it automatically read C2, D2, E2, ..... till T2
Codes:
public String ReadCellData(int vRow, int vColumn)
{
String value=null; //variable for storing the cell value
Workbook wb=null; //initialize Workbook null
try
{
//reading data from a file in the form of bytes
FileInputStream fis=new FileInputStream(RunConfiguration.getProjectDir() + "/Data Files/testmatrix.xlsx");
//constructs an XSSFWorkbook object, by buffering the whole stream into the memory
wb=new XSSFWorkbook(fis);
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e1)
{
e1.printStackTrace();
}
Sheet sheet=wb.getSheetAt(0); //getting the XSSFSheet object at given index
Row row=sheet.getRow(vRow); //returns the logical row
Cell cell=row.getCell(vColumn); //getting the cell representing the given column
//value=cell.getStringCellValue(); //getting cell value
//return value; //returns the cell value
}
}
codes to get and print data
//read excel cell C2, ignore first row column A1. (int vRow, int vColumn)
def exceldata = CustomKeywords.'test.readexcel.ReadCellData'(2, 2)
String jsondata = JsonOutput.prettyPrint(exceldata.toString())
println(jsondata)
WebUI.delay(1)
//call the object and post the above data as API HTTP request body
def post = ((findTestObject('Object Repository/Web Service Request/test-service/Post')) as RequestObject)
post.setBodyContent(new HttpTextBodyContent(jsondata))
WebUI.delay(2)
//POST and verification
def response = WS.sendRequestAndVerify(post)
println(response.statusCode)
assert response.getStatusCode() == 201
Use the For loop and iterate the loop and get the value
Example
def exceldata="";
for(int row =1;row<=2;row++)
{
for(int col=1;col<=5;col++)
{
exceldata = CustomKeywords.'test.readexcel.ReadCellData'(row,col)
}
}

Datagrid gives null values using for loop in WPF

I have a dataGrid with more than 100 rows in it. I am extracting it to an existing Excel file. I can open the file and add values to the sheet. My problem is, the value becomes null as soon as it gets to the 14th row.
I tried reversing the order of the data in the datagrid just to be sure that it's not the value or data in the dataGrid that is causing the issue but I still get the same result. Only the first 13 rows are extracted to the Excel sheet. The for loop still goes to the rest of the loop but it seems to not get the values.
Here is my code:
var path = #"D:\Reports\Sample.xlsx";
var excel = new Excel.Application {Visible = true};
var wb = excel.Workbooks.Open(path);
var ws = (Excel.Worksheet)wb.Sheets["summary"];
for (var i = 0; i < Grid.Columns.Count; i++)
{
for (int j = 0; j < Grid.Items.Count; j++)
{
var b = Grid.Columns[i].GetCellContent(Grid.Items[j]) as TextBlock; =====> ON THE 14th ROW, the "b" variable becomes null all throught out the for-loop
var myRange = (Range)ws.Cells[j + 2, i + 1];
try
{
if (b != null) myRange.Value2 = b.Text;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(100);
}
}
This is the Excel file created. Values are not extracted any more after the 14th row.

Apache POI not getting all rows and columns from a spreadsheet

I am creating a test framework using selenium, testNG, and Apache POI. So far I have created a piece of code that will get each row from my spreadsheet and insert it into the test. However, on adding a new row it simply ignores the added row. Any help is greatly appreciated.
Code for getting inputs:
#DataProvider(name="ExcelData")
public Object[][] passData() {
ExcelDataConfig config = new ExcelDataConfig("C:\\Users\\dindo\\Documents\\tests\\d2c-lv-int-01_DATA.xlsx");
int rows = config.getRowCount(0);
int frows = rows-2;
Object[][] data = new Object[frows][11];
for(int i=2;i<rows;i++)
{
data[i-2][0]=config.getStrData(0, i, 0);
data[i-2][1]=config.getIntData(0, i, 1);
data[i-2][2]=config.getIntData(0, i, 2);
data[i-2][3]=config.getStrData(0, i, 3);
data[i-2][4]=config.getStrData(0, i, 4);
data[i-2][5]=config.getStrData(0, i, 5);
data[i-2][6]=config.getIntData(0, i, 6);
data[i-2][7]=config.getIntData(0, i, 7);
data[i-2][8]=config.getIntData(0, i, 8);
data[i-2][9]=config.getStrData(0, i, 9);
data[i-2][10]=config.getStrData(0, i, 10);
}
return data;
}
Code for Excel sheet:
public ExcelDataConfig(String excelPath) {
try {
File src = new File(excelPath);
FileInputStream fis = new FileInputStream(src);
wb = new XSSFWorkbook(fis);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public String getStrData(int sheetNumber,int row, int col) {
Details = wb.getSheetAt(sheetNumber);
String strdata = Details.getRow(row).getCell(col).getStringCellValue();
return strdata;
}
public String getIntData(int sheetNumber,int row, int col) throws NullPointerException{
Details = wb.getSheetAt(sheetNumber);
double doubledata = Details.getRow(row).getCell(col).getNumericCellValue();
int intdata = (int) doubledata;
String strdata = Integer.toString(intdata);
return strdata;
}
public int getRowCount(int sheetIndex)
{
int row = wb.getSheetAt(sheetIndex).getLastRowNum();
return row;
}
Also, is it possible to merge getIntData and getStrData into one function which automatically knows if it is a string or integer.
Many Thanks in advance.
After some extensive keyboard thrashing I finally worked out the chink. It was simply that as Apache POI gets the first row in an xlsx file as 0, there was 1 to less rows in the array. Stupidly enough I found this out by accidentally saving my sheet with an extra letter in the row below the last.😂

I want to get some particular cell from excel using selenium webdriver

I am working with excel file with selenium webdriver. I can read the data from excel successfully but I want to get some particular Cell address and value from excel sheet using selenium webdirver.
Can anyone help on this?
Thanks in Advance.
Here is the Code.
String FilePath="D:\\ProUtility_Automation\\Transformation Logic.xls";
try {
Workbook wrk1 = Workbook.getWorkbook(new File(
FilePath));
Sheet sheet1 = wrk1.getSheet(0);
int totalNoOfRows = sheet1.getRows();
int totalNoOfCols = sheet1.getColumns();
//String a[][] = new String[1000][1000];
for (int row = 0; row < totalNoOfRows; row++) {
for (int col = 0; col < totalNoOfCols; col++) {
System.out.print(sheet1.getCell(col, row).getContents() + "\t");
}
System.out.println();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Here is the code for reading particular cell value from excel, please import the right POI jars in your project, so that this code works correctly
private static XSSFCell Cell;
private static XSSFRow Row;
public static String getCellData(int RowNum, int ColNum) throws Exception{
try{
Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
String CellData = Cell.getStringCellValue();
return CellData;
}catch (Exception e){
return"";
}
}
If you want the 2nd row, 3rd column cell value simply pass the parameters getCellData(1,2)---------> excel rows and columns start from (0,0)

POI: Append rows to existing workbook

Using XSSFWorkbook, is it possible to append rows to an existing sheet? I am doing multiple writes (which was a PITA to solve due to a bug) and while I can write out new sheets multiple times, it does not appear that I can append.
What I am currently doing is the following:
Read sheet to my workbook.
Load workbook.
Append rows to workbook in memory
Write out again.
4 Does not appear to work, just ignores it completely!
I am aware that SXSSFWorkbook exists, but attempting to convert my existing XSSFWorkbook into a streaming workbook creates corruption upon write.
Is it possible to solve this concundrum?
Update: Changed code based on suggestion, but getting stream closed error.
Code: (The physical rows returns correctly, but nothing gets written out)
private void writeToSheetMultipleTimes(SXSSFWorkbook wb,
ReportTemplateStructure appA, File wbFile)
{
Sheet sheet = wb.getSheetAt(0);
log.info("Attempting multi-write to sheet: " + sheet.getSheetName());
for(int i = 0; i < 10; i++)
{
Row row = sheet.getRow(i);
if (row == null) {
row = sheet.createRow(i);
}
Cell cell = row.getCell(0, Row.CREATE_NULL_AS_BLANK);
cell.setCellValue("Written value:" + i);
int numRows = sheet.getPhysicalNumberOfRows();
log.info("Current row count: " + numRows);
try{
XSSFWorkbook xssfBook = (XSSFWorkbook)writeOutAndReadBack(wb);
wb.dispose();
wb = new SXSSFWorkbook(xssfBook);
} catch (Exception e)
{
log.error("Unable to perform multiple write to same sheet", e);
}
}
}
public Workbook writeOutAndReadBack(Workbook wb) {
if(!(wb instanceof SXSSFWorkbook)) {
throw new IllegalArgumentException("Expected an instance of SXSSFWorkbook");
}
Workbook result;
try {
FileOutputStream baos = new FileOutputStream(streamingWorkBookFile);
wb.write(baos);
InputStream is = new FileInputStream(streamingWorkBookFile);
result = new XSSFWorkbook(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
return result;
}
You appear to be always making changes to Sheet 0, but you're calling createRow every time. This won't go well if there's already something there, eg on your second pass! You either need to add a new Sheet every time, or check if the Row is there with a call to getRow(int) first and only create if it is null.
If we look at your code snippet:
Sheet sheet = wb.getSheetAt(0);
for(int i = 0; i < 10; i++)
{
Row row = sheet.createRow(i);
Cell cell = row.createCell(0);
That should either be something like:
Sheet sheet = wb.createSheet();
for(int i = 0; i < 10; i++)
{
Row row = sheet.createRow(i);
Cell cell = row.createCell(0);
Or you should check first and only create missing rows/cells, eg
Sheet sheet = wb.getSheetAt(0);
for(int i = 0; i < 10; i++)
{
Row row = sheet.getRow(i);
if (row == null) {
row = sheet.createRow(i);
}
Cell cell = row.getCell(0, Row.CREATE_NULL_AS_BLANK);
You can use getPhysicalNumberOfRows() Method in XSSFSheet class to get last updated row number. Now create a new row by incrementing this value to append new data.

Resources