Apache POI - Allow calculation with time strings - java

I have an excel sheet which contains some time values. These values are Durations formatted to Strings. When I try to do a sum on those values I get a 0 as result since Excel can't do sums on Strings. When I hit the enter button in the formula bar it does become a time so I the sum works. How do I change the value of the cell from a String to a time value? I already have the date format set up as [hh:mm] with a DateFormat
I start with an amount of time converted into seconds which I convert into a Duration
Duration clockedDuration = Duration.ofSeconds(clockedSeconds)
Then I format the Duration to a String using DurationFormatUtils
DurationFormatUtils.formatDuration(duration.toMillis(), "HH:mm", true)
Then I set the cell value to the String that was just made
c.setCellValue(clockedDuration)
I then set the CellStyle to one that has a DataFormat that's set up as [hh]:mm
Lastly I make a sum of all the values in that particular column (B in this instance)
c = r.createCell(i++)
c.setCellFormula("SUM(B2:B" + lastRow +")")
c.setCellType(Cell.CELL_TYPE_FORMULA)
This is the sheet before I hit the enter button on the first value in the row (09:52)
This is the sheet after I've hit the enter button in the formula bar

I fixed it by dividing the seconds by 86400 to get a decimal value and then use [hh]:mm as the data format.
c.setCellValue(clockedSeconds / 86400) // 24(hours) * 60(minutes) * 60(seconds) = 86400

Just a hunch: you mentioned to actually use formulas, and if you are hitting enter on the sheet "the sum works". Applying formulas is a two-liner, in addition to set the "value", you also need to format the cell type as being a formula:
XSSFRow row = worksheet.getRow(rowIndex);
XSSFCell cell = row.getCell(cellIndex);
cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula("sum(start:end)");
Edit: You also will want to make sure to use the XSSF-Classes

Related

divide excel sheet based on spesific cell values

i have a data sheet in excel about 950000 row with 7 col.and i want to divide it based on V5 col data. V5 holds data for time in seconds into one hour so i need to divide the data into sheets each sheet contains all value related to one minute and so on until finish splitting
if any help in do it with micro VBA thats will be good.
this is what i could do in VBA
Sub SPLIT()
Dim ws1, ws2 As Worksheet
Dim row2 As Integer
Dim rw As Range
Dim dv, fv As Variant
Set ws1 = Sheets("sheet1")
Set ws2 = Sheets.Add
row2 = 1
For Each rw In ws1.Rows
If rw.Cells(1, 5).Value2 = 00:00:59 Then " and so on until i divide each minute data rows alone"
Exit For
End If
So I've put something together for you that will get you started. You'll likely have to adjust the code for the exact time bounds that fit your requirement (which will be a good learning oppurtunity!). Note that you can take an approach of setting these bounds as either fixed or variable (i.e.: increments of minutes/seconds/hours, or the fixed bounds I have now)
To set this up you'll need three sheets in your workpaper named (1) Hours, (2) Minutes, and (3) Seconds.
As the code is set up the rows get sorted and placed into bounds depending on if it's under one minute, under one hour, or greater than one hour.
Take a stab at adjusting the code to your exact requirements and if you have any questions feel free to let me know!
Function Last_Row(Sheet_Name As String)
Last_Row = Sheets(Sheet_Name).Range("A" & Sheets(Sheet_Name).Rows.Count).End(xlUp).Row
End Function
Sub AllocateSheet()
Dim Cell As Variant
Dim Cell_Range As Range
Set Cell_Range = Range("E2:E990000")
Seperator_Second = TimeValue("00:00:01")
Seperator_Minute = TimeValue("00:01:00")
Seperator_Hour = TimeValue("01:00:00")
For Each Cell In Cell_Range
If Cell.Value >= Seperator_Hour Then
Rows(Cell.Row).Copy Destination:=Sheets("Hours").Rows(Last_Row("Hours") + 1)
ElseIf Cell.Value <= Seperator_Hour And Cell.Value >= Seperator_Minute Then
Rows(Cell.Row).Copy Destination:=Sheets("Minutes").Rows(Last_Row("Minutes") + 1)
ElseIf Cell.Value <= Seperator_Minute And Cell.Value >= Seperator_Second Then
Rows(Cell.Row).Copy Destination:=Sheets("Seconds").Rows(Last_Row("Seconds") + 1)
End If
Next Cell
End Sub
I reach into deviding minutes uisng this code any help in edit this code so i can divide the total rows in the sheet about 1000000 row also the code make the loop only to 60000 row in E colunm. I dont know why it just took from 1 to 6000 E1:E6000 and make a loop on 60000 row any help. also how i can craete new sheet to
paste to it inside code.
Option Explicit
Sub Test()
ti=TimeValue("00:00:00")
Dim Cell As Range
With Sheets(1)
For Each Cell In .Range("E1:E6000" & .Cells(.Rows.Count, "E").End(xlUp).Row)
If Cell.Value <= ti Then
.Rows(Cell.Row).Copy Destination:=Sheets("first minute").Rows(Cell.Row)
End If
Next Cell
End With
End Sub

