2012年10月13日 星期六

Java 與資料處理入門

資料處理入門

Many examples in this document are adapted from Java: How To Program (3rd Ed.), written by Deitel and Deitel, and Thinking in Java (2nd Edition), written by Bruce Eckel. All examples are solely used for educational purposes. Hopefully, I am not violating any copyright issue here. If so, please do email me.
Please install JDK 1.3.1_02 or later with Java Plugin to view this page. Also, this page is best viewed with browsers (for examples, Mozilla 0.99 or later, IE 6.x or later) with CSS2 support. This document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu

請勿轉貼
看其他教材

目錄

  1. 使用 Properties 來初始化你的程式
  2. 資料庫
  3. JDBC 的種類
  4. 資料庫存取的基本步驟
  5. 資料庫新增、刪除、查詢、修改
  6. JDBC 的種類
  7. 如何從 Unix (或 Linux)連資料庫?
  8. 從 applet 連資料庫的問題
  9. 讀取 Excel 的資料

使用 Properties 來初始化你的程式

在 Win32 的系統上,我們經常將會變動的值儲存在設定檔中(.ini) -- 例如安裝路徑,使用者帳號,密碼,JDBC 的 driver 等 --以便 在不同的環境下,只需要變更設定檔而不需重新 compile 每一個程式。 這種設定檔在 Java 的情形,我們稱 Properties 檔。
  • 擺放初始值的檔案(meta.txt)
      dbUser=monkey
      dbPasswd=password
      
  • 讀取初始值的程式
      import java.util.*;
      import java.io.*;
    
      public class LoadProperty
      {
        public static void main(String argv[])
        {
          Properties props = new Properties();
          try {
            props.load(new FileInputStream("meta.txt"));
          } catch (IOException ioe) {
            System.out.println("Open meta.txt Error!");
            System.exit(1);
          }
    
          System.out.println(props.getProperty("dbUser"));
          System.out.println(props.getProperty("dbPasswd"));
        }
      }
      
另外,System 類別也提供了一系列的 properties 讓開發者來 使用,例如,java.class.path 這個 property 能讓開發人員來 讀取目前系統的 CLASSPATH 的設定,或者 os.version 能讓 開發人員讀取目前使用的作業系統版本。所有系統預設的 properties 可以從 Sun's Accessing System Resource 查到。
//
// to run this program, please enter the following command
// java -DSchool=<some value> TestSystem
//

public class TestSystem {
  public static void main(String[] args) {
    // print out the default system properties
    System.out.println("CLASSPATH = " +
                       System.getProperty("java.class.path"));
    System.out.println("OS Version = " + System.getProperty("os.version"));

    // check to see if user enter property "School"
    // if none is found, the default value "x" is set
    if (System.getProperty("School", "x").equals("x"))
      System.out.println("Usage: java -DSchool=<some value> TestSystem");
    else
      System.out.println("You are a student of " +
                         System.getProperty("School"));
  }
}

資料庫

