本文介绍了JAVA Apache POI自定义格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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(不包含自定义格式的数据)。



编辑 p>

原始单元格类型为CELL_TYPE_NUMERIC。



>






如何在java代码中显示格式化的值031642153283700100 ?



我试过:




  • cell.toString()=>42153283700100

  • cell.getNumericCellValue()=>42153283700100



  cell.setCellType(Cell.CELL_TYPE_STRING); 




  • cell.getStringCellValue()=>42153283700100

  • cell.getRichStringCellValue()=>42153283700100


  • 旧的HSSFDataFormatter与formatCellValue(cell)method =>421532837001000316



解决方案

对于数字格式,您应该使用 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);
工作簿wb = WorkbookFactory.create(inp);

Sheet sheet = wb.getSheetAt(0);

for(Row row:sheet){

for(单元格:行){

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;

// ...

默认值:
System.out.println();
}
}
}

} catch(InvalidFormatException ifex){
} catch(FileNotFoundException fnfex){
} catch(IOException ioex ){
}
}
}

编辑



好的,我们有一个更一般的例子。以上不适用于日期(我已经知道的),但也不适用于所有数字格式。后者我认为 CellNumberFormatter 应该做但不会。不幸的是,它甚至会产生一些正确数字格式的错误。



Excel 中,一个数字格式最多可以包含4个部分用分号分隔。第一部分是大于0的数字,第二部分是数字低于0的数字,第三部分是数字等于0,第四部分是数字的文字。



格式> 0 ; 格式< 0 ; format = 0 ; text



由于 CellNumberFormatter 不能正确处理,所以我们应该在使用 CellNumberFormatter 之前进行处理。 / p>

  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);
工作簿wb = WorkbookFactory.create(inp);

Sheet sheet = wb.getSheetAt(0);

for(Row row:sheet){

for(单元格:行){

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){//默认的短日期没有显式格式化
dateformatstring =yyyy-MM-dd; //这个
的默认日期格式else if(cell.getCellStyle()。getDataFormat()== 22){//默认的短日期时间没有显式格式化
dateformatstring =yyyy-MM-dd hh :毫米; //这个
的默认datetime格式} else {//显式格式化的其他数据格式
dateformatstring = formatstringparts [0];
}
formattedvalue = new CellDateFormatter(dateformatstring).format(date);
} else {

double cellvalue = cell.getNumericCellValue();
System.out.println(cellvalue);

switch(formatstringparts.length){
案例4:
案例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()格式(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;

// ...

默认值:
System.out.println();
}
}
}

} catch(InvalidFormatException ifex){
} catch(FileNotFoundException fnfex){
} catch(IOException ioex ){
}
}
}


I am Using poi version : 3.14

I access an Excel (.xlsx) file

this.workbook = WorkbookFactory.create(new FileInputStream(f.getPath()));
this.workbook.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK);
this.sheet = workbook.getSheetAt(0);

Here is a custom format found in .xlsx file applied to a cell. I want to display the cell value in my code.

As you can see the cell value visible in file is "031642153283700100". Also when i clic on this particular cell, value is changing to "42153283700100" (data without custom format applied on).

EDIT

Original cell type is CELL_TYPE_NUMERIC.

==>


How can i display the formatted value "031642153283700100" in java code ?

I tried :

  • cell.toString() => "42153283700100"
  • cell.getNumericCellValue() => "42153283700100"

With previous cell type conversion :

cell.setCellType(Cell.CELL_TYPE_STRING);

  • cell.getStringCellValue() => "42153283700100"
  • cell.getRichStringCellValue() => "42153283700100"

  • Old HSSFDataFormatter with formatCellValue(cell) method => "421532837001000316"

解决方案

For number formats you should use CellGeneralFormatter or CellNumberFormatter.

Example:

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) {
  }
 }
}

Edit

OK, let's have a more general example. The above will not work with dates (what I had known already) but also not with all number formats. The latter I thought the CellNumberFormatter should do but it does not. Unfortunately it will even produce errors with some proper number formats.

In Excel a number format can contain up to 4 parts delimited with semicolon. The first part is for numbers greater than 0, the second part is for numbers lower than 0, the third part is for numbers equal 0 and the fourth part is for text.

format > 0;format < 0;format = 0;text

Since the CellNumberFormatter does not handle this properly, we should do it before using the 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) {
  }
 }
}

这篇关于JAVA Apache POI自定义格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 05:02
查看更多