zoukankan      html  css  js  c++  java
  • java实现导出Excel(跨行,跨列)

    先来个最终结果样式:

    第一步: 传参,后期可根据自己需要进行调整。我这里需要的是 

    quarter 代表季度
    dptid 部门编号
    根据接受过来的参数进行文档命名。
    UserInfo userInfo=(UserInfo)request.getSession().getAttribute("userInfo");
        String userid=userInfo.getUserID();
        String quarter = request.getParameter("quarter");
        String dptid = request.getParameter("dptid");
        /***********************EXCEL导出部分**************************/
        String str3 = FileInfoTools.getSystemFilePath()
                + "/documentTemp/";
        File file = new File(str3);
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }
        String names = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date());
        String ourl = str3 +  names + "_"+userid+".xls";
        FileOutputStream fos = null;
        String fileName = "";
        try {
            HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄
            fileName = "安全可控导出"+"_"+userid+"_"+names+".xls";
            DBManager dbm = new DBManager();
            System.out.println("quarter+"+quarter+"dptid="+dptid);
            try{
                dbm.newConnection();
                String str = "select departmentname from dpt_department where departmentid='"+dptid+"'"; //获取唯一id
                String dptName = dbm.executeQueryString(str);
                fileName=dptName+"部门安全可控清单汇总"+"_"+userid+"_"+names+".xls";
                //创建sheet页,并写入内容
                createSheet(dbm,wb,getCardInfo(dbm,quarter,dptid));
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                dbm.closeConnection();
            }
            File ff = new File(ourl);
            if (ff.exists()) {
                ff.delete();
            }
            fos = new FileOutputStream(ourl);
            wb.write(fos);
            fos.close();
            String u = "/project/system/fileAction.do?filePath=" + URLEncoder.encode(ourl)
                    + "&fileName=" + URLEncoder.encode(fileName);
            response.sendRedirect(u);
        } catch (Exception e) {
            e.printStackTrace();
        }

    第二步:创建sheet页签

    public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
            for(int i=0;i<vt.size();i++){
                Hashtable ht = (Hashtable)vt.get(i);
                String id = (String)ht.get("id");
                String quarter = (String)ht.get("quarter");
                HSSFSheet sheet = w.createSheet("安全可控清单");
                //写入数据
                wirteSheet(dbm,sheet,w,id,quarter);
            }
        }

    我这里页签是固定的名称

      

    可根据自己的需要根据参数来进行判断页签。如果多个页签的话 可以这样:

    public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
                Hashtable temp = (Hashtable)vt.get(0);
                String id = (String)temp.get("id");
                String quarter = (String)temp.get("quarter");
                System.out.println("DumpExcel.jsp   id"+id+"quarter:"+quarter);
                //查询得到当前模板对应的页签
                String sheets = "select a7 from a_templet_col_num where templet_id='"+id+"' group by a7  order by a7 ";
                Vector sheetsVc = dbm.executeQueryVector3LowerCase(sheets.toString());
                if (sheetsVc != null && sheetsVc.size() > 0) {
                    for (int i = 0; i < sheetsVc.size(); i++) {
                        Hashtable ht = (Hashtable) sheetsVc.get(i);
                        System.out.println("导出的页签:ht"+ht.get("a7"));
                        HSSFSheet sheet = w.createSheet(ht.get("a7").toString());
                        //写入数据
                        wirteSheet(dbm,sheet,w,id,quarter,ht.get("a7").toString());
                        
                    }
                }
        }

    此处的a7 就是页签的名称 在数据库里有对应。此处id是根据另一个方法里查询的!

     

    多个页签样式

    请注意第一处代码处:createSheet()方法

    createSheet()方法中调用getCardInfo()方法 此方法就是返回你部门的数据。

    public Vector getCardInfo(DBManager dbm,String quarter,String departmentid) throws Exception{
            String sql = "select id,quarter from   a_templet where quarter= "+quarter+" and department="+departmentid;
            Vector vc = dbm.executeQueryVector3LowerCase(sql);
            return vc;
        }

    此处可根据需要来进行返回,不做多解释!

     第三步:写入数据

    每一个页签都会有不同的数据,在创建页签时就会对该页签写入数据。循环操作!

    31.创建表头

    我此处的数据不存在数据库我是固定的。list命名方式自己定义。我这里定义的意义代表他是报表的第几行数据 col是跨几列属性 可根据自己习惯来进行定义

    //第一列数据
    List<Map<String, Object>> listOne = new ArrayList<Map<String, Object>>();
    Hashtable htss = new Hashtable(); htss.put("group_name", +year+"年第"+ji+"季度信息技术情况调研表"); htss.put("col", "10"); listOne.add(htss);

    第二列这里的参数col_name 是为了跟数据库的属性进行对比取值。

    //第二列数据
            Hashtable tweDump = new Hashtable();
            tweDump.put("show_name", "代码");
            tweDump.put("col_name", "a1");;
            listTwe.add(tweDump);
            Hashtable tweDump0 = new Hashtable();
            tweDump0.put("show_name", "代码");
            tweDump0.put("col_name", "a2");;
            listTwe.add(tweDump0);
            Hashtable tweDump1 = new Hashtable();
            tweDump1.put("show_name", "名称");
            tweDump1.put("col_name", "a3");;
            listTwe.add(tweDump1);
            Hashtable tweDump2 = new Hashtable();
            tweDump2.put("show_name", "厂商名称");
            tweDump2.put("col_name", "a4");;
            listTwe.add(tweDump2);
            Hashtable tweDump3 = new Hashtable();
            tweDump3.put("show_name", "厂商性质");
            tweDump3.put("col_name", "a5");;
            listTwe.add(tweDump3);
            Hashtable tweDump4 = new Hashtable();
            tweDump4.put("show_name", "厂商外资国别");
            tweDump4.put("col_name", "a6");;
            listTwe.add(tweDump4);
            Hashtable tweDump5 = new Hashtable();
            tweDump5.put("show_name", "2017年1季度末总数");
            tweDump5.put("col_name", "a7");;
            listTwe.add(tweDump5);
            Hashtable tweDump6 = new Hashtable();
            tweDump6.put("show_name", "2017年2季度新增数量");
            tweDump6.put("col_name", "tbsl");;
            listTwe.add(tweDump6);
            Hashtable tweDump7 = new Hashtable();
            tweDump7.put("show_name", "2017年2季度新增投入金额(万元)");
            tweDump7.put("col_name", "tbje");;
            listTwe.add(tweDump7);
            Hashtable tweDump8 = new Hashtable();
            tweDump8.put("show_name", "备注");
            tweDump8.put("col_name", "a8");;
            listTwe.add(tweDump8);

    第三列。这里下面的循环主要是为了报表上 跨行列跨行显示条线,不多解释

    //第三列数据
            Hashtable Tree = new Hashtable();
            Tree.put("show_name", "大类");
            Tree.put("col_name", "1");;
            listTree.add(Tree);
            Hashtable Tree1 = new Hashtable();
            Tree1.put("show_name", "小类");
            Tree1.put("col_name", "2");;
            for(int i=0;i<9;i++){
                listTree.add(Tree1);
            }

    插入数据:这里需要进行查询数据库操作 。这里我不合并到一起是有原因的。因为每个大类上面有个类别样式

    所以我需要这样做判断。

    //插入的数据
            List<Map<String,Object>> listA = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listB = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listC = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listD = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listE = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listF = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listG = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listH = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listI = new ArrayList<Map<String,Object>>();
            List<Map<String,Object>> listJ = new ArrayList<Map<String,Object>>();
            System.out.println("templetid:"+templetid+"--time:"+time);
            
            //查询数据
            String sql="select  t1.*,t2.*,t3.tbjd,t3.tbje,t3.tbsl  from (select * from a_templet_safe_control_colnum where templet_id='"+templetid+"' order by A2) t1 left join (select A2,count(*) as counts from a_templet_safe_control_colnum where templet_id='"+templetid+"' group by A2) t2 on t1.A2=t2.A2 left join (select * from a_templet_safe_control_colval where tbjd='"+time+"') t3 on t1.id=t3.templet_num_id  where 1=1 ";
            for(int i=0;i<10;i++){
                Vector var =null;
                switch(i){
                    case 0:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='A' ");
                    break;
                    case 1:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='B'  ");
                        break;
                    case 2:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='C'  ");
                        break;
                    case 3:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='D'  ");
                        break;
                    case 4:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='E'  ");
                        break;
                    case 5:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='F'  ");
                        break;
                    case 6:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='G'  ");
                        break;
                    case 7:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='H'  ");
                        break;
                    case 8:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='I'  ");
                        break;
                    case 9:
                        var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='J'  ");
                        break;
                }
            
    if (var != null && var.size() > 0) {
                    for (int j = 0; j < var.size(); j++) {
                        Hashtable ht = (Hashtable) var.get(j);
                        switch(i){
                        case 0:
                            listA.add(ht);
                        break;
                        case 1:
                            listB.add(ht);
                            break;
                        case 2:
                            listC.add(ht);
                            break;
                        case 3:
                            listD.add(ht);
                            break;
                        case 4:
                            listE.add(ht);
                            break;
                        case 5:
                            listF.add(ht);
                            break;
                        case 6:
                            listG.add(ht);
                            break;
                        case 7:
                            listH.add(ht);
                            break;
                        case 8:
                            listI.add(ht);
                            break;
                        case 9:
                            listJ.add(ht);
                            break;
                    }
                    }
                }
    
    
    
     

     把数据添加到对应的list中

    创建表头开始:这里的前三列是固定的可根据自己需求来修改

    //配置显示的固定列数
            int col_num=9;
            //创建表头开始
            HSSFRow row0 = sheet.createRow(0);
            HSSFRow row1 = sheet.createRow(1);
            HSSFRow row2 = sheet.createRow(2);
            for(int j=0;j<col_num;j++){
                HSSFCellStyle s = getTitleStyle(w,2);
                HSSFCell cell0 = row0.createCell(j);
                HSSFCell cell1 = row1.createCell(j);
                HSSFCell cell2 = row1.createCell(j);
                cell0.setCellStyle(s);
                cell1.setCellStyle(s);
                cell2.setCellStyle(s);
            }
            int startCol=0;
            for(int i=0;i<listOne.size();i++){
                Hashtable ht = (Hashtable)listOne.get(i);
                String group_name = (String)ht.get("group_name");
                int colspan =Integer.parseInt((String)ht.get("col"));
                sheet.getRow(0).setHeight((short)600);//设置列高
                HcreateCell(sheet, row0, w, startCol, group_name, 0, 0, startCol, (startCol+colspan-1),0);
                startCol+=colspan;
            }
            startCol=0;
            sheet.getRow(1).setHeight((short)500);//设置列高
            sheet.getRow(2).setHeight((short)500);//设置列高
            for(int i=0;i<listTwe.size();i++){
                Hashtable ht = (Hashtable)listTwe.get(i);
                String show_name = (String)ht.get("show_name");
                //System.out.println("i==="+i+"--"+ht.get("show_name"));
                sheet.setColumnWidth((short)i, (short)4000);//设置列宽
                if(i==0){
                    HcreateCell(sheet, row1, w, startCol, show_name, 1, 1, startCol, 1,i);
                }else{
                    HcreateCell(sheet, row1, w, startCol, show_name, 1, 2, startCol, startCol,i);
                }
                startCol++;
            }
            startCol=0;
            for(int i=0;i<listTree.size();i++){
                Hashtable ht = (Hashtable)listTree.get(i);
                String show_name = (String)ht.get("show_name");
                //System.out.println("i==="+i+"--"+ht.get("show_name"));
                if(i==1||i==0){
                    sheet.setColumnWidth((short)i, (short)2000);//设置列宽
                }
                    HcreateCell(sheet, row2, w, startCol, show_name, 2, 2, startCol, startCol, i);
                    HcreateCell(sheet, row2, w, startCol, show_name, 2, 2, startCol, startCol, i);
                
                startCol++;
            }
            //表头结束

    固定值添加完成,开始数据库的值

    //写入数据
            HSSFRow row=null;
            //样式颜色
            HSSFCellStyle s = getCellStyle(w,1);
            HSSFCellStyle r = getCellStyle(w,2);
            HSSFCellStyle y = getCellStyle(w,3);
            HSSFCellStyle g = getCellStyle(w,4);
            int rowspan=3;
            System.out.println("rowspan==="+rowspan);
            if(listA.size()>0){
                for(int j=0;j<listA.size()+1;j++){
                    row =sheet.createRow(j+3);
                    for(int col=0;col<col_num;col++){
                        HSSFCell cell = row.createCell(col);    
                        cell.setCellStyle(s);
                    }
                }
                for(int j=0;j<listA.size();j++){
                    int nums=0;
                    for(int k=0;k<j;k++){
                        //System.out.println(listA.get(k).get("a1")+"---"+listA.get(j).get("a1"));
                        if(listA.get(k).get("a1").equals(listA.get(j).get("a1"))){ 
                            nums+=1; 
                        }
                    }
                        if(j==0){
                            //System.out.println("列高rowspan==="+rowspan);
                            sheet.getRow(rowspan).setHeight((short)1000);//设置列高
                            createCell(sheet, sheet.getRow(rowspan), w, g, 0, "A", rowspan, rowspan, 0, 0);
                            createCell(sheet, sheet.getRow(rowspan), w, g, 1, "", rowspan, rowspan, 1, 1);
                            createCell(sheet, sheet.getRow(rowspan), w, g, 2, "计算机设备", rowspan, rowspan, 2, 2);
                            createCell(sheet, sheet.getRow(rowspan), w, g, 3, "", rowspan, rowspan, 3, 9);
                            rowspan++;
                        }
                        //System.out.println("列高rowspan==="+rowspan);
                        sheet.getRow(rowspan).setHeight((short)500);//设置列高
                    for(int k=0;k<listTwe.size();k++){
                        //System.out.println("值:"+listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")));
                            //第二行
                                if(k==0){    
                                    //System.out.println("j====="+j+"--"+listA.get(j).get("counts")+"rowspan:"+rowspan+"ID:"+listA.get(j).get("id"));
                                    createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, (listA.size()+3), k, k);
                                }else if(k==1||k==2){
                                    createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan+Integer.parseInt(listA.get(j).get("counts")+"")-1, k, k); //第二列
                                }else{
                                    createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan, k, k);
                                }
                    }    
                    rowspan++;
                }
            }

    我这里做的判断是 刚进入循环代表循环有值时 打印出类别,

    打印类别记得rowspan++操作。因为类别没有在数据库里。如果不做该操作 则会打印时最后一条数据打印不了。因为位置被占了!

    然后在进行循环listTwe第二列的数据 这时候刚才定义的col_name用得上了。循环listA的值看哪个能对应col_name则输出!

    K==0进行判断 k代表 第几列 第一列要跨当前类的所有行,只打印一次。循环完之后进行rowspan++操作 ,让下次循环知道是第几行的,不会覆盖当前行

    一下的listB ...listJ 的类似

    最后还有样式:因为需求需要我在定义样式的时候传入值 num 根据num进行打印不同的背景颜色。可根据需求进行调整

    public static HSSFCellStyle getCellStyle(HSSFWorkbook wb,int num) {
            HSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setWrapText(true);
            if(num==1){
                cellStyle.setFillForegroundColor(HSSFColor.WHITE.index);
            }else if(num==2){
                cellStyle.setFillForegroundColor(HSSFColor.RED.index);
            }else if(num==3){
                cellStyle.setFillForegroundColor(HSSFColor.YELLOW.index);
            }else if(num==4){
                cellStyle.setFillForegroundColor(HSSFColor.GREEN.index);
            }
            cellStyle.setFillPattern(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderBottom((short) 1);
            cellStyle.setBorderLeft((short) 1);
            cellStyle.setBorderRight((short) 1);
            cellStyle.setBorderTop((short) 1);
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
            cellStyle.setBottomBorderColor(HSSFColor.GREY_80_PERCENT.index);
            cellStyle.setLeftBorderColor(HSSFColor.GREY_80_PERCENT.index);
            cellStyle.setRightBorderColor(HSSFColor.GREY_80_PERCENT.index);
            cellStyle.setTopBorderColor(HSSFColor.GREY_80_PERCENT.index);
            cellStyle.setFont(getContentFont(wb,2));
            cellStyle.setLocked(false);
            return cellStyle;
        }

    打印的字体样式: 根据自己的需求来进行修改。

    public static HSSFFont getContentFont(HSSFWorkbook wb,int i) {
            HSSFFont fontStyle = wb.createFont();
            fontStyle.setFontName("微软雅黑");
            if(i==1){
                fontStyle.setFontHeightInPoints((short) 16);
            }else if(i==2){
                fontStyle.setFontHeightInPoints((short) 9);
            }
            fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
            fontStyle.setColor(HSSFColor.GREY_80_PERCENT.index);
            return fontStyle;
        }

    java引用包

    <%@page contentType="text/html; charset=GBK"%>
    <%@page import="java.net.URLEncoder"%>
    <%@page import="java.io.File"%>
    <%@page import="java.io.FileOutputStream"%>
    <%@page import="java.util.*"%>
    <%@page import="java.text.SimpleDateFormat"%>
    <%@page import="java.text.DecimalFormat"%>
    <%@page import="java.math.BigDecimal"%>
    <%@page import="org.apache.poi.hssf.usermodel.*"%>
    <%@page import="org.apache.poi.hssf.util.*"%>

     到这,也就完成了导出操作!

    有什么不懂得可以一起探讨,有比我更便捷的方法或方式,请告知!

     完整代码就不贴了,太多。

     转载请注明出处:http://www.cnblogs.com/huole/p/6141814.html

  • 相关阅读:
    Memcached 笔记与总结(5)Memcached 的普通哈希分布和一致性哈希分布
    大数据价值挖掘:聚焦商业模式探索
    微博商业数据挖掘方法
    微博商业数据挖掘方法
    如何用大数据探索市场营销实践
    如何用大数据探索市场营销实践
    数据挖掘基本任务
    数据挖掘基本任务
    医疗大数据分析深入浅出
    医疗大数据分析深入浅出
  • 原文地址:https://www.cnblogs.com/huole/p/6141814.html
Copyright © 2011-2022 走看看