Java 提供與各種資料庫的連結方式,而聯結資料庫需要驅動程式,這一類給 Java 使用來連結資料庫的程式統稱為 JDBC 驅動程式。JDBC 驅動程式共分成 四個 level 並將於下一個主題討論。在一開始, 我們僅討論如何利用 JDBC-ODBC 的驅動程式與資料庫連結。 (JDBC-ODBC 僅適用於 Win32 的系統) 若你使用 JDK 1.1.x 或以上版本, JDBC-ODBC 的驅動程式已經包含在 JDK 中。 若你尚在使用 JDK 1.0.x, 我建議你升級。 至於最新的 JDBC 驅動程式的 發展, 使用者歡迎到 JDBC Homepage 去找尋資料。 在以下的範例中, 我們使用的是一個 Microsoft Access 的資料庫 -- samples.mdb。 這個資料庫中包含一個 Table, 其名稱為 Product。 Product 有四個欄位 (ID, Name, Price, Qty)。 請於下載後, 利用 ODBC 將其設定為 Samples. 其過程為:
「開始」 --> 「設定」 --> 「控制台」 -->  「ODBC」 -->
「系統資料來源名稱」 -->  「新增」 -->
「Microsoft Access Driver (*.mdb)」  --> 「完成」
在 "資料來源名稱" 欄, 輸入 Samples, 並 「選擇」 samples.mdb 後按 OK。幾個簡單的 SQL 範例:
  1. 新增 (insert): 將一筆資料加入 Product.
        insert into Product values ('5','燒錄器', 15000, 10)
        
  2. 查詢 (select):
    1. 查詢全部資料:
            select * from Product
            
    2. 查詢名稱為'燒錄器'的相關資料:
            select * from Product where Name='燒錄器'
            
    3. 查詢名稱為'燒錄器'的目前存量:
            select Name, Qty from Product where Name='燒錄器'
            
    4. 查詢單價低於 2500 元的產品:
            select * from Product where Price < 2500
            
    5. 查詢單價介於 300 與 10000 元間的產品:
            select * from Product where Price >= 300 and Price < 10000
            
  3. 更改 (update): 將燒錄器的存量改為 20.
        update Product set Qty=20 where Name='燒錄器'
        
  4. 刪除 (delete): 刪除燒錄器的產品資料
        delete from Product where Name='燒錄器'
        

JDBC 的種類

  1. JDBC-ODBC bridge plus ODBC driver.
    • JDBC-ODBC bridge <--> ODBC driver <--> DBMS
    • Limitations: slower, requires 3rd party driver on non-Win32 machine, ODBC was written in C (中文化).
  2. Native-API partly-Java driver.
    • JDBC-API <--> DBMS (compare to category 4)
    • this type of driver requires that some operating system-specific binary code be loaded on each client machine.
  3. JDBC-Net pure Java driver.
    • JDBC <--> middleware on client <--> middleware on server <--> DBMS
    • In general, this is the most flexible JDBC alternative.
  4. Native-protocol pure Java driver.
    • JDBC driver <--> DBMS
    • In general, JDBC drivers are provided by DBMS vendors.

資料庫存取的基本步驟

  1. 載入 JDBC 驅動程式
    • 以 jdbc-odbc 為例,Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    • 以 MS SQL 2000 的驅動程式為例,Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
    • 以 Oracle 為例,DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
  2. 連結到資料庫
    • 以 jdbc-odbc 為例,Connection conn = DriverManager.getConnection("jdbc:odbc:odbc-DSN"); 注意,建議使用「系統的 DSN」。
    • 以 MS SQL 2000 的驅動程式為例,Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://hostname:1433","username","password"); 有了 SQL 2000 的純 JDBC 驅動程式,你可以從非 Windows 平台連結上 SQL 2000。
    • 以 Oracle 為例,Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:username/password@hostname:1521:sid");
  3. 建立並執行 SQL 指令。每一個 Connection 可以執行多個 Statement,而不需要為每一個 Statement 建立一個 Connection。建立 Connection 的成本是蠻高的!
      Statement aStatement = conn.createStatement();
      ResultSet rs = aStatement.executeQuery(aQuery);
      
  4. 處理由資料庫回傳的資料(ResultSet)
  5. 結束與資料庫的連線。注意,請在 Statement 不再需要的時候就把他 close 掉,同樣的程式結束以前(包含發生例外狀況時的例外處理),一定要記得結束連線。
[註: 使用 JDK 1.1.x,本程式無法顯示中文資料,請使用 JDK 1.3.0_01 以上的版本] 若需顯示中文資料, 請參考 JDBC driver 中文轉碼類別。 此類別為 SQL.java. 使用前述之類別後新的程式碼
import java.sql.*;