Insert fraction as text to Excel with Aspose library

I need to generate column where some values are fractions. In this case Excel display this value as calculated value or even as a date(for preparing screenshot I manually added space).
I see the solution as applying function:
=TEXT(value, \"0/#0\")
So, my question is how to apply function to cell using java Aspose library? Does it is the best solution?
Well, this is MS Excel's behavior which converts the fraction values to DateTime or numeric (calculated) values. You may easily cope with it via applying numbers formatting to your specified cells. See the sample code with comments for your reference on how to display fraction values in the cells using Aspose.Cells for Java. Also, see the code on how to apply formula to cells:
e.g
Sample code:
Workbook workbook = new Workbook();
//Get the first worksheet (default sheet)
Worksheet worksheet = workbook.getWorksheets().get(0);
Cells cells = worksheet.getCells();
//Input fraction values to the cells.
Cell cell1 = cells.get("A1");
double val1 = 1/2d;
cell1.putValue(val1);
Cell cell2 = cells.get("A2");
double val2 = 19/4d;
cell2.putValue(val2);
Cell cell3 = cells.get("A3");
double val3 = 5/3d;
cell3.putValue(val3);
//Create a style object.
Style style = workbook.createStyle();
//Set the numbers formatting
style.setCustom("# ?/?");
//Apply style to the cells.
cell1.setStyle(style);
cell2.setStyle(style);
cell3.setStyle(style);
//Apply formula to a cell
Cell cell4 = cells.get("B1");
cell4.setFormula("=TEXT(A1,\"0/#0\")");
//Even you may directly put numeric value as text value.
Cell cell5 = cells.get("C1");
cell5.putValue("1/2", false);
//Note: if you double cliked in the cell, it will be converted to numeric DateTime notations.
//Save the file
workbook.save("f:\\files\\out1.xls");
Note: I am working as Support developer/ Evangelist at Aspose.

How can we read default cell format from Excel in Apache POI?

public java.text.Format getDefaultFormat(Cell cell).
I am reading values from an Excel cell and storing it in a database.
The code below is not working, it's giving a type mismatch error.
userdata.setTaskid((int)(row.getCell(0).getNumericCellValue()));
System.out.println(userdata.getTaskid());
Following code will give you the cell format and then based on that return integer format you can decide the way to get cell value, e.g. either using getNumericCelValue or getBooleanCelValue etc.
int cellType = row.getCell(0).getCellType();
Blank Value = 3
Boolean Value = 4
Error Value = 5
Formula Value = 2
Numeric Value = 0
String value = 1

Apache POI - get number as integer

Numbers all come back from Apache POI cell values as Double.
When I do getCell(...).toString(), a number that appeared as "123" in Excel will convert to "123.0".
How can I tell that the number should have displayed as an integer? Is there some magic I need to apply in Java to replicate what Excel does with "General" formatting?
Excel stores almost all numbers in the file format as floating point values, which is why POI will give you back a double for a numeric cell as that's what was really there
I believe, though it's not quite clear from your question, that what you want to do is get a String object in Java that contains the number as it would look in Excel? i.e. apply the formatting rules applied to the cell to the raw number, and give you back the formatted string?
If so, you want to do exactly the same thing as in my answer here. To quote:
What you want to do is use the DataFormatter class. You pass this a cell, and it does its best to return you a string containing what Excel would show you for that cell. If you pass it a string cell, you'll get the string back. If you pass it a numeric cell with formatting rules applied, it will format the number based on them and give you the string back.
For your case, I'd assume that the numeric cells have an integer formatting rule applied to them. If you ask DataFormatter to format those cells, it'll give you back a string with the integer string in it.
Edit And for those of you who apparently find clicking through to the JavaDocs to be just that little bit too much work..., you need to use the DataFormatter.formatCellValue(Cell) method. If iterating, you'd do something along the lines of:
Workbook workbook = WorkbookFactory.create(new File("input.xlsx"));
DataFormatter formatter = new DataFormatter();
Sheet s = workbook.getSheetAt(0);
for (Row r : s) {
for (Cell c : r) {
System.out.println(formatter.formatCellValue(c));
}
}
// We create a variable of type Workbook and load the excel for reading the fields.
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream("LIST.xls"));
// Getting the working sheet
HSSFSheet sheet = workbook.getSheetAt(0);
// Getting the working row
HSSFRow row = sheet.getRow(0);
// Store the numeric value on Int var
int d = (int) row.getCell(0).getNumericCellValue();
// Printing the result
System.out.println(d0);
// Close the current workbook
workbook.close();

