Converting from a double to a String but keeping an leading zeros - java

I am trying to convert from a double to a String. It is working but it is removing all leading zeros. For example, 00010000 is being changed to 10000 and 01 is changed to 1. I am trying to read an xls file and it is proving difficult.
The amount of digits is not known when running the program so I couldn't think of a way to get around this problem. Could anyone help?
Below is my code:
while (cells.hasNext()) {
cell = (HSSFCell) cells.next();
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
lineList.add(cell.getStringCellValue());
} else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
String s = String.valueOf(cell.getNumericCellValue());
lineList.add(s);
}
}

My guess as to what is happening here is that you have numeric data in Excel which is formatted as 00010000. However, internally in Excel this data is probably just stored as 10000 or 10000.0 etc. and the leading zeroes are just present because of your formatting. When you imported this numeric data into Java using HSSF, it also came in as 10000 or 10000.0 etc. As others have already mentioned, there are no "leading" zeroes in a Java double primitive type. So when you convert to a String, of course there are no leading zeroes, because they simply don't exist.
Possible workaround:
If you format your Excel numeric column as text, and then import it, then the following if condition should fire for these values:
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
lineList.add(cell.getStringCellValue());
}
You can then simply read in the text values directly, leading zeroes and all, and retain the information which was present in your Excel spreadsheet.
I have not tested this, but this would probably be something I would try if I were faced with your problem.

Related

format datacell to comma(?)

Hi i want to edit these cells to have a comma instead of a decimal point.
they are exported from my database to a excel sheet, but instead of the decimal point i want a comma
( , )
can anyone help please?
int r = 1;
while (rs.next() )
{
String vpid = rs.getString("VP_ID");
String vtb = rs.getString("partner");
String bs = rs.getString("Bonus");
String bo = rs.getString("Bonus2");
row = sheet.createRow(r++);
row.createCell(0).setCellValue(vpid);
row.createCell(1).setCellValue(vtb);
row.createCell(2).setCellValue(bs);
row.createCell(3).setCellValue(bo);
That question seems to be a good example for a XY problem.
One gets numbers as text values from a database and writes them into a Excel sheet:
...
String bs = rs.getString("Bonus");
String bo = rs.getString("Bonus2");
...
row.createCell(2).setCellValue(bs);
row.createCell(3).setCellValue(bo);
...
Let bs be "123.45" and bo be "67.89", then the Excel cells will contain the texts "123.45" and "67.89" after that instead of the numbers 123.45 and 67.89.
Now one looks at that and uses Excel in a locale which has set comma as the decimal separator instead of dot. The misinterpretation now is, that Excel's interpretation of the numbers as text is because the wrong decimal separator. So one asks how to change the decimal separator.
But the real reason for Excel's interpretation of the numbers as text is because the code really sets text values instead of numbers. The decimal separator is not a format in Excel but only determined by used locale or by a extended application property. If numbers shall be cell contents then the cell value needs to be set using Cell.setCellValue(double value) and not using Cell.setCellValue(java.lang.String value). Using what decimal separator the number then gets showed in the sheet depends on used locale or the extended application property for decimal separator.
So the correct solution is to set the cell values as doubles. Either by doing:
...
row.createCell(2).setCellValue(Double.valueOf(bs));
row.createCell(3).setCellValue(Double.valueOf(bo));
...
But better would be to save the values correctly as numbers in the database and to retrieve them from the database like so:
...
double bs = rs.getDouble("Bonus");
double bo = rs.getDouble("Bonus2");
...
row.createCell(2).setCellValue(bs);
row.createCell(3).setCellValue(bo);
...

Apache POI formulas not evaluating

So I'm having some issues getting Apache POI to evaluate formulas.
Here's the code I call to evaluate formulas before writing:
complete.getCreationHelper().createFormulaEvaluator().evaluateAll();
complete.write(fileOut);
Here's the code I call to write to the cells being used (proving they're numbers):
try{
cell.setCellValue((Double)grid[i][j]);
}
catch(Exception e){
cell.setCellValue((String)grid[i][j]);
}
FYI: grid is a 2D Object array containing only entries of the type double and String.
Here's the formulas I'm trying to evaluate:
"=G13 - H13"
"=STDEV.P(C1:L1)"
"=I13/G13"
Any ideas why when I open up my final workbook in Excel the formulas arn't evaluated? Also, when I click on an unevaluated field and hit enter Excel will recognize the formula and evaluate it. In bulk this isn't practical, but I believe it demonstrates that the cells being used are the correct type. Could this be related to the formulas being of the String type?
EDIT:
OK, so looks like you're supposed to explicitly tell it you have a formula cell. Here's my modified code to do that:
try{
cell.setCellValue((Double)grid[i][j]);
}
catch(Exception e){
String val = (String) grid[i][j];
if (val != null && val.startsWith("=")){
val = val.replaceAll("=", "");
cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula(val);
}
else{
cell.setCellValue(val);
}
}
Unfortunately you need to remove the equals sign (which is dumb) to pass formulas and then force it to reevaluate before saving (which is dumb). After trying to get it to reevaluate formulas it complained, however, saying:
Caused by:
org.apache.poi.ss.formula.eval.NotImplementedFunctionException:
STDEV.P
I'm imagining that this means Excel has implemented standard deviation calculations but POI hasn't caught up yet?
Try this:
XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
or, if you are using xls
HSSFFormulaEvaluator.evaluateAllFormulaCells(hssfWorkbook)
You probably want to call this just before saving.