public class OldJavaDB 
{
  public static void main( String argv[] )
  {
    // initialize query string
    String aQuery = "select * from Product";

    try
    {
      // load the JDBC-ODBC bridge driver
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

      // connect to Database
      Connection conn = DriverManager.getConnection("jdbc:odbc:Samples");
  
      // Construct a SQL statement and submit it
      Statement aStatement = conn.createStatement();
      ResultSet rs = aStatement.executeQuery(aQuery);

      // Get info about the query results
      ResultSetMetaData rsmeta = rs.getMetaData();
      int cols = rsmeta.getColumnCount();

      // Display column headers
      for(int i=1; i<=cols; i++)
      {
        if(i > 1) System.out.print("\t");
        System.out.print(rsmeta.getColumnLabel(i));
      }
      System.out.print("\n");

      // Display query results.
      while(rs.next())
      {
        for(int i=1; i<=cols; i++)
        {
          if (i > 1) System.out.print("\t");
          System.out.print(rs.getString(i));
        }
        System.out.print("\n");
      }
  
      // Clean up
      rs.close();
      aStatement.close();
      conn.close();
    }
    // a better exception handling can be used here.
    catch (Exception e)
    {
      System.out.println("Exception Occurs.");
    }
  }
}

資料庫新增、刪除、查詢、修改

import java.sql.*;

public class NewJDBC
{
  // 試著將以下的設定以 properties 的檔案讀進來
  static String classname = "sun.jdbc.odbc.JdbcOdbcDriver";
  static String jdbcURL = "jdbc:odbc:dbms";
  static String UID = "uid";
  static String PWD = "pwd";
  static Connection conn = null;

  public static void main( String argv[] )
  {
    // initialize query string
    if(argv.length != 1)
    {
      System.out.println("Usage: java NewJDBC ");
      System.out.println("   ex. java NewJDBC department");
      System.exit(2);
    }
    String aQuery = "select * from " + argv[0];
    String iSQL = "insert into " + argv[0] + " values('資訊管理',3,'456789111','12/30/2000')";
    String uSQL = "update " + argv[0] + " set dname='資訊工程' where dnumber=3";
    String dSQL = "delete " + argv[0] + " where dnumber=3";

    try
    {
      // load the JDBC-ODBC bridge driver
      Class.forName(classname);

      // connect to Database
      conn = DriverManager.getConnection(jdbcURL,UID,PWD);

      // Display current content
      System.out.println("Display current content");
      ShowResults(aQuery);

      // Insert a new record
      System.out.println("\nInserting a new record .....");
      InsertNew(iSQL);
      ShowResults(aQuery);

      // Update record
      System.out.println("\nUpdateing a record .....");
      UpdateNew(uSQL);
      ShowResults(aQuery);

      // Delete record
      System.out.println("\nDeleting a record .....");
      DeleteNew(dSQL);
      ShowResults(aQuery);

      conn.close();
    } catch (Exception sqle)
    {
      System.out.println(sqle);
      System.exit(1);
    }
  }

  private static void DeleteNew(String dSQL)
  {
    try
    {
      Statement aStatement = conn.createStatement();
      aStatement.executeUpdate(dSQL);
    }
    catch (Exception e)
    {
      System.out.println("Delete Error: " + e);
      System.exit(1);
    }
  }

  private static void UpdateNew(String uSQL)
  {
    try
    {
      Statement aStatement = conn.createStatement();
      aStatement.executeUpdate(uSQL);
    }
    catch (Exception e)
    {
      System.out.println("Update Error: " + e);
      System.exit(1);
    }
  }

  private static void InsertNew(String iSQL)
  {
    try
    {
      Statement aStatement = conn.createStatement();
      aStatement.executeUpdate(iSQL);
    }
    catch (Exception e)
    {
      System.out.println("Insert Error: " + e);
      System.exit(1);
    }
  }


