讀取Excel表格日期類型數據的時候

 

用POI讀取Excel數據:(版本號:POI3.7)java

一、讀取Excelapache

Java代碼   收藏代碼
private List<String[]> rosolveFile(InputStream is, String suffix, int startRow) throws IOException, FileNotFoundException { Workbook xssfWorkbook = null; if ("xls".equals(suffix)) { xssfWorkbook = new HSSFWorkbook(is); } else if ("xlsx".equals(suffix)) { xssfWorkbook = new XSSFWorkbook(is); } Sheet xssfSheet = xssfWorkbook.getSheetAt(0); if (xssfSheet == null) { return null; } ArrayList<String[]> list = new ArrayList<String[]>(); int lastRowNum = xssfSheet.getLastRowNum(); for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) { if (xssfSheet.getRow(rowNum) != null) { Row xssfRow = xssfSheet.getRow(rowNum); short firstCellNum = xssfRow.getFirstCellNum(); short lastCellNum = xssfRow.getLastCellNum(); if (firstCellNum != lastCellNum) { String[] values = new String[lastCellNum]; for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) { Cell xssfCell = xssfRow.getCell(cellNum); if (xssfCell == null) { values[cellNum] = ""; } else { values[cellNum] = parseExcel(xssfCell); } } list.add(values); } } } return list; } 

 

 

 二、Excel數據處理:app

Excel存儲日期、時間均以數值類型進行存儲,讀取時POI先判斷是是不是數值類型,再進行判斷轉化xss

一、數值格式(CELL_TYPE_NUMERIC):ui

1.純數值格式:getNumericCellValue() 直接獲取數據spa

2.日期格式處理yyyy-MM-dd, d/m/yyyy h:mm, HH:mm 等不含文字的日期格式調試

1).判斷是不是日期格式:HSSFDateUtil.isCellDateFormatted(cell)excel

2).判斷是日期或者時間code

cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm") 或者: cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("yyyy-MM-dd")

 

3.自定義日期格式處理yyyy年m月d日,h時mm分,yyyy年m月等含文字的日期格式orm

判斷cell.getCellStyle().getDataFormat()值,解析數值格式

yyyy年m月d日----->31

m月d日---->58

h時mm分--->32

二、字符格式(CELL_TYPE_STRING):直接獲取內容

 

Java代碼   收藏代碼
private String parseExcel(Cell cell) { String result = new String(); switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC:// 數字類型 
            if (HSSFDateUtil.isCellDateFormatted(cell)) {// 處理日期格式、時間格式 
                SimpleDateFormat sdf = null; if (cell.getCellStyle().getDataFormat() == HSSFDataFormat .getBuiltinFormat("h:mm")) { sdf = new SimpleDateFormat("HH:mm"); } else {// 日期 
                    sdf = new SimpleDateFormat("yyyy-MM-dd"); } Date date = cell.getDateCellValue(); result = sdf.format(date); } else if (cell.getCellStyle().getDataFormat() == 58) { // 處理自定義日期格式:m月d日(經過判斷單元格的格式id解決,id的值是58) 
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); double value = cell.getNumericCellValue(); Date date = org.apache.poi.ss.usermodel.DateUtil .getJavaDate(value); result = sdf.format(date); } else { double value = cell.getNumericCellValue(); CellStyle style = cell.getCellStyle(); DecimalFormat format = new DecimalFormat(); String temp = style.getDataFormatString(); // 單元格設置成常規 
                if (temp.equals("General")) { format.applyPattern("#"); } result = format.format(value); } break; case HSSFCell.CELL_TYPE_STRING:// String類型 
            result = cell.getRichStringCellValue().toString(); break; case HSSFCell.CELL_TYPE_BLANK: result = ""; default: result = ""; break; } return result; } 

 

 

 *萬能處理方案

全部日期格式均可以經過getDataFormat()值來判斷

yyyy-MM-dd----- 14

yyyy年m月d日--- 31

yyyy年m月------- 57

m月d日  ---------- 58

HH:mm----------- 20

h時mm分  ------- 32

 

Java代碼   收藏代碼
 
