java处理excel的一点实践积累

作者:佟亮    日期:2008-11-06

1   文档说明

   目的:编写本文档主要的目的是与大家分享下如何用java处理excel,文档中的代码一部分来自《企业项目管理系统V2.0》的源码,一部分copy网上的。

     背景:使用Windows操作系统的同事对Excel(电子表格)一定不会陌生,但是要使用Java语言来操纵Excel文件并不是一件容易的事。在Web应用日益盛行的今天,通过Web来操作Excel文件的需求越来越强烈。

2   需求

    本部分与技术无关,没兴趣的同事可以跳过直接看下一章。

   之所以我要把“需求”单列出来讲讲,是因为通过实现这个需要,我学到的不只是技术,更重要的是思想和工作的方式。客户的原始需求是,在web系统实现数据以表格的形式录入,然后对这些数据能够进行公式计算处理(一部分表格里面配置的是公式)。当时接到这个需求的时候,我们二话没说直接用js画表格,js实现公式的计算。结果由于客户不断的按照excel中的功能要求我们实现,我们终于吃不消了,要知道联通的这个需求实际上是excel的全部功能呀。闭门造车的我们殊不知早在几年前就已经有类似的weboffice中间件了。造成我们有这么失误的主要原因是思想的局限和工作方式的死板,所以这是我的一个教训,希望看到文档的同事引以为鉴。之后我们引用了金格公司的weboffice2003这个中间件,其实我们用的只是通过这个中间件将excel在jsp页面打开,然后将excel的内容用他封装的提交方式发送给action,然后我们在action、Bo、dao中处理这个excel,其中如何处理excel就是我接下来要讲的。

3   技术实现

要学习java处理excel,首先大家需要了解jxl这个包,我们引用的所有方法都来自这个包,我的介绍也主要围绕着这个包里的类和方法展开。

3.1   读excel

3.1.1  读取本地excel文件

读取Excel数据表的第一步是创建Workbook(术语:工作薄)。

      InputStream is = new FileInputStream(sourcefile[w1] );

      Workbook wb = Workbook.getWorkbook(is);

创建了Workbook对象,我们就可以通过它来访问Excel Sheet(术语:工作表)。

Sheet rs = rwb.getSheet(0[w2] );

类似这样还可以取到Cell对象,以及cell的相应属性信息。大家可以查看jxl的api文档。 

此外,当你完成对Excel电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要。  wb.close();

3.1.2  读取数据库文件

与读取本地excel类似,区别在于输入流的获取。一般excel在数据库以blob类型存储,所以我们在查询的时候要读blob字段,获取输入流。

代码如下:

InputStream instream = vField[w3] .getBinaryStream();

3.2   写excel文件

3.2.1  创建excel文件

3.2.1.1 创建方式

          1、写到本地文件

    WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile[w4] ));

                 2、直接写入到输出流   

    ByteArrayOutputStream outs = new ByteArrayOutputStream();

    WritableWorkbook wb = Workbook.createWorkbook(outs);

3.2.1.2 创建步骤

                 1、创建可写的Workbook[w5] (createWorkbook)。

2、创建可写的Sheet[w6] (createSheet)。

3、如果想美化生成的excel可以创建WritableFont,WritableCellFormat来设定颜色,字体等

4、添加Number对象,.添加Boolean对象,添加DateTime对象,添加Label对象及使用mergeCells方法合并单元格。

5、写入Exel工作表 wb.write();

6、关闭Excel工作薄对象wb.close();

详细代码见备注4.1

3.2.2  修改excel文件

3.2.2.1 获取方式

1、本地文件

InputStream is = new FileInputStream(sourcefile[w7] );

ByteArrayOutputStream outs = new ByteArrayOutputStream();

2、数据库对象

InputStream instream = vField[w8] .getBinaryStream();

ByteArrayOutputStream outs = new ByteArrayOutputStream();

 

 

3.2.2.2 修改步骤

1、创建可写的Workbook[w9] 。

wwbook = Workbook.createWorkbook(outstream, this.rwbook,new WorkbookSettings());

接下来的操作和创建excel一样,返回的都是一个输出流。你可以对这个输出流做你想要的操作。

详细代码见备注4.2

4   备注

4.1   创建excel文件代码举例

//1.添加Label对象

Label labelC = new jxl.write.Label(0, 0, "This is a Label cell");

ws.addCell(labelC);

//添加带有字型Formatting的对象

jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);

jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);

jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF);

ws.addCell(labelCF);

//添加带有字体颜色Formatting的对象

jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,

UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED);

jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);

jxl.write.Label labelCFC = new jxl.write.Label(1, 0, "This is a Label Cell", wcfFC);

ws.addCell(labelCF);

//2.添加Number对象

jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926);

ws.addCell(labelN);

//添加带有formatting的Number对象

jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");

jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);

jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN);

ws.addCell(labelNF);

//3.添加Boolean对象

jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false);

ws.addCell(labelB);

//4.添加DateTime对象

jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date());

ws.addCell(labelDT);

//添加带有formatting的DateFormat对象

jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss");

jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df);

jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF);

ws.addCell(labelDTF);

4.2   修改excel文件代码举例

/**

     * <p>Description: 初始化模板信息</p>

     * <p>Remark: </p>

             * @return

     * @throws ServiceException

     */

    public AccessoryVO doInit(String initExtId,String departmentCode) throws ServiceException

    {

        AccessoryVO accessoryVO = new AccessoryVO();

        /*重新初始化,通过初始化编号获得规划模板编号*/

        String templateExtId = initDAO.getTemplateIdByInitId(initExtId);

        String rpSno = initDAO.getRpSno(templateExtId);

        FilloutVO filloutVO = new FilloutVO();

        filloutVO.setRpSno(rpSno);

        filloutVO.setDepartmentCode(departmentCode);

        List list= initDAO.getHistoryData(filloutVO);

       // initDAO.updateFilloutStatus("5",initExtId);

        /*获得初始化模板*/

        InputStream ins = initDAO.getExcelTemplate(templateExtId);

        /*获得空附件输出流*/

        ByteArrayOutputStream outs = new ByteArrayOutputStream();

      

        createExcel(ins,outs,list);

        accessoryVO.setAccessoryBody(outs.toByteArray());

        //initDAO.updateRpStatus("5",rpSno);

        try

        {

            if(outs!=null)

            {

                outs.close();

            }

            if(ins!=null)

            {

                ins.close();

            }

        }

        catch (IOException e)

        {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

      

        return accessoryVO;

    }

 

    /**

     * <p>Description: 生成带初始化数据的excel</p>

     * <p>Remark: </p>

     * @return

     * @throws ServiceException

     */

    public String createExcel(InputStream ins,OutputStream outs,List list)

            throws ServiceException

    {

            changeWorkbookByStream(ins,outs);

             try

             {

             WritableWorkbook book = null;

             book = this.wwbook;

             //设置格式

             jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#,###");

             jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);

             wcfN.setBorder(Border.ALL,BorderLineStyle.THIN);

             wcfN.setVerticalAlignment(VerticalAlignment.CENTRE);

           

             int length = list.size();

             WritableSheet rs = null;

             RdVO vo = null;

             //循环取得处理sheet数据

             for(int j = 0;j<length;j++){

                 vo = (RdVO)list.get(j);

                 sheetId = vo.getSheetId();

                 cellRow = vo.getCellRow();

                 cellColumn = vo.getCellColumn();

                 rpData = NullProcessUtil.nvlToString(vo.getRpData(), "0");

                 rs = (WritableSheet)book.getSheet(Integer.parseInt(sheetId));

                 labeltemp = new Number( Integer.parseInt(cellColumn),Integer.parseInt(cellRow), Double.parseDouble(rpData),wcfN);

                 ((WritableSheet) rs).addCell(labeltemp);

             }

             book.write();

             //关闭book,释放资源

             book.close();

             rwbook.close();

             }catch(Exception e){      

                 errorMsg = e.getMessage();

                 //errorMsg += "  错误在行 :"+rowTemp+" 列:"+colTemp;

                 System.out.println("出错了啊!!"+errorMsg);

                 System.out.println(e);

                 e.printStackTrace();

                 return this.errorMsg;

             }

             return this.errorMsg;

        }

    /**

     * 变更取得Workbook的方式为流获取

     * @author

     * @date Jun 2, 2008

     * @return void

     */

    public void changeWorkbookByStream(InputStream instream,OutputStream outstream) {

                try {

                    this.rwbook = Workbook.getWorkbook(instream);

                    System.out.println("this.wbook init() OK!!");

                } catch (IOException e) {

                    e.printStackTrace();

                } catch (BiffException e) {

                    e.printStackTrace();

                }

                try {

                    this.wwbook = Workbook.createWorkbook(outstream, this.rwbook,new WorkbookSettings());

                   

                   

                } catch (IOException e) {

                    e.printStackTrace();

                }

               

    }