  private static void ShowResults(String aQuery)
  {
    try
    {
      // Construct a SQL statement and submit it
      Statement aStatement = conn.createStatement();
      ResultSet rs = aStatement.executeQuery(aQuery);

      // Get info about the query results
      ResultSetMetaData rsmeta = rs.getMetaData();
      int cols = rsmeta.getColumnCount();

      // Display column headers
      for(int i=1; i<=cols; i++)
      {
        if(i > 1) System.out.print("\t");
        System.out.print(rsmeta.getColumnLabel(i));
      }
      System.out.print("\n");

      // Display query results.
      while(rs.next())
      {
        for(int i=1; i<=cols; i++)
        {
          if (i > 1) System.out.print("\t");
          System.out.print(rs.getString(i));
        }
        System.out.print("\n");
      }

      // Clean up
      rs.close();
      aStatement.close();
    }
    // a better exception handling can be used here.
    catch (Exception e)
    {
      System.out.println("Exception Occurs.");
    }
  }
}

如何從 Unix (或 Linux)連資料庫?

解釋 Openlink 後,demo 如何在 Linux 上與 Microsoft SQL Server 連結並取得資料。
import java.sql.*;

public class OPLTest 
{
  public static void main( String argv[] )
  {
    // initialize query string
    String aQuery = null;
    Connection conn = null;
    int flag = 0;

    try
    {
      // load the JDBC-ODBC bridge driver
      Class.forName("openlink.jdbc2.Driver");

      if (argv.length == 0)
      {
        System.out.println("Usage: java OPLTest o1 [o2]");
        System.out.println("   o1: pubs, dbms, or bob");
        System.out.println("   o2: odbc or empty");
        System.exit(1);
      }

      // connect to Database
      if (argv[0].equals("bob"))
      {
        // to MS Access via odbc
        flag++;
        aQuery = "select * from books";
        conn = DriverManager.getConnection("jdbc:openlink://163.17.3.151/DSN=bob/");
      }

      if (argv[0].equals("pubs"))
      {
        flag++;
        aQuery = "select * from stores";
        if (argv.length ==2 && argv[1].equals("odbc"))
          // either way is fine.
          conn = DriverManager.getConnection(
                 //"jdbc:openlink://163.17.28.223/DSN=pubs", "uid", "pwd");
                 "jdbc:openlink://163.17.28.223/DSN=pubs/UID=uid/PWD=pwd/");
                 // jdbc:openlink://ODBC is type 1 driver which requires
                 // opljodbc2.jar
                 //"jdbc:openlink://ODBC/DSN=pubs/UID=uid/PWD=pwd/");
                 // jdbc:openlink://UDBC is type 2 driver which requires
                 // opljudbc2.jar
                 //"jdbc:openlink://UDBC/DSN=pubs/UID=uid/PWD=pwd/");
        else
          // DSN-less connection
          conn = DriverManager.getConnection("jdbc:openlink://163.17.28.223:5000/SVT=SQLServer 7/DATABASE=pubs/UID=uid/PWD=pwd/FBS=55/Readonly=Y/");
      }

      if (argv[0].equals("dbms"))
      {
        flag++;
        aQuery = "select * from employee";
        if (argv.length ==2 && argv[1].equals("odbc"))
          conn = DriverManager.getConnection(
                 "jdbc:openlink://163.17.11.7/DSN=dbms","uid","pwd");
        else
          conn = DriverManager.getConnection(
                 "jdbc:openlink://163.17.11.7:5000/Database=dbms/UID=uid/PWD=pwd/SVT=SQLServer 7/FBS=60/Readonly=Y");
      }

      if (flag == 0)
      {
        System.out.println("You define wrong DSN. Only pub, dbms, or bob is allowed.");
        System.exit(2);
      }
  
      // Construct a SQL statement and submit it
      Statement aStatement = conn.createStatement();
      ResultSet rs = aStatement.executeQuery(aQuery);

      // Get info about the query results
      ResultSetMetaData rsmeta = rs.getMetaData();
      int cols = rsmeta.getColumnCount();

      // Display column headers
      for(int i=1; i<=cols; i++)
      {
        if(i > 1) System.out.print("\t");
        System.out.print(rsmeta.getColumnLabel(i));
      }
      System.out.print("\n");

      // Display query results.
      while(rs.next())
      {
        for(int i=1; i<=cols; i++)
        {
          if (i > 1) System.out.print("\t");
          System.out.print(rs.getString(i));
        }
        System.out.print("\n");
      }
  
      // Clean up
      rs.close();
      aStatement.close();
      conn.close();
    }
    // a better exception handling can be used here.
    catch (Exception e)
    {
      System.out.println("Exception Occurs: " + e);
    }
  }
}