//一、判斷是不是數值格式 
if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){ short format = cell.getCellStyle().getDataFormat(); SimpleDateFormat sdf = null; if(format == 14 || format == 31 || format == 57 || format == 58){ //日期 
        sdf = new SimpleDateFormat("yyyy-MM-dd"); }else if (format == 20 || format == 32) { //時間 
        sdf = new SimpleDateFormat("HH:mm"); } double value = cell.getNumericCellValue(); Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value); result = sdf.format(date); } 

 

Java 讀取Excel表格日期類型數據的時候,讀出來的是這樣的  13-十二月-2017,而Excel中輸入的是 2017/12/13 或 2017-12-13

還有Excel中輸入的是整型 5,java 讀取出來的是5.0

這可怎麼整?

解決方法:

日期轉換

import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Cell; Workbook workBook = (Workbook)ModelUtils.getRequestContext().getActionContext().getParameter("excel"); Sheet sheet = workBook.getSheetAt(0); int fr = sheet.getPhysicalNumberOfRows() - 4; for(int i=0;i<fr;i++){ int r = 4+i; org.apache.poi.ss.usermodel.Row rowDetail = sheet.getRow(r); String guarantee_date = ""; Cell dateCell = rowDetail.getCell(2); //判斷是否爲日期類型
         if(0==dateCell.getCellType()){ if(DateUtil.isCellDateFormatted(dateCell)){ //用於轉化爲日期格式
        Date d = dateCell.getDateCellValue(); DateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); guarantee_date = formater.format(d); } } System.out.println(guarantee_date); //------------整型數量格式處理--------------
         String countStr = rowDetail.getCell(3).toString(); Integer count = 0; System.out.println("入庫數量:"+countStr); if(countStr.indexOf(".")>=0){ System.out.println(". 位數: "+ countStr.indexOf(".")); countStr = countStr.substring(0, countStr.indexOf(".")); count = Integer.valueOf(countStr); } }

 

Apache poi 版本:3.12

今天在用poi解析excel文件時,碰到一個蛋疼的問題。

在個人excel文件中有一列是日期類型,例若有如下這麼一行數據(日期中月份前面的0會自動去掉):

image

在讀取註冊日期這個數據時,返回了一串數字,變成了 42149,

斷點調試到讀取數據的代碼,發現poi是正確識別的,可是在讀取具體數據時發生了變化:

image

從上圖能夠看到,poi把日期數據也歸類爲 Cell.CELL_TYPE_NUMERIC 數字類型,

而且在cell中是正確讀取到了 2015-05-25,可是在使用cell.getNumericCellValue()方法獲取時卻發生了變化,返回了42149.0

不知道它在裏面進行了怎樣的處理,但這不是咱們想要的結果。

既然如此,我直接用字符串的方式獲取可不能夠呢?

把代碼改成:

case Cell.CELL_TYPE_NUMERIC: value = cell.getStringCellValue(); DecimalFormat df = new DecimalFormat("0"); value = df.format(value); break;

 

拋出以下異常:

  1. Caused by: java.lang.IllegalStateException: Cannot get a text value from a numeric cell
  2. at org.apache.poi.xssf.usermodel.XSSFCell.typeMismatch(XSSFCell.java:888)
  3. at org.apache.poi.xssf.usermodel.XSSFCell.getRichStringCellValue(XSSFCell.java:310)
  4. at org.apache.poi.xssf.usermodel.XSSFCell.getStringCellValue(XSSFCell.java:261)

說明不能夠把它看成字符串類型來處理,

看方法卻是有個cell.getDateCellValue(),但是在何時進行調用呢,我要怎麼能知道它是date類型?

經過查詢資料發現,poi在Cell.CELL_TYPE_NUMERIC中又具體區分了類型,Date類型就是其中一種,把代碼再作處理:

case Cell.CELL_TYPE_NUMERIC: if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); value = DateFormatUtils.format(date, "yyyy-MM-dd"); } else { value = cell.getNumericCellValue(); DecimalFormat df = new DecimalFormat("0"); value = df.format(value); } break;

 

成功解決問題。

另外若是日期中有精確到日,精確到秒不一樣精度的,能夠用cell.getCellStyle().getDataFormat()cell.getCellStyle().getDataFormatString()來獲取格式。

相關文章
相關標籤/搜索