java 保留小數與四捨五入以及時間日期的轉換和excel讀入與資料庫寫入
之前進行開發了一段小程式,開發過程中發現短短白來行的程式碼需要用到很多的知識現在進行總結
先貼程式碼,後面做詳細的解釋
第一個函式是主函式,主要用於讀取excel的內容,然後根據empCode在資料庫中查詢一些資料,再對excel的時間進行一些處理,最後將處理過的內容放到一個新的資料庫中public class ImportData { static SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); static DecimalFormat decimalFormatter = new DecimalFormat("###.##"); public static void main(String[] args) { Connection conn = null; Statement stmt = null; ResultSet rs = null; try{ Class.forName("oracle.jdbc.driver.OracleDriver"); String url = "jdbc:oracle:thin:@10.16.67.55:1526:ehrtst2"; conn = DriverManager.getConnection(url, "hrmidea", "Midea2014"); stmt = conn.createStatement(); FileInputStream sourceFile = new FileInputStream("C:\\Users\\hp\\Desktop\\total.xls"); POIFSFileSystem poiFileSystem = new POIFSFileSystem(sourceFile); HSSFWorkbook workBook = new HSSFWorkbook(poiFileSystem, true); sourceFile.close(); HSSFSheet sheet = workBook.getSheetAt(0); System.out.println(sheet.getLastRowNum()); // for(int i = 2; i<90; i++){ for(int i = 2; i<sheet.getLastRowNum(); i++){ HSSFRow row = sheet.getRow(i); String empName = getCellValue(row.getCell((short)0)); //員工姓名 String empCode = getCellValue(row.getCell((short)1)); //員工工號 String worktime = getCellValue(row.getCell((short)2)); //科技工時 String source = getCellValue(row.getCell((short)3)); //來源 String beginDate = getCellValue(row.getCell((short)4)); //開始時間 Date enddateTemp = formater.parse("2015-05-31"); String endDate= formater.format(enddateTemp); String msg = empName+"\t"+empCode+"\t"+worktime+"\t"+source+"\t"+beginDate+"\t"; //System.out.print(msg); String sql1 = "select c_employeeid, c_code, c_name, c_employeestatus, c_unitid, c_unitname, c_jobid, c_jobname, c_joborder from tb_inf_employee_0526 where c_code='"+empCode+"'"; rs = stmt.executeQuery(sql1); if(rs.next()){ BigDecimal empid = (BigDecimal)rs.getObject("c_employeeid"); String name = (String)rs.getObject("c_name"); String employeestatus = (String)rs.getObject("c_employeestatus"); BigDecimal unitid = (BigDecimal)rs.getObject("c_unitid"); String unitname = (String)rs.getObject("c_unitname"); BigDecimal jobid = (BigDecimal)rs.getObject("c_jobid"); String jobName = (String)rs.getObject("c_jobname"); String jobOrder = (String)rs.getObject("c_joborder"); if(beginDate!=null&&beginDate.length()>1){ //System.out.println(""); //todo }else{ if(!"0".equals(worktime)){ Date date = formater.parse("2015-06-01"); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); BigDecimal bigDecimal = new BigDecimal(worktime).setScale(0, BigDecimal.ROUND_HALF_UP); calendar.add(2,-bigDecimal.intValue()); date = calendar.getTime(); beginDate = formater.format(date); //System.out.println(beginDate); //todo } } String sql2 = "insert into TB_INF_TECPERSONINFO_0526 (C_OID,C_EMPOID,C_OPERATETIME,C_OPERATOR,C_BEGINDATE,C_ENDDATE,C_UNITID,C_UNITNAME,C_JOBID,C_JOBNAME,C_JOBORDER,C_JOBSENIORITYACC) VALUES (hibernate_sequence.nextval,"+empid.longValue()+",sysdate,0,to_date('"+beginDate +"','yyyy-mm-dd'),to_date('"+endDate +"','yyyy-mm-dd'),"+unitid.longValue()+",'"+unitname+"',"+jobid.longValue()+",'"+ jobName +"','"+ jobOrder +"',0)"; stmt.addBatch(sql2); }else{ msg += "根據工號找不到對應員工;"; } } stmt.executeBatch(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } }catch(Exception e2){ e2.printStackTrace(); } } } public static String getCellValue(HSSFCell hssfCell){ String cellValue = null; if (hssfCell != null) { switch (hssfCell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC : if (HSSFDateUtil.isCellDateFormatted(hssfCell)) cellValue = formater.format(hssfCell.getDateCellValue()); else cellValue = decimalFormatter.format(hssfCell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING : cellValue = hssfCell.getStringCellValue().trim(); break; case HSSFCell.CELL_TYPE_FORMULA : if (!Double.isNaN(hssfCell.getNumericCellValue())) { if (HSSFDateUtil.isCellDateFormatted(hssfCell)) cellValue = formater.format(hssfCell.getDateCellValue()); else cellValue = decimalFormatter.format(hssfCell.getNumericCellValue()); } else if (!hssfCell.getStringCellValue().equals("")) { cellValue = hssfCell.getStringCellValue().trim(); } else { // 存在不可識別的資料格式 throw new InfoCenterException(InfoCenterExceptionType.UNKNOWNDATATYPEEXCEPTION, new Object[]{String.valueOf(hssfCell.getCellNum() + 1)}); } break; case HSSFCell.CELL_TYPE_BLANK : cellValue = ""; break; case HSSFCell.CELL_TYPE_BOOLEAN : cellValue = String.valueOf(hssfCell.getBooleanCellValue()); break; default : //存在不可識別的資料格式 throw new InfoCenterException(InfoCenterExceptionType.UNKNOWNDATATYPEEXCEPTION, new Object[]{String.valueOf(hssfCell.getCellNum() + 1)}); } }else { //單元格為空時,返回空串 cellValue = ""; } return cellValue; } }
由於是單獨的java demo,為了方便測試,首先是對資料庫進行連結,按照驅動,URL,使用者名稱,密碼,和statement的方式進行連結
最後,加入了關閉資料庫連結的語句,這裡主要是為了養成良好的習慣
然後對excel的匯入進行了code,這裡提一句用poi在ssh中是比較常見的,
excel的匯出可以參考http://blog.csdn.net/evangel_z/article/details/7332535
ecel的匯入可以參考http://sarin.iteye.com/blog/845035
這裡我們對比上文可以看到
讀入有兩種方式:
一種是
excelFile = new File(filePath);
InputStream is = new FileInputStream(excelFile);// 獲取檔案輸入流
HSSFWorkbook workbook2003 = new HSSFWorkbook(is);//
一種是
FileInputStream sourceFile = new FileInputStream("C:\\Users\\hp\\Desktop\\total.xls");
POIFSFileSystem poiFileSystem = new POIFSFileSystem(sourceFile);
HSSFWorkbook workBook = new HSSFWorkbook(poiFileSystem, true);
sourceFile.close();
兩者的不同,第二種必須是excel檔案,而第一種可以是其他檔案,第二種方法第四種要加入進來
http://www.yiibai.com/apache_poi/apache_poi_core_classes.html這裡寫了HSSFWorkbook不同建構函式的區別
接下來就是按照getCellValue(HSSFCell hssfCell)函式讀取每行每列的資料,這裡需要提到的是這個函式,可以對不同的型別進行轉碼
第一個case是對區分日期和真正的數字
第二個case是字串
第三個是對應公式即CELL_TYPE_FORMULA
第四個是空格
第五個是布林型別
這個函式可以作為讀取excel的工具類
之後的sql1是用於查詢語句,純sql語句,用stmt.executeQuery(sql1)來執行,大資料的話用批量執行,具體參考之前的博文
之後就是最重要的日期轉換,按照客戶需求,如果讀取的列裡面沒有開始時間,則設定結束時間為2015-05-31,開始時間為結束時間減去worktime(單位為月)
如果有開始時間則不更改開始時間,結束時間也為2015-05-31
這裡就涉及到日期的增減,具體功能實現的步驟如下
static SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 建立一個格式,通過函式getCellValue(HSSFCell hssfCell)可以把excel裡面的時間讀取成這個格式,
然後進行邏輯判斷,如果沒有開始時間,則設定結束時間,具體程式碼如下
Date date = formater.parse("2015-06-01"); //設定data
Calendar calendar = Calendar.getInstance();
calendar.setTime(date); //轉換成日期格式
下一步應該用結束時間減去worktime,在處理這裡時發現,worktime可能為小數,根據要求要四捨五入,這裡運用了下面的方法
BigDecimal bigDecimal = new BigDecimal(worktime).setScale(0, BigDecimal.ROUND_HALF_UP);
上面的0代表保留的位數,後面代表四捨五入
具體四捨五入和保留小數位數的方法可以參考,裡面還有湊整等一系列的方法
http://www.cnblogs.com/xd502djj/archive/2011/07/21/2112683.html
最後進行減去,並轉換回data
calendar.add(2,-bigDecimal.intValue()); 2代表減月份
date = calendar.getTime(); 轉換會時間
beginDate = formater.format(date); 轉換成相應的string
日期的加減可參考http://blog.csdn.net/liwenfeng1022/article/details/6534176/
最後拼接成sql進行插入
String sql2 = "insert into TB_INF_TECPERSONINFO_0526 (C_OID,C_EMPOID,C_OPERATETIME,C_OPERATOR,C_BEGINDATE,C_ENDDATE,C_UNITID,C_UNITNAME,C_JOBID,C_JOBNAME,C_JOBORDER,C_JOBSENIORITYACC) VALUES (hibernate_sequence.nextval,"+empid.longValue()+",sysdate,0,to_date('"+beginDate +"','yyyy-mm-dd'),to_date('"+endDate +"','yyyy-mm-dd'),"+unitid.longValue()+",'"+unitname+"',"+jobid.longValue()+",'"+ jobName +"','"+ jobOrder +"',0)";
這裡面涉及到序列程式碼,當前時間,時間插入,字元,陣列,等方式,是個很好的案例,第一個為序列值,資料庫為oracle的命令,mysql會有點不同
stmt.addBatch(sql2);
為批量插入,具體可以參考之前的博文