從 applet 連資料庫的問題

一般來說,以 Java 的安全機制來看,利用 applet 來連結資料庫並不是 一個非常好的方式,我們試著以下列的範例作說明。
  • 試試看下列的程式
    //
    // Example JDBC Applet
    //
    import java.sql.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class OdbcJdbc extends JApplet implements ActionListener
    {
      private String classname = "sun.jdbc.odbc.JdbcOdbcDriver";
      private String jdbcURL = "jdbc:odbc:dbms";
      private String UID = "UID";
      private String PWD = "PWD";
      private Connection conn = null;
    
      private JLabel prompt;
      private JTextField input;
      private JTextArea outputArea;
      private String aQuery = "select * from department";
    
      public void init()
      {
        // create visual presentation
        JPanel p = new JPanel();
        p.setLayout(new FlowLayout(FlowLayout.LEFT));
        prompt = new JLabel("Table Name");
        input = new JTextField(aQuery, 20);
        p.add(prompt);
        p.add(input);
        outputArea = new JTextArea( 10, 30 );
        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        c.add("North", p);
        c.add("Center", new JScrollPane(outputArea));
    
        // register event handler
        input.addActionListener(this);
      }
    
      public void actionPerformed( ActionEvent ev )
      {
        String text = ev.getActionCommand();
        outputArea.setText("");
    
        // Loading JDBC driver
        try {
          Class.forName(classname);
        } catch (Exception e) {
          outputArea.append("Loading JDBC error!\n");
          outputArea.append(e.toString());
          outputArea.append("\n");
        }
    
        try {
          // connect to Database
          conn = DriverManager.getConnection(jdbcURL,UID,PWD);
        } catch (SQLException sqle) {
          outputArea.append("Connection to database error!\n");
        }
    
        showResults(text);
    
        try {
          conn.close();
        } catch (Exception ex) {
          outputArea.append("Connection close error.\n");
        }
      }
    
      private void showResults(String aQuery)
      {
        try {
          // Construct a SQL statement and submit it
          Statement aStatement = conn.createStatement();
          ResultSet rs = aStatement.executeQuery(aQuery);
    
          // Get info about the query results
          ResultSetMetaData rsmeta = rs.getMetaData();
          int cols = rsmeta.getColumnCount();
    
          // Display column headers
          for(int i=1; i<=cols; i++)
          {
            if(i > 1) outputArea.append("\t");
            outputArea.append(rsmeta.getColumnLabel(i));
          }
          outputArea.append("\n");
    
          // Display query results.
          while(rs.next())
          {
            for(int i=1; i<=cols; i++)
            {
              if (i > 1) outputArea.append("\t");
              outputArea.append(rs.getString(i));
            }
            outputArea.append("\n");
          }
    
          // Clean up
          rs.close();
          aStatement.close();
        }
        // a better exception handling can be used here.
        catch (Exception e) {
          outputArea.append("Query error!!\n");
        }
      }
    }
    
  • 你應該會得到下列的錯誤訊息,而造成這個錯誤的原因就是之前所說的 Java Applet 的安全機制(即 sandbox),而這是合理的。想要利用 applet 來連結資料庫,你必須
    1. 如果你把程式中有關 Swing 的元件換成 AWT 的元件,而且使用 JDK 1.1.x 並利用 appletviewer 來看,你應該可以看的到結果。
    2. 對於所要執行的 applets 事先先經過簽章。(不在本課程範圍)
    3. 在 applet 內所欲連結的資料庫同時也存在於你所下載 applet 的網站上。
    4. 除非你使用 multi-tier 的解決方法,這個方法不在 本課程的範圍(除非我們說明了 RMI 或者 CORBA)。
    
    Can't find Database driver class: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.jdbc.odbc)
    
    
    在以下的範例中,我們在 web server 上也安裝了資料庫(我們用 Oracle 8i),
    • 網頁: classes111.zip 為 Oracle 8i 的 thin JDBC pure Java driver.
        <applet codebase="." archive="classes111.zip"
        code="JdbcApplet" width=500 height=200>
        </applet>
        
    • 程式
      // Import the JDBC classes
      import java.sql.*;
      
      // Import the java classes used in applets
      import java.awt.*;
      import java.io.*;
      import java.util.*;
      import java.awt.event.*;
      import javax.swing.*;
      
      public class JdbcApplet extends JApplet implements ActionListener
      {
      
        // The connect string
        static final String connect_string =
                        "jdbc:oracle:thin:@hostname:1521:ora";
      
        // The query we will execute
        static final String query = "select * from dept";
      
        // The button to push for executing the query
        JButton execute_button;
      
        // The place where to dump the query result
        JTextArea output;
      
        // The connection to the database
        Connection conn;
      
        // Create the User Interface
        public void init ()
        {
          Container c = getContentPane();
          c.setLayout (new BorderLayout ());
          execute_button = new JButton ("Hello JDBC");
          c.add ("North", execute_button);
          output = new JTextArea (10, 60);
          c.add ("Center", new JScrollPane(output));
      
          execute_button.addActionListener(this);
        }
      
        // Do the work
        public void actionPerformed (ActionEvent ev)
        {
          try
          {
            // See if we need to open the connection to the database
            if (conn == null)
            {
              // Load the JDBC driver
              DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
      
              // Connect to the databse
              output.append("Connecting to " + connect_string + "\n");
              conn = DriverManager.getConnection(connect_string, "UID", "PWD");
              output.append ("Connected\n");
            }
      
            // Create a statement
            Statement stmt = conn.createStatement ();
      
            // Execute the query
            output.append ("Executing query " + query + "\n");
            ResultSet rset = stmt.executeQuery (query);
      
            // Dump the result
            while (rset.next ())
            {
              output.append (rset.getString (1) + "\t");
              output.append (rset.getString (2) + "\t");
              output.append (rset.getString (3) + "\n");
            }
      
            // We're done
            output.append ("done.\n");
          }
          catch (Exception e)
          {
            // Oops
            output.append (e.getMessage () + "\n");
          }
        }
      }
        
    • 試試看

