How to copy/write particular row using apache poi - java

I know i am missing the main function here. I want to copy/ write only particular row from my source excel to destination excel using apache POI.
eg. My source excel has 10 rows. I need only 5th row to be copied to my destination excel.
My class,
public class Test1 {
public static void main(String[] args) throws Exception{
File srcFile=new File("C:\\Test\\Read.xlsx");
FileInputStream fis=new FileInputStream(srcFile);
XSSFWorkbook wb=new XSSFWorkbook(fis);
XSSFSheet sheet1=wb.getSheetAt(0);
File desFile=new File("C:\\Test\\Write.xlsx");
FileOutputStream fout=new FileOutputStream(desFile);
wb.write(fout);
wb.close();
}
}

As per the Apache POI docs, you can use the XSSFSheet.getRow(int) method to get a row at a specific index.
// 5th row
Row row = sheet.getRow(4);
To add this row to a new workbook, you'll have to iterate through each cell in the row object and set the value of cells in the new workbook to these values. An example can be found here.

Related

Apache POI setCellData not actually setting cell data

Using Apache POI 3.16
Eclipse IDE neon 3
Selenium 3.4 (not that it matters in this case)
I'm having an issue with writing values to an excel spreadsheet then reading back the value.
Here's what I want to do at a high level:
Open up an excel file
write to row 1 column 1 (we are using index starting at 0)
Read back what was written in that cell.
The cell contains the value "B2". In a setCellData() function, I write to the cell a "Hello World" and have the function return the contents of the cell. I also have a separate function that reads in the contents of a specified cell.
When I run the following code:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
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 Udemy_Excel_Driven {
public static XSSFWorkbook wb;
public static XSSFSheet sheet;
public static XSSFRow row;
public static XSSFCell cell;
public static FileInputStream fis;
public static void main(String[] args) throws IOException, Exception
{
System.out.println("Before cell edit value is:");
System.out.println(getCellData(1,1));
String value = setCellData(1,1,"Hello World");
System.out.println("What's the value after setting it with setCellData()?");
System.out.println(value);
System.out.println("What's the value using getCellData()?");
System.out.println(getCellData(1,1));
}
public static String getCellData(int rowNum, int colNum) throws IOException
{
/*
* Hierarchy of excel data:
*
* Workbook - take control of this
* Sheet - pick up the sheet of the workbook
* Row - pick the row
* Column - after picking the row, select the column
* Value - grab the value from the cell
*
*/
//0. = identify the path to the excel file in the system.
fis = new FileInputStream("C:\\data.xlsx");
//1. Create a new XSSFWorkbook object. You need to pass in a FileInputStream object into it, which you created earlier.
wb = new XSSFWorkbook(fis);
//2. Get the sheet in the workbook. Create a new XSSFsheet object and set it to the sheet in the workbook
// Access the workbook method "getSheet" and pass in the name of the sheet
sheet = wb.getSheet("script");
//3. Get the row and column. We are going to access the data from row 2 column 2. And remember the indices start at 0.
row = sheet.getRow(rowNum);
cell = row.getCell(colNum);
//get the value specified in the row and cell
return cell.getStringCellValue();
}
public static String setCellData(int rowNum, int colNum, String data) throws IOException
{
fis = new FileInputStream("C:\\data.xlsx");
wb = new XSSFWorkbook(fis);
sheet = wb.getSheet("script");
row = sheet.getRow(rowNum);
cell = row.getCell(colNum);
cell.setCellValue(data);
String cellData = cell.getStringCellValue();
return cellData;
}
I get the following output:
Before cell edit value is:
B2
What's the value after setting it with setCellData()?
Hello World
What's the value using getCellData()?
B2
I don't think the write actually occurred since I opened up the excel file and the "Hello World" string wasn't in the specified cell. Any answers to this issue?
I don't see any part of your code that actually writes to your file.
It should more or less look something like this:
FileOutputStream fileOut = new FileOutputStream("C:\\data.xlsx");
wb.write(fileOut);
fileOut.close();
You can also consult this guide for this issue as well as other functionality that you might be interested in implementing.

Get the computed value of a formula in Excel using Apache POI 3.14

Update 2: Well for some reason I completely forgot to mention that the cell I am trying to access is actually summing up cells that contain formulas themselves. These cells contain a SUMIF formula as such:
=SUMIF('Sheet1'!B2:B4,DATE(2016,8,31),'Sheet1'!E2:E4)
So my reasoning was that I had to evaluate these cells before evaluating the actual cell I need, and this is where the FormulaEvaluator isn't working correctly. In other words, the simple SUM function is evaluating as intended, but is mistakenly summing up 0.0 from the cells containing the SUMIF functions. I tried using evaluator.sumInCell() every time I would update a cell containing the SUMIF function, but that is evaluating into 0.0 as well.
Does it have to do with the libraries not supporting the SUMIF function? Or maybe I should change the condition?
=========================================================================
Update: Okay so I only managed to get the correct value by manually opening the excel file and then closing it right after. I would get a prompt to save my changes to the file when in fact I made none. I imagine there's something wrong with how I am generating and manipulating the file.
private void createDataFile(File dataFile) throws IOException {
FileOutputStream fos = new FileOutputStream(dataFile);
XSSFWorkbook workBook = new XSSFWorkbook();
//
// Code to create and populate rows and cells
//
workBook.write(fos);
fos.close();
}
private void updateSheet(File dataFile) throws IOException {
Workbook workBook = WorkbookFactory.create(new FileInputStream(dataFile));
Sheet sheet = workBook.getSheet(0);
//
// Code to update and manipulate cells
//
FileOutputStream fos = new FileOutputStream(dataFile);
workBook.write(fos);
fos.close();
}
Note: I am only able to read the value through cell.getNumericCellValue(), FormulaEvaluator still doesn't work either way.
=========================================================================
Hello I am trying to read a value computed using a formula in an excel sheet.
The formula is a simple sum function as follows: SUM(B2:B6).
Using Apache POI 3.14 libraries, I came up with the following snippet of code:
public Double getCellValue() throws IOException, InvalidFormatException{
Workbook workBook = WorkbookFactory.create(new FileInputStream(new File("data.xlsx")));
Sheet sheet = workBook.getSheetAt(0);
// i only need one specific cell, at the last row in my sheet
Row row = sheet.getRow(sheet.getLastRowNum());
Cell cell = row.getCell(1);
// this is where I am stuck
FormulaEvaluator evaluator = workBook.getCreationHelper().createFormulaEvaluator();
CellValue cellValue = evaluator.evaluate(cell);
return cellValue.getNumberValue();
}
I made sure that I am targeting the correct cell, however this method returns 0.0 instead of the correct computed value.
I initially tried a different approach using cell.getNumericCellValue() instead of FormulaEvaluator, however that was giving me the same incorrect result, 0.0.
After going through the documentation online, I failed to find an explanation to my problem, any insight on the matter would be greatly appreciated.
Cheers.
With
This works for me:
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
public final class Demo {
public static void main(final String[] args) throws Exception {
System.out.println(getCellValue());
}
public static Double getCellValue() throws Exception {
final Workbook workBook = WorkbookFactory.create(new FileInputStream(new File("data.xlsx")));
final Sheet sheet = workBook.getSheetAt(0);
// i only need one specific cell, at the last row in my sheet
final Row row = sheet.getRow(1);
final Cell cell = row.getCell(0); // formula in A2
System.err.println(cell.getCellFormula());
// this is where I am stuck
final FormulaEvaluator evaluator = workBook.getCreationHelper().createFormulaEvaluator();
final CellValue cellValue = evaluator.evaluate(cell);
return cellValue.getNumberValue();
}
}
output:
SUM(B2:B6)
15.0
So I assume there is some issue with your way to get the cell, or the xlsx content. Using a debugger, you should be able to figure out whats wrong

Apache POI getRow() returns null and .createRow fails

I have the following problem using Apache POI v3.12:
I need to use a XLSX file with 49 rows [0..48] as a template, fill it's cells with data and write it out as a different file, so I can reuse the template again. What I am doing is approximately this:
XSSFWorkbook wbk_template = new XSSFWorkbook(new FileInputStream (f_wbk_template));
SXSSFWorkbook wbk = new SXSSFWorkbook(wbk_template, 50, true);
Sheet sheet = wbk.getSheet(STR_SHEET_NAME);
/ later on/
Row row = sheet.getRow(rownum);
if (null == row) {
row = sheet.createRow(rownum);
}
Upon debugging it turns out that getRow() returns null, but the attempt to .createRow() fails with:
java.lang.IllegalArgumentException: Attempting to write a row[2] in the range [0,48] that is already written to disk.
at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:122)
...
am I missing something here? As far as I have read in the Apache docs and forums, I need to createRow() if getRow() returns null. The sheet does not contain any rows according to .getPhysicalRows(), .getFirstRowNum() and .getLastRowNum()
Thanks.
See the documentation for the SXSSFWorkbook constructor that takes the XSSFWorkbook as param. You cannot override or access the initial rows in the template file. You are trying to overwrite an existing row and the API does not support this. Your exception message reflects this.
https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html#SXSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook)
For your use case, you may want to try http://jxls.sourceforge.net.
If you want to read or edit an exist row, you can firstly do it in xssf type, and then create the sxssf file base on the xssf file.
The code is something like below...
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream(file));
//do the read and edit operation with xssf......
......
......
SXSSFWorkbook sXSSFbook = new SXSSFWorkbook(xssfWorkbook);
//do the write operation with sxssf......
......
......
Please have a look at this constructor arguments
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(exportExcelTo));
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook, -1, Boolean.FALSE, Boolean.TRUE);

