JXL制作属于自己的excel导入导出报表工具(一)背

系统 1345 0

   从事JAVA开发一年多了,大约有半年都在搞Excel导入导出吧.刚刚交接项目时,还是个对Java有些陌生,有些惧怕的.但是因为人都走光了,项目中只有咱一个开发了,只能担起全部的开发维护责任,也慢慢成长了起来.项目中以前的Excel导出用的JXL,因为客户的特殊需求,导出并非平时那么简单,涉及到分页(每sheet一页),还要将数据合并.架构师写了分页的代码,并写了某个报表的导出类,然后其他工程师CV,即便对于当时没多少经验的我来说,这也很没意思,很不好,但是事已至此,我也就只能随波逐流了.

  直到到某一天,客户提出了由于政策变更要重新制作一套报表的需求,我才意识到问题的严重性,这样一个类一个类的改,不止麻烦,而且要实现客户的那些格式要求(如某列需要加粗,某单元格有上下左边框等等)都十分麻烦,还会大大增加代码复杂度(需要在各种循环里判断),于是萌生了重新构架导出功能的想法.

 

--------------------以上为发泄心情,可以忽略不看--------------------

 

  做java的必然要有面向对象的意识,万物皆为对象,报表亦如此.一个Excel报表,我将其分为七个部分,那就是首页头信息(只出现在第一页),头信息(每页都有),动态信息,尾信息(每页都有),尾页尾信息(只出现在最后一页),统计信息(所有数据之后的那行),页码信息(位置不固定).如下图所示:

              JXL制作属于自己的excel导入导出报表工具(一)背景和思路

  参考了hibernate的orm思想,将excel与对象映射起来,但由于早期,并不会写DTD,于是就用某类的静态成员变量来充当配置文件.报表中的动态信息需要用一个集合来表示,集合中的每个对象代表Excel中动态信息的一行,每个成员变量代表Excel中的一个单元格.其他的头尾信息之类,可以用一个对象来表示.下面简要的介绍一下整体思路.

  首先,我们需要准备好模板,用JXL读取模板,并将其sheet复制一份出来,在新的sheet上输出数据,以免影响到模板上的原有数据.之后,当然是根据情况分页,将数据分成几个list,每个list代表一页的数据,然后循环输出,自然循环中的控制变量i就成了页码.对于i为0的时候也就是第一页,要将首页头信息输出,其他的情况下,则要把首页头信息的内容清空(模板上写的那部分).之后输出相应的头信息动态信息尾信息,之后需要判断是否是最后一页,对于最后一页我们需要输出尾页尾信息,其他页我们需要清空模板中的尾页尾信息.这样报表摸板便完成了,不敢说这样可以应对任何报表,但是对于多数报表,我们以后要做的只是配置七大部分的格式,与对象的映射,就足够产生一个xls文件了.

  以下便是核心代码部分的简要的介绍.

   

    // 读取模板
     tempBook = Workbook.getWorkbook(new File(inPath), workbookSettings);
     // 创建目标对象
     book = Workbook.createWorkbook(new File(outPath), tempBook);
  WritableSheet copySheet=book.getSheet(0);
  WritableSheet sheet=null;
     //拆分动态数据集
     List[] lists;
     //没有动态数据
     if(report.getDynamic()==null)
     {
      book.copySheet(0,report.getName(), 1);
      sheet=book.getSheet(1);
      //填充静态数据的方法参数3代表对应的输出对象,参数4为包含配置的对象,参数5为相对位置,参数6页码
      fillStaticData(sheet, copySheet, staticData, report.getFirsthead(), 0,1);
     }
     else
     {
      //分页
      lists=paging(dynamicData);
      int position=0;//相对位置
      for(int i=0;i<lists.length;i++)
      {
       position=0;
       book.copySheet(0,report.getName(),i+1);//复制新sheet
       sheet=book.getSheet(i+1);
       if(report.getFirsthead()!=null)//首页
       {
        if(i==0)//输出首页头信息
        {
         position+=fillStaticData(sheet, copySheet,staticData, report.getFirsthead(),0, i); 
        }
        else //清空头信息
        {
         JXXUtil.cutRange(sheet, 0, 0, report.getFirsthead().getRows(), report.getFirsthead().getColumns());
         JXXUtil.blankRange(sheet, 0, 0, report.getFirsthead().getRows(), report.getFirsthead().getColumns());
        }
       }
       //输出头信息
       position+=fillStaticData(sheet, copySheet,staticData, report.getAllhead(),position, i);
       if(report.getDynamic().getStartRow()!=0)
       {
        position=report.getDynamic().getStartRow();
       }
       //写入动态数据
       fillDynamicCell(sheet, copySheet, lists[i], position, report.getDynamic());
       //相对位置的计算
       position+=lists[i].size();
       if(i!=lists.length-1)//末页
       {
        if(report.getLasttail()!=null)
        {
         JXXUtil.cutRange(sheet, position+1, 0,position+1+report.getLasttail().getRows(), report.getLasttail().getColumns());
         JXXUtil.blankRange(sheet,position+1, 0,position+1+report.getLasttail().getRows(), report.getLasttail().getColumns());
        }
       }
       position+=fillStaticData(sheet, copySheet,staticData, report.getAlltail(),position, i);
       if(report.getLasttail()!=null)
       {
        if(i==lists.length-1)//末页
        {
         fillStaticData(sheet, copySheet,staticData, report.getLasttail(),position, i); 
        }
       }
      }
     }
     book.removeSheet(0);
   book.write();
   tempBook.close();
     book.close();
  

  具体的实现以及JXL处理Excel上的一些困难,以后都会一一介绍,这次就写到这了.

JXL制作属于自己的excel导入导出报表工具(一)背景和思路


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论