讀取 Excel 的資料

由於 JDBC-ODBC 是經由 ODBC 來讀取資料,因此只要你設定好一個 Excel 檔而且將其指定給一個 ODBC 的 DSN,那麼 Java 也可以 讀取 Excel 的資料。微軟的 ODBC 驅動程式將 spreadsheet 的第一列 當作資料庫的欄位名稱,而將工作表(worksheet)的名稱當作 資料表(table)的名稱。[註:如果你執行下列的程式卻發現在資料 的最後出現許多的 null 值,請將那些列都在 Excel 反白,並執行 「編輯」--> 「刪除」。]
import java.sql.*;

public class JdbcExcel
{
  static String classname = "sun.jdbc.odbc.JdbcOdbcDriver";
  static String jdbcURL = "jdbc:odbc:grades";
  static String UID = "";
  static String PWD = "";
  static Connection conn = null;

  public static void main( String argv[] )
  {
    // initialize query string
    if(argv.length != 1)
    {
      System.out.println("Usage: java JdbcExcel ");
      System.out.println("   ex. java JdbcExcel A");
      System.exit(2);
    }
    String aQuery = "select * from [" + argv[0] + "$]";

    try
    {
      // load the JDBC-ODBC bridge driver
      Class.forName(classname);

      // connect to Database
      conn = DriverManager.getConnection(jdbcURL,UID,PWD);

      // Display current content
      System.out.println("Display current content");
      ShowResults(aQuery);

      conn.close();
    } catch (Exception sqle)
    {
      System.out.println(sqle);
      System.exit(1);
    }
  }