Using POI Set Cell Style Based on Cell Formula Result

I need some help on setting the cell style base on the cell value.
The code used to populate cell.
String totalvariationweightv1 = "J" + (x+1);
String totalvariationweightv2 = "L" + (x+1);
cell85014.setCellType(Cell.CELL_TYPE_FORMULA);
cell85014.setCellFormula("SUM(((" + totalvariationweightv2 + "-" + totalvariationweightv1 + ")/" + totalvariationweightv1 + ")*100)");
Then I need to color the field if it exceeds a certain value. Right now I just have alternating colors:
cell85014.setCellStyle((x%2)==0?stylefloatGray:stylefloat);
I cannot figure out how to get the cell value. Using getNumericValue returns 0.
Apache POI stores the formula, but it doesn't evaluate it automatically.
The Excel file format (both .xls and .xlsx) stores a "cached" result for every formula along with the formula itself. This means that when the file is opened, it can be quickly displayed, without needing to spend a long time calculating all of the formula results. It also means that when reading a file through Apache POI, the result is quickly available to you too!
After making changes with Apache POI to either Formula Cells themselves, or those that they depend on, you should normally perform a Formula Evaluation to have these "cached" results updated. This is normally done after all changes have been performed, but before you write the file out.
You must tell Apache POI to evaluate the formula separately.
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
// Set your cell formula here
switch (evaluator.evaluateFormulaCell(cell85014)) {
case Cell.CELL_TYPE_NUMERIC:
double x = cell85014.getNumericCellValue();
// Set cell style here, based on numeric value,
// as you already are doing in your code.
// Watch out for floating point inaccuracies!
break;
default:
System.err.println("Unexpected result type!");
break;
}

Reading excel using POI HSSFCell with leading zeros [duplicate]

This question already has answers here:
How can I read numeric strings in Excel cells as string (not numbers)?
(24 answers)
Closed 8 years ago.
I am trying to read an excel file using Java POI HSSF. Everything was working fine, except that when the value is 001001 the HSSFCell will return 1001.0
Is there any way I can use HSSFCell to get the value 001001 ?
I am not supposed to do any modification to the excel file.
Thank in advance for any help and suggestion.
Edit
I have been using the following code:
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.toString();
I also ran a debug mode and checked on the cell value the moment the HSSF grabs it. It truncate the leading zeros and converted it to double therefore I do not see a way to retrieve the truncated zeros. There is a link that stated it could be a bug from HSSF:
http://osdir.com/ml/jakarta.poi.user/2003-02/msg00007.html
By the way, I solved it by hard coded it. The number of digits are know in advanced. The link for the code that I used: How to format a Java string with leading zero?
Can you try reading it as a string instead of Numeric,
cell.setCellType(Cell.CELL_TYPE_STRING);
Changing the cell type usually will not modify the contents of the cell.
it can be retrieved with either of the following approaches:
cell.getStringCellValue();
cell.getRichStringCellValue().getString();

Apache POI formula cell duplication very slow

I'm generating an excel file using Apache POI 3.8 , and have the need to replicate some existing row n° times.
This because I have some complex formula which I use as a template to create new lines, replacing cell indexes with regexps.
The problem is that performance are awful, it takes 2h to generate some 4000 rows.
I've pinpointed the problem to be not in the regexp part, as I initially thought, but in the duplication of formula cells.
I actually use this to replicate formula cells:
case Cell.CELL_TYPE_FORMULA:
newCell.setCellType(oldCell.getCellType());
newCell.setCellFormula(oldCell.getCellFormula());
break;
If I copy the formula as text like this:
case Cell.CELL_TYPE_FORMULA:
newCell.setCellType(Cell.CELL_TYPE_STRING);
newCell.setCellValue("="+oldCell.getCellFormula());
break;
it's instead pretty fast, even with my regexp in place.
Anyway, this is an imperfect solution, because the formula has english keywords (ie IF()), when I need to write in italian format.
More, cells with formula inserted like that need to be forcefully re-evaluated in excel with something like "replace all -> '=' with '='".
The problem seems to rely in the setCellFormula(), because of the HSSFFormulaParser.parse().
What's strange, is that parsing time seems to grow exponentially:
100 rows -> 6785ms
200 rows -> 23933ms
300 rows -> 51388ms
400 rows -> 88586ms
What it seems, is that each time I copy a formula, the POI library re-evaluates or re-parses or re-something all preceding rows.
Do anyone know how can solve this problem?
Thanks in advance.
Oh my...I think I found it...
Original was:
// If the row exist in destination, push down all rows by 1 else create a new row
if (newRow != null) {
worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
} else {
newRow = worksheet.createRow(destinationRowNum);
}
I've commented everything leaving only
newRow = worksheet.createRow(destinationRowNum);
And now I'm down to 60sec to process all rows!
Probably, there's some dirt in my template which was causing POI to shift everything at each iteration.

Categories

Resources