JAVA Apache POI 自定义格式
JAVA Apache POI Custom Format
我正在使用 poi 版本:3.14
我访问一个 Excel (.xlsx) 文件
this.workbook = WorkbookFactory.create(new FileInputStream(f.getPath()));
this.workbook.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK);
this.sheet = workbook.getSheetAt(0);
这是在应用于单元格的 .xlsx 文件中找到的自定义格式。我想在我的代码中显示单元格值。
如您所见,文件中可见的单元格值为“031642153283700100”。此外,当我点击此特定单元格时,值会更改为“42153283700100”(未应用自定义格式的数据)。
编辑
原始单元格类型是CELL_TYPE_NUMERIC。
==>
如何在 java 代码中显示格式化值“031642153283700100”?
我试过了:
- cell.toString() => "42153283700100"
- cell.getNumericCellValue() => "42153283700100"
之前的细胞类型转换:
cell.setCellType(Cell.CELL_TYPE_STRING);
- cell.getStringCellValue() => "42153283700100"
cell.getRichStringCellValue() => "42153283700100"
带有 formatCellValue(cell) 方法的旧 HSSFDataFormatter => "421532837001000316"
你可以试试这个
row = sheet.getRow(RowNo);
// RowNo on which Row cell should have appeared
cell = row.getCell(CellNo);
// CellNo on which Position cell should have appeared on Row
cell.setCellValue("031642153283700100");
// You could also get CellFormula by using cell.getCellFormula();
对于数字格式,您应该使用 CellGeneralFormatter
或 CellNumberFormatter
。
示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.format.*;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.FileInputStream;
class ReadExcelWithFormats {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String formatstring = cell.getCellStyle().getDataFormatString();
System.out.println(formatstring);
switch (cell.getCellType()) {
//...
case Cell.CELL_TYPE_NUMERIC:
double cellvalue = cell.getNumericCellValue();
System.out.println(cellvalue);
String formattedvalue = "";
if ("general".equals(formatstring.toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstring).format(cellvalue);
}
System.out.println(formattedvalue);
break;
//...
default:
System.out.println();
}
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
编辑
好的,让我们举一个更一般的例子。以上不适用于日期(我已经知道的),但也不适用于所有数字格式。后者我认为 CellNumberFormatter
应该做,但事实并非如此。不幸的是,它甚至会产生某些正确数字格式的错误。
在 Excel
中,数字格式最多可以包含 4 个以分号分隔的部分。第一部分用于大于 0 的数字,第二部分用于小于 0 的数字,第三部分用于等于 0 的数字,第四部分用于文本。
format > 0
;format < 0
;format = 0
;text
由于CellNumberFormatter
不能很好地处理这个问题,所以我们应该在使用CellNumberFormatter
之前处理这个问题。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.format.*;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Date;
class ReadExcelWithFormats {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String formatstring = cell.getCellStyle().getDataFormatString();
System.out.println(formatstring);
switch (cell.getCellType()) {
//...
case Cell.CELL_TYPE_NUMERIC:
String formattedvalue = "";
String[] formatstringparts = formatstring.split(";");
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
System.out.println(date);
String dateformatstring = "";
if (cell.getCellStyle().getDataFormat() == 14) { //default short date without explicit formatting
dateformatstring = "yyyy-MM-dd"; //default date format for this
} else if (cell.getCellStyle().getDataFormat() == 22) { //default short datetime without explicit formatting
dateformatstring = "yyyy-MM-dd hh:mm"; //default datetime format for this
} else { //other data formats with explicit formatting
dateformatstring = formatstringparts[0];
}
formattedvalue = new CellDateFormatter(dateformatstring).format(date);
} else {
double cellvalue = cell.getNumericCellValue();
System.out.println(cellvalue);
switch (formatstringparts.length) {
case 4:
case 3:
if (cellvalue > 0) {
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
if (cellvalue < 0) {
if ("general".equals(formatstringparts[1].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[1]).format(cellvalue);
}
}
if (cellvalue == 0) {
if ("general".equals(formatstringparts[2].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[2]).format(cellvalue);
}
}
break;
case 2:
if (cellvalue >= 0) {
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
if (cellvalue < 0) {
if ("general".equals(formatstringparts[1].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[1]).format(cellvalue);
}
}
break;
default:
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
}
System.out.println(formattedvalue);
break;
//...
default:
System.out.println();
}
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
重要提示:
此代码示例来自 2016 年,适用于 apache poi 3.14
。
从当前的 apache poi
版本 3.17
和 4.x.y
开始,不应再使用它。在当前版本中,这很简单:
...
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
DataFormatter formatter = new DataFormatter();
for (Row row : sheet) {
for (Cell cell : row) {
String formattedvalue = formatter.formatCellValue(cell);
System.out.println("Using DataFormatter: " + formattedvalue);
}
}
...
我正在使用 poi 版本:3.14
我访问一个 Excel (.xlsx) 文件
this.workbook = WorkbookFactory.create(new FileInputStream(f.getPath()));
this.workbook.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK);
this.sheet = workbook.getSheetAt(0);
这是在应用于单元格的 .xlsx 文件中找到的自定义格式。我想在我的代码中显示单元格值。
如您所见,文件中可见的单元格值为“031642153283700100”。此外,当我点击此特定单元格时,值会更改为“42153283700100”(未应用自定义格式的数据)。
编辑
原始单元格类型是CELL_TYPE_NUMERIC。
如何在 java 代码中显示格式化值“031642153283700100”?
我试过了:
- cell.toString() => "42153283700100"
- cell.getNumericCellValue() => "42153283700100"
之前的细胞类型转换:
cell.setCellType(Cell.CELL_TYPE_STRING);
- cell.getStringCellValue() => "42153283700100"
cell.getRichStringCellValue() => "42153283700100"
带有 formatCellValue(cell) 方法的旧 HSSFDataFormatter => "421532837001000316"
你可以试试这个
row = sheet.getRow(RowNo);
// RowNo on which Row cell should have appeared
cell = row.getCell(CellNo);
// CellNo on which Position cell should have appeared on Row
cell.setCellValue("031642153283700100");
// You could also get CellFormula by using cell.getCellFormula();
对于数字格式,您应该使用 CellGeneralFormatter
或 CellNumberFormatter
。
示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.format.*;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.FileInputStream;
class ReadExcelWithFormats {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String formatstring = cell.getCellStyle().getDataFormatString();
System.out.println(formatstring);
switch (cell.getCellType()) {
//...
case Cell.CELL_TYPE_NUMERIC:
double cellvalue = cell.getNumericCellValue();
System.out.println(cellvalue);
String formattedvalue = "";
if ("general".equals(formatstring.toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstring).format(cellvalue);
}
System.out.println(formattedvalue);
break;
//...
default:
System.out.println();
}
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
编辑
好的,让我们举一个更一般的例子。以上不适用于日期(我已经知道的),但也不适用于所有数字格式。后者我认为 CellNumberFormatter
应该做,但事实并非如此。不幸的是,它甚至会产生某些正确数字格式的错误。
在 Excel
中,数字格式最多可以包含 4 个以分号分隔的部分。第一部分用于大于 0 的数字,第二部分用于小于 0 的数字,第三部分用于等于 0 的数字,第四部分用于文本。
format > 0
;format < 0
;format = 0
;text
由于CellNumberFormatter
不能很好地处理这个问题,所以我们应该在使用CellNumberFormatter
之前处理这个问题。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.format.*;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Date;
class ReadExcelWithFormats {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String formatstring = cell.getCellStyle().getDataFormatString();
System.out.println(formatstring);
switch (cell.getCellType()) {
//...
case Cell.CELL_TYPE_NUMERIC:
String formattedvalue = "";
String[] formatstringparts = formatstring.split(";");
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
System.out.println(date);
String dateformatstring = "";
if (cell.getCellStyle().getDataFormat() == 14) { //default short date without explicit formatting
dateformatstring = "yyyy-MM-dd"; //default date format for this
} else if (cell.getCellStyle().getDataFormat() == 22) { //default short datetime without explicit formatting
dateformatstring = "yyyy-MM-dd hh:mm"; //default datetime format for this
} else { //other data formats with explicit formatting
dateformatstring = formatstringparts[0];
}
formattedvalue = new CellDateFormatter(dateformatstring).format(date);
} else {
double cellvalue = cell.getNumericCellValue();
System.out.println(cellvalue);
switch (formatstringparts.length) {
case 4:
case 3:
if (cellvalue > 0) {
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
if (cellvalue < 0) {
if ("general".equals(formatstringparts[1].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[1]).format(cellvalue);
}
}
if (cellvalue == 0) {
if ("general".equals(formatstringparts[2].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[2]).format(cellvalue);
}
}
break;
case 2:
if (cellvalue >= 0) {
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
if (cellvalue < 0) {
if ("general".equals(formatstringparts[1].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[1]).format(cellvalue);
}
}
break;
default:
if ("general".equals(formatstringparts[0].toLowerCase())) {
formattedvalue = new CellGeneralFormatter().format(cellvalue);
} else {
formattedvalue = new CellNumberFormatter(formatstringparts[0]).format(cellvalue);
}
}
}
System.out.println(formattedvalue);
break;
//...
default:
System.out.println();
}
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
重要提示:
此代码示例来自 2016 年,适用于 apache poi 3.14
。
从当前的 apache poi
版本 3.17
和 4.x.y
开始,不应再使用它。在当前版本中,这很简单:
...
InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
DataFormatter formatter = new DataFormatter();
for (Row row : sheet) {
for (Cell cell : row) {
String formattedvalue = formatter.formatCellValue(cell);
System.out.println("Using DataFormatter: " + formattedvalue);
}
}
...