  private static void ShowResults(String aQuery)
  {
    try
    {
      // Construct a SQL statement and submit it
      Statement aStatement = conn.createStatement();
      ResultSet rs = aStatement.executeQuery(aQuery);

      // Get info about the query results
      ResultSetMetaData rsmeta = rs.getMetaData();
      int cols = rsmeta.getColumnCount();

      // Display column headers
      for(int i=1; i<=cols; i++)
      {
        if(i > 1) System.out.print("\t");
        System.out.print(rsmeta.getColumnLabel(i));
      }
      System.out.print("\n");

      // Display query results.
      while(rs.next())
      {
        for(int i=1; i<=cols; i++)
        {
          if (i > 1) System.out.print("\t");
          System.out.print(rs.getString(i));
        }
        System.out.print("\n");
      }

      // Clean up
      rs.close();
      aStatement.close();
    }
    // a better exception handling can be used here.
    catch (Exception e)
    {
      System.out.println("Exception Occurs.");
    }
  }
}
可是如果你是在一個非 Windows 的環境下而想能夠從你的 Java 程式存取 Excel 檔的資料,那要怎麼辦呢?這時候你就需要藉助 Jarkata 的 POI, 首先你需要下載 Jarkata POI library,並將 poi.jar 設定在你的 CLASSPATH 的環境變數。假設我們的 Excel 檔的資料是一個成績檔,那麼處理的程式 就如以下範例所示。另外,你也可以參考 Elango Sundaram, Excelling in Excel with Java: Learn how to use the Jakarta POI, JavaWorld, 03/2004.
import java.io.*;
import java.text.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.hssf.usermodel.*;

public class TestExcel {
  public static void main(String[] args) {
    DecimalFormat f = new DecimalFormat("###");
    try {
      POIFSFileSystem fs      =
               new POIFSFileSystem(new FileInputStream("ds93f.xls"));
      HSSFWorkbook wb = new HSSFWorkbook(fs);
      HSSFSheet sheet = wb.getSheetAt(0);
      HSSFRow row;
      int i = 0;
      short col = (short) (sheet.getRow(0).getLastCellNum() - 1);
      while((row = sheet.getRow(i)) != null) {
        HSSFCell cell;

        if(i != 0 && 
           row.getCell((short)0).getCellType() == HSSFCell.CELL_TYPE_BLANK)
          break;

        for(short j = 2; j < col; j++) {
          cell = row.getCell(j);
          int status = cell.getCellType();
          switch (status) {
            case HSSFCell.CELL_TYPE_STRING:
              System.out.print(cell.getStringCellValue() + "\t");
              break;
            case HSSFCell.CELL_TYPE_NUMERIC:
              System.out.print(f.format(cell.getNumericCellValue()) + "\t");
              break;
            case HSSFCell.CELL_TYPE_FORMULA:
              System.out.print(f.format(cell.getNumericCellValue()) + "\t");
              break;            
            case HSSFCell.CELL_TYPE_BLANK:
              System.out.print("\t");
              break;            
            default:
              System.out.print("unknown type \t");
          }
        }
        System.out.println("");
        i++;
      }
    } catch (IOException e) {
      System.out.println(e.getMessage());
    }
  }
}


Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu





沒有留言:

張貼留言