4.5 在JSP中访问Excel

在JSP页面访问Excel可以将一些信息以表格的形式打印出来,下面介绍在JSP页面中访问Excel的方法。

实例086 通过ODBC访问Excel

本实例是一个典型的、操纵Excel的程序

实例位置:光盘\mingrisoft\04\086

实例说明

有些时候数据是保存在Excel表格内的,那么能否在JSP页面中显示Excel表格内的信息呢?答案是肯定的,本实例将实现这一功能。运行本实例,如图4.43所示,其中的数据为从Excel表格内查询出的数据。

图4.43 通过ODBC访问Excel

技术要点

采用JDBC方式连接数据库时,在url中给出的是数据库的路径,例如:

        String url = jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_database04;

而在连接Excel时,需要采用JDBC-ODBC方式,即在服务器上为要操作的Excel建立ODBC数据源,这时url中给出的是数据源名称,例如本例的url为:

        DriverManager.getConnection("jdbc:odbc:operateExcel");   //operateExcel为数据源名称

实现过程

(1)建立ODBC数据源,步骤如下。

① 单击“我的电脑”→“控制面板”→“管理工具”→“数据源(ODBC)”,打开“ODBC数据源管理器”对话框,单击“系统DSN”标签。

② 单击“添加”按钮,在弹出的对话框中选择Driver do Microsoft Excel(*.xls)。

③ 单击“完成”按钮,在弹出的对话框中填写数据源名(本例使用的数据源名为operateExcel),单击“选择工作簿”按钮,在弹出的对话框(见图4.44)的中间选择要访问的Excel文件的路径,然后在对话框左侧选中该文件,再在对话框的右侧去掉“只读”属性(否则不允许向文件插入记录),最后连续单击“确定”按钮,返回到“ODBC数据源管理器”对话框,会发现新建的数据源已经在列表当中了。

图4.44 选择Excel文件

注意:Microsoft的ODBC驱动程序把Excel表中的第一行作为字段名,把Excel文件名作为数据表名。

(2)创建操作Excel的JavaBean(OperateExcel.java)。首先,在静态块中指定数据库的连接方式(JDBC-ODBC桥连接);然后编写建立连接的方法open(),指定ODBC数据源的名称“operateExcel”;接着编写关闭连接的方法close();最后编写查询方法select()。关键代码如下:

        public class OperateExcel {
            private Connection con = null;
            private Statement stmt = null;
            private ResultSet rs = null;
            static{                                 //加载驱动
                try {
                    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                } catch (Exception e) {
                    System.out.println("加载驱动时抛出异常,内容如下:");
                    e.printStackTrace();
                }
            }
            public OperateExcel() {
            }
            public void open(){                       //建立连接
                try {
                    con = DriverManager.getConnection("jdbc:odbc:operateExcel");
                    stmt = con.createStatement();
                } catch (SQLException e) {
                    System.out.println("建立连接时抛出异常,内容如下:");
                    e.printStackTrace();
                }
            }
            public void close(){                      //关闭连接
                try {
                    rs.close();
                    con.close();
                } catch (SQLException e) {
                    System.out.println("关闭连接时抛出异常,内容如下:");
                    e.printStackTrace();
                }
            }
            public ResultSet select(){                //查询方法
                try {
                    rs = stmt.executeQuery("select * from [sheet1$]");
                } catch (SQLException e) {
                    System.out.println("在查询记录时抛出异常,内容如下:");
                    e.printStackTrace();
                }
                return rs;
            }
            public void insert(){                     //添加数据
        }
        public void update(){                   //修改excel文件内容
        }
        }

(3)创建index.jsp页面,读取Excel数据表中的数据。首先,应用java.sql包中的ResultSetMetaData类,获得表格字段总数。通过getColumnCount()方法获得表格总列数。然后,应用getColumnName(int i)方法获得指定列的名称,入口参数i为指定列的索引值,第一列的索引值为1,不是0。关键代码如下:

        table width="100%"  border="1"cellspacing="0"cellpadding="4">
        <%
            OperateExcel operate = new OperateExcel();
            operate.open();
            ResultSet rs=operate.select();
            try {
                ResultSetMetaData RSMD=rs.getMetaData();       //获得表格字段总数
                int columnCount=RSMD.getColumnCount();         //获得表格总列数
        %>
            <tr align="center">
                <%
                    for (int i = 1; i <= columnCount; i++) {
                %>
                <td><%=RSMD.getColumnName(i) %></td>
                <%
                    }
                %>
            </tr>
            <%
                    while(rs.next()){            //获得和打印记录
                %>
                <tr align="center">
                <%
                    for (int i = 1; i <= columnCount; i++) {
                        String str="";
                        if(i==1){
                            str=""+rs.getInt(i);
                        }else{
                            str=rs.getString(i);
                            if(str==null||str.equals("null")){
                                str="&nbsp;";
                            }
                        }
                %>
                    <td><%=str %></td>
                <%
                    }
                %>
                </tr>
                <%
                    }
            }catch (SQLException e) {
                e.printStackTrace();
            }finally{
                if(rs!=null){
                    operate.close();
                }
            }
                %>
        </table>

注意:在JSP中操作Excel时支持插入、修改和查询操作,但不支持删除操作。

举一反三

根据本实例,读者可以:

