Reputation: 63
In my Excel file that I am trying to convert using Apache POI, I have a cell that has numeric value as -3.97819466831428 and Custom format as "0.0 p.p.;(0.0 p.p.)". So, in Excel the value that is displayed is "(4.0 p.p.)"
When I convert the same using POI library, I get the output as: "(4.0 p" How can I get the same value as in Excel: (4.0 p.p.) ?
The way I am using DataFormatter is:
val = dataFormatter.formatRawCellContents(cell.getNumericCellValue(), style.getDataFormat(), style.getDataFormatString());
I believe the problem is coming from the usage of "p.p." in the data format string, especially the dots. When I print the data format string from POI using style.getDataFormatString(), I get the format as "0.0\ \p.\p.;(0.0\ \p.\p.\)".
Even if I manually change the format string to use "0.0;(0.0\ \p\.\p\.\)", still its the same result. So, I am out of ideas now. How can I get the full result back from data-formatter like in Excel as "(4.0 p.p.)" ?
Another question that I have is: Is it possible using Apache POI to get the actual displayed value in Excel file? Like in this case, is it possible to get the value "(4.0 p.p.)" directly from Excel without having to apply any data formatting in POI?
Upvotes: 0
Views: 840
Reputation: 61852
This is an error in apache poi
's DataFormatter
while translating the Excel
number format 0.0\ \p.\p.;\(0.0\ \p.\p.\)
into a java.text.Format
. The correct corresponding java.text.Format
would be a new java.text.DecimalFormat("0.0' p.p.';(0.0' p.p.')")
. But apache poi
's DataFormatter
fails to translate this properly.
You should file a bug report to apache poi
about this. In that bug report you should provide a working example (full Java
code and a sample Excel
file) to reproduce the issue.
As a workaround one can tell DataFormatter
how single special Excel
number formats shall be translated. For this use the method DataFormatter.addFormat.
Example:
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
class DataFormatterAddFormat {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelExample.xlsx"));
DataFormatter dataFormatter = new DataFormatter();
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
dataFormatter.addFormat("0.0 p.p.;(0.0 p.p.)",
new java.text.DecimalFormat("0.0' p.p.';(0.0' p.p.')"));
dataFormatter.addFormat("0.0\" p.p.\";\\(0.0\" p.p.\"\\)",
new java.text.DecimalFormat("0.0' p.p.';(0.0' p.p.')"));
dataFormatter.addFormat("0.0\\ \\p.\\p.;\\(0.0\\ \\p.\\p.\\)",
new java.text.DecimalFormat("0.0' p.p.';(0.0' p.p.')"));
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String value = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.println(value);
}
}
workbook.close();
}
}
This is now able correct translating the added special number formats. Of course this is not really the final solution since the need here is to catch all possible Excel
formats which have to be translated. That's why the hint to file a bug report to apache poi.
Btw.: The Excel
format 0.0" p.p.";\(0.0" p.p."\)
would be more general for this. It avoids confusing the dot (.
) in p.p.
with the decimal separator.
To your question about getting the formatted value directly from the Excel
file: This is not possible. All Excel
versions store values and styles separate. Numeric values are always stored as floating point values in double
precision. Number formats for those values are stored in a separate styles section of the file. So best practice to get cell values styled as in Excel
using apache poi
is using DataFormatter.formatCellValue as shown in my code sample.
Upvotes: 1