POI是Apache的一套讀MS文檔的API,用它還是可以比較方便的讀取Office文檔的。目前支持Word,Excel,PowerPoint生成的文檔,還有Visio和Publisher的。
http://poi.apache.org/download.html
具體的用法可以查閱文檔裏面您的quickguide,我給出我自己的範例,從xls文件把數據導出到mysql。
這裏面我總是假定excel在第一個sheet並且第一行是字段名,能夠自動從第一行讀取字段名建立一個表然後導入數據。
- package JDBCPractice;
- import java.io.*;
- import java.sql.*;
- import org.apache.poi.hssf.*;
- import org.apache.poi.ss.usermodel.*;
- import org.apache.poi.hssf.usermodel.HSSFCell;
- import org.apache.poi.hssf.usermodel.HSSFRow;
- import org.apache.poi.hssf.usermodel.HSSFSheet;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- // 導入hssf來處理xls文件
- import org.apache.poi.poifs.filesystem.POIFSFileSystem;
- // 使用poifs來讀文件更加的輕鬆,當然也可以不用
- public class main {
- /**
- * @param args
- */
- public static void main(String[] args) {
- String addr = "/home/ulysess/Developer/T_user.XLS";
- HSSFWorkbook wb = null;
- HSSFSheet contents = null;
- try {
- POIFSFileSystem exlf = new POIFSFileSystem(new FileInputStream(addr));
- wb = new HSSFWorkbook(exlf);
- } catch (FileNotFoundException e) {
- System.out.println("文件不存在,請檢查路徑");
- e.printStackTrace();
- return;
- } catch (IOException e) {
- System.out.println("讀取文件時發生IO錯誤");
- e.printStackTrace();
- return;
- }
- contents = wb.getSheetAt(0);
- //取第一個sheet
- int minColIdx, maxColIdx, maxRowIdx;
- maxRowIdx = contents.getLastRowNum();
- HSSFRow xlrow = contents.getRow(0);
- //-----------------------建立MySQL連接-------------------------
- try {
- Class.forName("com.mysql.jdbc.Driver");
- //建立一個mysql的driver的實例,並將其註冊到DriversManager
- } catch (ClassNotFoundException e) {
- System.out.println("Unable load Driver");
- e.printStackTrace();
- }
- String name = "root";
- String password = "moratorium";
- String url = "jdbc:mysql://localhost/USERDATAS";
- try {
- Connection con = DriverManager.getConnection(url, name, password);
- //建立連接
- Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
- ResultSet.CONCUR_UPDATABLE);
- try {
- /*stmt.execute("create table ORGDATAS( " +
- "USERID VARCHAR(24) NOT NULL PRIMARY KEY," +
- " USERNAME VARCHAR(24), SEX TINYINT, " +
- "PASSWORD VARCHAR(64), USERTYPE TINYINT, " +
- "FREEAUTHEN TINYINT, CERTIFICATETYPE TINYINT, " +
- "CERTIFICATENO VARCHAR(24), EDUCATION TINYINT, " +
- "POSTCODE VARCHAR(10), ADDRESS VARCHAR(128), " +
- "PHONENO VARCHAR(24), BIRTHDAY DATE, EMAIL VARCHAR(64) );");*/
- //建表
- HSSFCell cel, refcell;
- HSSFRow ferr = contents.getRow(1);
- String ctbsql = "create table TARGETTABLE (";
- for(int i = xlrow.getFirstCellNum(); i < xlrow.getLastCellNum(); i++) {
- cel = xlrow.getCell(i);
- refcell = ferr.getCell(i);
- if(refcell == null) {
- ctbsql = ctbsql.concat(cel.getStringCellValue() + " VARCHAR(64)");
- } else {
- switch(refcell.getCellType()) {
- case Cell.CELL_TYPE_FORMULA:
- case Cell.CELL_TYPE_STRING:
- ctbsql = ctbsql.concat(cel.getStringCellValue() + " VARCHAR(64)");
- break;
- case Cell.CELL_TYPE_NUMERIC:
- ctbsql = ctbsql.concat(cel.getStringCellValue() + " INT");
- break;
- case Cell.CELL_TYPE_BOOLEAN:
- ctbsql = ctbsql.concat(cel.getStringCellValue() + " TINYINT");
- break;
- default:
- ctbsql = ctbsql.concat(cel.getStringCellValue() + " VARCHAR(64)");
- }
- }
- if(i < xlrow.getLastCellNum()-1) {
- if(i == 0 ) {
- ctbsql = ctbsql.concat(" NOT NULL PRIMARY KEY");
- }
- ctbsql = ctbsql.concat(", ");
- }else {
- ctbsql = ctbsql.concat(");");
- }
- }
- stmt.execute(ctbsql);
- //跟據前兩行的內容來建表
- } catch(SQLException e) {
- }
- ResultSet rs = stmt.executeQuery("select * from TARGETTABLE");
- minColIdx = xlrow.getFirstCellNum();
- maxColIdx = xlrow.getLastCellNum();
- //設定每列的最小最大索引
- int cnt =0 ;
- boolean infirstrow = true;
- //for each式遍歷整個表
- for (Row row : contents) {
- if(infirstrow) {
- infirstrow = false;
- continue;
- }
- rs.moveToInsertRow();
- System.out.println("insert " + cnt++);
- for (Cell cell : row) {
- if(cell == null) {
- continue;
- }
- switch(cell.getCellType()) {
- case Cell.CELL_TYPE_FORMULA:
- case Cell.CELL_TYPE_STRING:
- rs.updateString(cell.getColumnIndex() + 1, cell.getStringCellValue());
- break;
- case Cell.CELL_TYPE_NUMERIC:
- rs.updateInt(cell.getColumnIndex() + 1, (int) cell.getNumericCellValue());
- break;
- case Cell.CELL_TYPE_BOOLEAN:
- rs.updateShort(cell.getColumnIndex() + 1, (short) cell.getNumericCellValue());
- break;
- default:
- rs.updateString(cell.getColumnIndex() + 1, cell.getStringCellValue());
- }
- }
- rs.insertRow();
- }
- System.out.println("--------------------------");
- } catch (SQLException e) {
- e.printStackTrace();
- System.out.println("/n--- SQLException caught ---/n");
- while (e != null) {
- System.out.println("Message: "
- + e.getMessage ());
- System.out.println("SQLState: "
- + e.getSQLState ());
- System.out.println("ErrorCode: "
- + e.getErrorCode ());
- e = e.getNextException();
- e.printStackTrace();
- System.out.println("");
- }
- } catch (IllegalStateException ie) {
- ie.printStackTrace();
- }
- }
- }
在項目中用戶需要導入大量Excel表格數據到數據庫,爲此需求自己寫了一個讀取Excel數據的java類,現將代碼貼出來與大家一起分享。
該類提供兩個方法,一個方法用於讀取Excel表格的表頭,另一個方法用於讀取Excel表格的內容。
(注:本類需要POI組件的支持,POI是apache組織下的一個開源組件,)
代碼如下:
- package org.hnylj.poi.util;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import org.apache.poi.hssf.usermodel.HSSFCell;
- import org.apache.poi.hssf.usermodel.HSSFRow;
- import org.apache.poi.hssf.usermodel.HSSFSheet;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.poifs.filesystem.POIFSFileSystem;
- /**
- * 操作Excel表格的功能類
- * @author:hnylj
- * @version 1.0
- */
- public class ExcelReader {
- private POIFSFileSystem fs;
- private HSSFWorkbook wb;
- private HSSFSheet sheet;
- private HSSFRow row;
- /**
- * 讀取Excel表格表頭的內容
- * @param InputStream
- * @return String 表頭內容的數組
- *
- */
- public String[] readExcelTitle(InputStream is) {
- try {
- fs = new POIFSFileSystem(is);
- wb = new HSSFWorkbook(fs);
- } catch (IOException e) {
- e.printStackTrace();
- }
- sheet = wb.getSheetAt(0);
- row = sheet.getRow(0);
- //標題總列數
- int colNum = row.getPhysicalNumberOfCells();
- String[] title = new String[colNum];
- for (int i=0; i<colNum; i++) {
- title[i] = getStringCellValue(row.getCell((short) i));
- }
- return title;
- }
- /**
- * 讀取Excel數據內容
- * @param InputStream
- * @return Map 包含單元格數據內容的Map對象
- */
- public Map<Integer,String> readExcelContent(InputStream is) {
- Map<Integer,String> content = new HashMap<Integer,String>();
- String str = "";
- try {
- fs = new POIFSFileSystem(is);
- wb = new HSSFWorkbook(fs);
- } catch (IOException e) {
- e.printStackTrace();
- }
- sheet = wb.getSheetAt(0);
- //得到總行數
- int rowNum = sheet.getLastRowNum();
- row = sheet.getRow(0);
- int colNum = row.getPhysicalNumberOfCells();
- //正文內容應該從第二行開始,第一行爲表頭的標題
- for (int i = 1; i <= rowNum; i++) {
- row = sheet.getRow(i);
- int j = 0;
- while (j<colNum) {
- //每個單元格的數據內容用"-"分割開,以後需要時用String類的replace()方法還原數據
- //也可以將每個單元格的數據設置到一個javabean的屬性中,此時需要新建一個javabean
- str += getStringCellValue(row.getCell((short) j)).trim() + "-";
- j ++;
- }
- content.put(i, str);
- str = "";
- }
- return content;
- }
- /**
- * 獲取單元格數據內容爲字符串類型的數據
- * @param cell Excel單元格
- * @return String 單元格數據內容
- */
- private String getStringCellValue(HSSFCell cell) {
- String strCell = "";
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_STRING:
- strCell = cell.getStringCellValue();
- break;
- case HSSFCell.CELL_TYPE_NUMERIC:
- strCell = String.valueOf(cell.getNumericCellValue());
- break;
- case HSSFCell.CELL_TYPE_BOOLEAN:
- strCell = String.valueOf(cell.getBooleanCellValue());
- break;
- case HSSFCell.CELL_TYPE_BLANK:
- strCell = "";
- break;
- default:
- strCell = "";
- break;
- }
- if (strCell.equals("") || strCell == null) {
- return "";
- }
- if (cell == null) {
- return "";
- }
- return strCell;
- }
- /**
- * 獲取單元格數據內容爲日期類型的數據
- * @param cell Excel單元格
- * @return String 單元格數據內容
- */
- private String getDateCellValue(HSSFCell cell) {
- String result = "";
- try {
- int cellType = cell.getCellType();
- if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
- Date date = cell.getDateCellValue();
- result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
- + "-" + date.getDate();
- } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
- String date = getStringCellValue(cell);
- result = date.replaceAll("[年月]", "-").replace("日", "").trim();
- } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
- result = "";
- }
- } catch (Exception e) {
- System.out.println("日期格式不正確!");
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String[] args) {
- try {
- //對讀取Excel表格標題測試
- InputStream is = new FileInputStream("C:\\Excel表格測試.xls");
- ExcelReader excelReader = new ExcelReader();
- String[] title = excelReader.readExcelTitle(is);
- System.out.println("獲得Excel表格的標題:");
- for (String s : title) {
- System.out.print(s + " ");
- }
- //對讀取Excel表格內容測試
- InputStream is2 = new FileInputStream("C:\\Excel表格測試.xls");
- Map<Integer,String> map = excelReader.readExcelContent(is2);
- System.out.println("獲得Excel表格的內容:");
- for (int i=1; i<=map.size(); i++) {
- System.out.println(map.get(i));
- }
- } catch (FileNotFoundException e) {
- System.out.println("未找到指定路徑的文件!");
- e.printStackTrace();
- }
- }
- }
- package org.hnylj.poi.util;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import org.apache.poi.hssf.usermodel.HSSFCell;
- import org.apache.poi.hssf.usermodel.HSSFRow;
- import org.apache.poi.hssf.usermodel.HSSFSheet;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.poifs.filesystem.POIFSFileSystem;
- /**
- * 操作Excel表格的功能類
- * @author:hnylj
- * @version 1.0
- */
- public class ExcelReader {
- private POIFSFileSystem fs;
- private HSSFWorkbook wb;
- private HSSFSheet sheet;
- private HSSFRow row;
- /**
- * 讀取Excel表格表頭的內容
- * @param InputStream
- * @return String 表頭內容的數組
- *
- */
- public String[] readExcelTitle(InputStream is) {
- try {
- fs = new POIFSFileSystem(is);
- wb = new HSSFWorkbook(fs);
- } catch (IOException e) {
- e.printStackTrace();
- }
- sheet = wb.getSheetAt(0);
- row = sheet.getRow(0);
- //標題總列數
- int colNum = row.getPhysicalNumberOfCells();
- String[] title = new String[colNum];
- for (int i=0; i<colNum; i++) {
- title[i] = getStringCellValue(row.getCell((short) i));
- }
- return title;
- }
- /**
- * 讀取Excel數據內容
- * @param InputStream
- * @return Map 包含單元格數據內容的Map對象
- */
- public Map<Integer,String> readExcelContent(InputStream is) {
- Map<Integer,String> content = new HashMap<Integer,String>();
- String str = "";
- try {
- fs = new POIFSFileSystem(is);
- wb = new HSSFWorkbook(fs);
- } catch (IOException e) {
- e.printStackTrace();
- }
- sheet = wb.getSheetAt(0);
- //得到總行數
- int rowNum = sheet.getLastRowNum();
- row = sheet.getRow(0);
- int colNum = row.getPhysicalNumberOfCells();
- //正文內容應該從第二行開始,第一行爲表頭的標題
- for (int i = 1; i <= rowNum; i++) {
- row = sheet.getRow(i);
- int j = 0;
- while (j<colNum) {
- //每個單元格的數據內容用"-"分割開,以後需要時用String類的replace()方法還原數據
- //也可以將每個單元格的數據設置到一個javabean的屬性中,此時需要新建一個javabean
- str += getStringCellValue(row.getCell((short) j)).trim() + "-";
- j ++;
- }
- content.put(i, str);
- str = "";
- }
- return content;
- }
- /**
- * 獲取單元格數據內容爲字符串類型的數據
- * @param cell Excel單元格
- * @return String 單元格數據內容
- */
- private String getStringCellValue(HSSFCell cell) {
- String strCell = "";
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_STRING:
- strCell = cell.getStringCellValue();
- break;
- case HSSFCell.CELL_TYPE_NUMERIC:
- strCell = String.valueOf(cell.getNumericCellValue());
- break;
- case HSSFCell.CELL_TYPE_BOOLEAN:
- strCell = String.valueOf(cell.getBooleanCellValue());
- break;
- case HSSFCell.CELL_TYPE_BLANK:
- strCell = "";
- break;
- default:
- strCell = "";
- break;
- }
- if (strCell.equals("") || strCell == null) {
- return "";
- }
- if (cell == null) {
- return "";
- }
- return strCell;
- }
- /**
- * 獲取單元格數據內容爲日期類型的數據
- * @param cell Excel單元格
- * @return String 單元格數據內容
- */
- private String getDateCellValue(HSSFCell cell) {
- String result = "";
- try {
- int cellType = cell.getCellType();
- if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
- Date date = cell.getDateCellValue();
- result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
- + "-" + date.getDate();
- } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
- String date = getStringCellValue(cell);
- result = date.replaceAll("[年月]", "-").replace("日", "").trim();
- } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
- result = "";
- }
- } catch (Exception e) {
- System.out.println("日期格式不正確!");
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String[] args) {
- try {
- //對讀取Excel表格標題測試
- InputStream is = new FileInputStream("C:\\Excel表格測試.xls");
- ExcelReader excelReader = new ExcelReader();
- String[] title = excelReader.readExcelTitle(is);
- System.out.println("獲得Excel表格的標題:");
- for (String s : title) {
- System.out.print(s + " ");
- }
- //對讀取Excel表格內容測試
- InputStream is2 = new FileInputStream("C:\\Excel表格測試.xls");
- Map<Integer,String> map = excelReader.readExcelContent(is2);
- System.out.println("獲得Excel表格的內容:");
- for (int i=1; i<=map.size(); i++) {
- System.out.println(map.get(i));
- }
- } catch (FileNotFoundException e) {
- System.out.println("未找到指定路徑的文件!");
- e.printStackTrace();
- }
- }
- }
通過該類提供的方法就能讀取出Excel表格中的數據,數據讀取出來了,其他的,對這些數據進行怎樣的操作,要靠你另外寫程序去實現,因爲該類只提供讀取Excel表格數據的功能。
說明:在該類中有一個getStringCellValue(HSSFCell cell)方法和一個getDateCellValue(HSSFCell cell)方法,前一個方法用於讀取那些爲字符串類型的數據,如果你的Excel表格中填寫的是日期類型的數據,則你應該在readExcelContent(InputStream is)方法裏調用getDateCellValue(HSSFCell cell)方法,因爲若調用getStringCellValue(HSSFCell cell)方法讀取日期類型的數據將得到的是一個浮點數,這很可能不符合實際要求。