Creating new sheet using Apache POI removes all the existing sheets

I trying to add new sheet to an existing excel file using Apache poi library as in the below code.
FileOutputStream fileOut = new FileOutputStream(new File(BASE_PATH+outputFile));
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Splitted Rules");
Set<String> tags = outputRules.keySet();
int i = 0;
for (String tag : tags) {
List<String> rules = outputRules.get(tag);
for (String rule : rules) {
Row row = sheet.createRow(i++);
row.createCell(0).setCellValue(tag);
row.createCell(1).setCellValue(rule);
}
}
wb.write(fileOut);
fileOut.close();
wb.close();`
The problem is that all the sheets in the file is deleted and only the new sheets exist.
What is this problem ?
The comments already hint at the solution.
The code above creates a new workbook and overwrites any existing file.
If you want to append a sheet to an existing workbook use the WorkbookFactory.create method (or the XSSFWorkbook constructors with the appropriate argument) to create the workbook based on the existing excel file.

Reading data from xlsx with Apache POI's SXSSFSheet

I want to read data ( cell values ) from a certain xlsx file using apachi poi.
The code below creates the SXSSFWorkBook instance successfully and assigns db.xlsx ( my dummy xlsx). I have tried changing sheet numbers and double checking it with the getSheetNumber method to make sure the workbook is correctly assigned.
Next I want to assign a specific sheet (index 0 with name main) to SXSSFSheet instance, but currently it returns null. (I have both tried getSheetAt and getSheet methods).
SXSSFRow DummyRow;
SXSSFCell DummyCell;
int RowCount;
OPCPackage pkg = OPCPackage.open(blabla string adress);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
Workbook MainBook = new SXSSFWorkbook(wb,100);
int a = MainBook.getNumberOfSheets();
SXSSFSheet MainSheet = (SXSSFSheet) MainBook.getSheetAt(0);
RowCount = MainSheet.getLastRowNum();
What am I doing wrong?
Edit:
I have tried getSheetName method and had a positive result. So the problem is with reaching rows in Worksheet. so, the last line getLastRowNum() is not working.
You can't. SXSSFWorkBook is write only, it doesn't support reading
For low memory reading of .xlsx files, you should look at the XSSF and SAX EventModel documentation

Categories