试着编写插入和修改Excel表中数据的方法;

在编写企业人事管理系统时,将人事档案从数据库导出到Excel。

实例087 利用Java Excel访问Excel

本实例是一个典型的操纵Excel的程序

实例位置:光盘\mingrisoft\04\087

实例说明

在开发管理软件时,经常需要将一些数据生成表格后打印,这就要求在JSP页面访问Excel,前面介绍了通过ODBC访问Excel的方式,但是并没有以Excel文件格式显示,在这里将介绍另一种访问方式,即通过开源项目Java Excel访问Excel,并介绍如何将数据以Excel文件的方式显示在JSP页面。图4.45所示为本例的运行结果,即在JSP页面打开Excel。

图4.45 在JSP中显示Excel信息

技术要点

如果想灵活地运用Java Excel,首先要了解Java Excel API,下面简单介绍Java Excel API中常用类提供的方法。

(1)Workbook类提供的方法。

● getNumberOfSheets():返回值类型为int型,用来获得工作簿(workbook)中工作表(sheet)的个数。

● getSheet(int index)和getSheet(String name):返回值类型为int型,分别通过工作表下标和名称获得指定工作表。

● getSheetNames():返回值类型为String[]型,用来获得工作簿中所有工作表的名称。

● getSheets():返回值类型为Sheet[]型,用来获得工作簿中所有工作表对象。

(2)Sheet类提供的方法。

● getName():返回值类型为String型,用来获得当前工作表名称。

● getRows():返回值类型为int型,用来获得当前工作表的记录数。

● getColumns():返回值类型为int型,用来获得当前工作表的字段数。

● getCell(int column,int row):返回值类型为Cell型,用来获得当前工作表指定的单元格,需要注意的是第一个参数为列,第二个参数为行。

● getRow(int row):返回值类型为Cell[]型,用来获得当前工作表指定行的所有单元格。

● getColumn(int column):返回值类型为Cell[]型,用来获得当前工作表指定列的所有单元格。

(3)Cell类提供的方法

● getRow():返回值类型为int型,用来获得当前单元格所在的行。

● getColumn():返回值类型为int型,用来获得当前单元格所在的列。

● getType():返回值类型为CellType型,用来获得当前单元格值的类型。

● getContents():返回值类型为String型,用来获得当前单元格的值。

● getCellFormat():返回值类型为CellFormat型,用来格式化单元格内容。

实现过程

(1)获得Java Excel开源包(jxl.jar)。

可以到http://www.andykhan.com/jexcelapi/download.html页面下载最新版本,并解压缩(本例采用的是2.6版本),然后将jxl.jar文件复制到Web工程的WEB-INF/lib文件夹下,或者通过开发工具将其导入工程。

注意:运行本例可以省去该步,在此列出该步主要是为了让读者知道在哪里可以获得最新版本。这也是运用其他插件的一般步骤。

(2)编写业务逻辑类(OperateExcel.java)。通过循环遍历Excel单元格,利用JSP的内置对象out将内容输出到JSP页面的Excel单元格中,代码如下:

        public static void readExcel(JspWriter out, String filePath) {
          try {
            //通过输入流创建Workbook(工作簿)对象
            InputStream inStr=new FileInputStream(filePath);
            Workbook workBook=Workbook.getWorkbook(inStr);
            //有两种方法获取Sheet(工作表)对象,分别是通过工作表的名称或下标,下标从0开始
            //Sheet sheet=workBook.getSheet("name");            //通过名字
            Sheet sheet=workBook.getSheet(0);                   //通过下标
            //获取工作表内容的行数和列数
            int rows=sheet.getRows();
            int columns=sheet.getColumns();
            //通过工作表对象创建Cell(单元格)对象
            Cell cell=null;
            out.print("<table>");
            for(int m=0;m<rows;m++){
                out.print("<tr align='center'>");
                for (int n = 0; n < columns; n++) {
                out.print("<td>");
                cell = sheet.getCell(n, m);
                if (cell.getType() == CellType.NUMBER) {
                    NumberCell numCell = (NumberCell) cell;
                    double num = numCell.getValue();
                    int a = (int) num;
                    out.print(a);
                } else {
                    String cellContent = cell.getContents();
                    out.print(cellContent);
                }
                out.print("</td>");
                }
                out.print("</tr>");
            }
            out.print("</table>");
            workBook.close();    //关闭对象,释放内存
            } catch (Exception e) {
            System.out.println("异常内容如下:");
            e.printStackTrace();
            }
        }

(3)创建index.jsp页面,设置容器类型为application/vnd.ms-excel,并调用readExcel()方法,读取Excel中的数据,代码如下:

        <%@ page contentType="text/html; charset=GBK" %>
        <%@ page import="java.io.File" %>
        <%@ page import="java.io.OutputStream" %>
        <%@ page import="mrgf.*" %>
        <%@ page import="jxl.*" %>
        <%
        response.reset();
        response.setCharacterEncoding("GBK");               //指定编码格式
        response.setContentType("application/vnd.ms-excel");      //设置容器类型
        OperateExcel.readExcel(out,getServletContext().getRealPath("test.xls"));       //调用readExcel()方法
        %>

举一反三

根据本实例,读者可以:

实现以网页形式输出Excel中的数据。