How to retrieve percentage type value from excel sheet using poi

I am trying to read cell values excel sheet using Apache POI. One of my sheet contains percentage type as the cell type. When I read that cell using POI using cell.getNumbericValue(), its returning me the double value. If cell contains 11.24%, it is returning me 0.1124.
My problem is, I want to read the % symbol also from the cell i.e., I want to read the exact data as it is in cell as 11.24%. So, I tried it using the cell.toString(), even then it is returning me the same value as above.
Can anyone please suggest me, how to get rid of this problem.
Thanks in advance
Nandu
You can detect if a cell is formatted as a percentage by testing the cell data format string like this:
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (cell.getCellStyle().getDataFormatString().contains("%")) {
// Detect Percent Values
Double value = cell.getNumericCellValue() * 100;
System.out.println("Percent value found = " + value.toString() +"%");
} else {
Double value = cell.getNumericCellValue();
System.out.println("Non percent value found = " + value.toString());
}
}
This should enable you to distinguish between percentage formatted values and ordinary numeric values.
11.24% is 0.1124, which is why that's what gets stored in the file, and that's what you get when you ask for the numeric value
POI provides a utility for formatting numeric strings based on the format rules applied to the cell, which is DataFormatter. If you use that to format the cell, you'll get back a string with the contents of the cell largely as seen in Excel.
Try this:
String typeCell =cell.getCellStyle().getDataFormatString();
It gives:
"General" value for non formated cells,
"0%" for percentage formats
dd/mm/yy for date , depends of locale
I manage to parse all types in cells (Numbers, Percentage, Date, Text, Currency) I just have to check what value for which cell type it will give me back.
Because I also have to much trouble with HSSFCell.CELL_TYPE_STRING or HSSFCell.CELL_TYPE_NUMERIC.
The answer of #WeeShetland should be the accepted answer.
Instead of cell.getCellStyle().getDataFormatString().contains("%") you can use
// class level
private static final int PERCENTAGE_FORMAT = BuiltinFormats.getBuiltinFormat("0%");
...
// in some method
if (cell.getCellStyle().getDataFormat() == PERCENTAGE_FORMAT) {
...

Categories