基于apache POI excel导出,支持多列多条件。

每次用到excel导出基本上都要重新写,这次是写了一个公共的,以后有想用的时侯直接复制就好,大部份都可以兼容,有问题后期再优化。


准备jar包

poi包:http://poi.apache.org/download.html


核心代码

import com.wd.common.anno.Merge;
import com.wd.common.utils.DateUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
 * 
 * <p>导出excel类</p> 
 * @ClassName: ExportExcelUtils     
 * @author: sunhr
 * @date: 2016年8月9日 下午7:18:33   
 * @version: V2.0  
 */
public class ExportExcelUtils<T>
{
   /**
    * 
    * <p>根据对象导出excel表格内容--泛型对象里面的属性顺序就已经确认了excel列的顺序,支持根据多个条件合并多列</p>
    * @author sunhr
    * @date 2016年9月30日 下午5:20:13 
    * @param workbook 是否想要多个sheet页
    * @param sheetName sheet页名称
    * @param heading 第一行标题
    * @param titles 列头
    * @param dataset 表格数据
    * @param mergeCells 要合并的列 -->int[] mergeCells={0,1,2,3,4,9,10,11,12};,根据rowMergeFlag属性值是否相等判别要合并多少行(只要每一行的此属性值相等,便合并)
    * @param total 合计数据
    * @param cols 自定义列宽
    * @return
    * Workbook
    */
   public Workbook ExportExcelMoreMergeCells(Workbook workbook,
                                 String sheetName,
                                 String heading,
                                 String[] titles,
                                 Collection<T> dataset,
                                 Map<String,int[]> mergeCellsMap,
                                 Map<String, Object> total,
                                 Map<Integer, Integer> cols){
      Workbook[] wbs = new Workbook[]{new HSSFWorkbook(), new XSSFWorkbook()};
      //设置表格版本
      Workbook wb = null;
      if(workbook == null){
         wb = wbs[0];
      }else{
         wb = workbook;
      }
      // 创建标题样式
      CellStyle titleStyle = wb.createCellStyle();
      titleStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index);
      titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
      titleStyle.setBorderTop(CellStyle.BORDER_THIN);
      titleStyle.setBorderLeft(CellStyle.BORDER_THIN);
      titleStyle.setBorderRight(CellStyle.BORDER_THIN);
      titleStyle.setBorderBottom(CellStyle.BORDER_THIN);
      titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
      titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);

      Font titleFont = wb.createFont();
      titleFont.setColor(HSSFFont.COLOR_NORMAL);
      titleFont.setFontHeightInPoints((short)11);
      titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
      titleStyle.setFont(titleFont);

      // 创建内容样式
      CellStyle dataStyle = wb.createCellStyle();
      dataStyle.setBorderTop(CellStyle.BORDER_THIN);
      dataStyle.setBorderLeft(CellStyle.BORDER_THIN);
      dataStyle.setBorderRight(CellStyle.BORDER_THIN);
      dataStyle.setBorderBottom(CellStyle.BORDER_THIN);
      dataStyle.setAlignment(CellStyle.ALIGN_CENTER);
      dataStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
      Font dataFont = wb.createFont();
      dataFont.setFontHeightInPoints((short)11);
      dataStyle.setFont(dataFont);

      // 创建工作薄
      Sheet sheet = wb.createSheet(sheetName);
      sheet.setDefaultColumnWidth((short)17);// 默认列宽
      sheet.createFreezePane(0, 2, 0, 2);
      //设置列宽
      if(cols != null){
         for(Map.Entry<Integer, Integer> entry : cols.entrySet()){
            sheet.setColumnWidth(entry.getKey(), entry.getValue());
         }
      }
      Row row = null;
      Cell cell = null;
      // 1. 创建标题(第一行)
      row = sheet.createRow(0);
      sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, (short)(titles.length - 1)));// 合并标题列
      row.setHeightInPoints(20);
      cell = row.createCell(0);
      cell.setCellValue(heading);
      cell.setCellStyle(titleStyle);

      // 2. 创建列头(第二行)
      row = sheet.createRow(1);
      row.setHeightInPoints(20);
      for(short i = 0; i < titles.length; i++){
         cell = row.createCell(i);
         cell.setCellStyle(titleStyle);
         HSSFRichTextString text = new HSSFRichTextString(titles[i]);
         cell.setCellValue(text);
      }

      // 3. 创建内容
      Iterator<T> it = dataset.iterator();
      int index = 1;// 内容启始行     
      String[] rowMergeFlag = new String[mergeCellsMap.size()];// 要合并的数值标识
      int[] startRow = new int[mergeCellsMap.size()];// 要合并的开始行号
      // 初始化起始行
      for(int i = 0; i < startRow.length; i++){
         startRow[i] = index+1;
      }
      int[] endRow = new int[mergeCellsMap.size()];// 要合并的结束行号
      int rowNumber = 1;// 合并后的行号
      // 遍历行
      while(it.hasNext()){
         index++;
         row = sheet.createRow(index);
         T t = it.next();
         Field[] fields = t.getClass().getDeclaredFields();
         // 遍历列
         for(int i = 0; i < fields.length; i++){
            Field field = fields[i];
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

            if(!getMethodName.contains("MergeFlag")){
               cell = row.createCell(i);
               cell.setCellStyle(dataStyle);
            }

            // 第一列为序号
            if(i == 0){
               cell.setCellValue(rowNumber);
               continue;
            }

            Class tCls = t.getClass();
            try{
               Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
               Object value = getMethod.invoke(t, new Object[]{});
               String textVlaue = null;
               if(value != null){
                  boolean continueFlag = false;
                  int mergeCellIndex = -1;
                  for(String key : mergeCellsMap.keySet()){
                     mergeCellIndex++;
                     if(fieldName.equals(key)){
                        if(rowMergeFlag[mergeCellIndex] != null){                          
                           // 验证上一行和下一行是否相等,进行合并。
                           if(rowMergeFlag[mergeCellIndex].equals(value.toString())){
                              endRow[mergeCellIndex] = index;
                              // 最后一行直接全并
                              if(!it.hasNext()){
                                 for(int j = 0; j < mergeCellsMap.get(key).length; j++){
                                    sheet.addMergedRegion(new CellRangeAddress(startRow[mergeCellIndex], endRow[mergeCellIndex], mergeCellsMap.get(key)[j], mergeCellsMap.get(key)[j]));// 合并
                                 }
                              }
                           }else{
                              // 不相等才进行合并
                              if(startRow[mergeCellIndex] < endRow[mergeCellIndex]){
                                 for(int j = 0; j < mergeCellsMap.get(key).length; j++){
                                    sheet.addMergedRegion(new CellRangeAddress(startRow[mergeCellIndex], endRow[mergeCellIndex], mergeCellsMap.get(key)[j], mergeCellsMap.get(key)[j]));// 合并
                                 }
                                 // 行号
                                 if(key.contains("MergeFlagKey")){
                                    rowNumber++;
                                 }
                              }else{
                                 // 行号
                                 if(key.contains("MergeFlagKey")){
                                    rowNumber++;
                                 }
                              }                              
                              startRow[mergeCellIndex] = index;
                           }
                        }else{
                           // 行号
                           if(key.contains("MergeFlagKey")){
                              rowNumber++;
                           }
                        }
                        rowMergeFlag[mergeCellIndex] = value.toString();
                        continueFlag = true;
                     }
                     
                  }
                  // 如果有合并标志位,不用写入excel
                  if(continueFlag){                     
                     continue;
                  }
                  
                  if(value instanceof Date){
                     Date date = (Date)value;
                     textVlaue = DateUtil.fmtDateToStr(date, "yyyy-MM-dd HH:mm:ss");
                  }else if(value instanceof BigDecimal){
                     NumberFormat point = NumberFormat.getCurrencyInstance();
                     point.setMaximumFractionDigits(2);
                     textVlaue = point.format(value);
                  }else{
                     textVlaue = value.toString();
                  }
               }
               if(textVlaue != null){
                  HSSFRichTextString text = new HSSFRichTextString(textVlaue);
                  cell.setCellValue(text);
               }else{
                  cell.setCellValue("");
               }
            }catch(NoSuchMethodException e){
               // TODO Auto-generated catch block
               e.printStackTrace();
            }catch(SecurityException e){
               // TODO Auto-generated catch block
               e.printStackTrace();
            }catch(IllegalAccessException e){
               // TODO Auto-generated catch block
               e.printStackTrace();
            }catch(IllegalArgumentException e){
               // TODO Auto-generated catch block
               e.printStackTrace();
            }catch(InvocationTargetException e){
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      }

      /** 合计处理 */
      // 金额样式
      CellStyle moneyStyle = wb.createCellStyle();
      moneyStyle.setBorderTop(CellStyle.BORDER_THIN);
      moneyStyle.setBorderLeft(CellStyle.BORDER_THIN);
      moneyStyle.setBorderRight(CellStyle.BORDER_THIN);
      moneyStyle.setBorderBottom(CellStyle.BORDER_THIN);
      moneyStyle.setAlignment(CellStyle.ALIGN_RIGHT);
      moneyStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
      Font moneyFont = wb.createFont();
      moneyFont.setColor(HSSFColor.RED.index);
      moneyFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
      moneyStyle.setFont(moneyFont);

      if(total != null){
         if(!it.hasNext()){
            StringBuffer totalVal = new StringBuffer("合计 - ");
            for(String key : total.keySet()){
               String textVlaue = null;
               if(total.get(key) instanceof BigDecimal){
                  NumberFormat point = NumberFormat.getCurrencyInstance();
                  point.setMaximumFractionDigits(2);
                  textVlaue = point.format(total.get(key));
               }
               totalVal.append(key + ":").append(textVlaue + "   ");
            }

            int lastRow = index + 1;
            row = sheet.createRow(lastRow);
            sheet.addMergedRegion(new CellRangeAddress(lastRow, lastRow, 0, (short)(titles.length - 1)));// 合并标题列
            row.setHeightInPoints(20);
            cell = row.createCell(0);
            cell.setCellValue(totalVal.toString());
            cell.setCellStyle(moneyStyle);
         }
      }

      return wb;
   }
}


 

调用导出的javabean

import com.wd.bi.financial.view.StudentConsumeListVW;
import com.wd.bi.financial.view.StudentConsumeVW;
import java.math.BigDecimal;
import java.text.NumberFormat;
/**
 * 
 * <p>导出对象</p> 
 * @ClassName: ExportStudentConsume     
 * @author: sunhr
 * @date: 2016年9月13日 上午9:52:10   
 * @version: V2.0  
 */
public class ExportStudentConsume extends IExportStudentConsume{
   
   /* 标识,必须在第一行 */
   private Integer serialNumber = 0; // 序号(必须要的属性)   

   /* 实际要输出的列 */
   private String studentName;//学生姓名
   
   // 合
   private String schoolNameStr;
   
   // 合
   private String contactStr;
   
   private String serialNum;
   // 合
   private String classPeriodNameStr;   
   private String teacherName;//授课教师
   
   // 合
   private String personalProgressStr;  
   
   private String attendCountStr;// 消耗
   
   private String remindCountStr;//剩余
   
   private BigDecimal projectRemindMoney = new BigDecimal(0);//项目剩余总金额
   
   private BigDecimal studentAccount=new BigDecimal(0);//账户金额
   
   private String manager;//班主任、学管
   
   private String signName;//签单人
   
   private String signTime;//首课时间
   
   /* ............................................... */
   
   /* 标识 必须在最后 (必须包含MergeFlag字符) */
   private String studentIdMergeFlagKey ; //行合并标识(为Excel的主键,必须包含MergeFlagKey)
   private String modelMergeFlag;// 行合并条件学生Model
   
   public ExportStudentConsume() {
      super();
   }
   
   public void initialize(StudentConsumeListVW sc,StudentConsumeVW scv){
      this.setStudentName(sc.getStudentName());
      this.setSchoolName(sc.getSchoolName());
      this.setStudentGradeName(sc.getStudentGradeName());
      this.setContactMobile(sc.getContactMobile());
      this.setContactName(sc.getContactName()); 
      this.setSerialNum(scv.getSerialNum());
      this.setClassPeriodName(scv.getClassPeriodName());
      this.setPeriodNum(scv.getPeriodNum());
      this.setTeacherName(scv.getTeacherName());
      this.setPersonalProgress(scv.getPersonalProgress());
      this.setCourseCount(scv.getCourseCount());
      this.setAttendCount(scv.getAttendCount());
      this.setAttendMoney(scv.getAttendMoney());
      this.setRemindCount(scv.getRemindCount());
      this.setRemindMoney(scv.getRemindMoney());
      this.setChargeType(scv.getChargeType());
      this.setProjectRemindMoney(scv.getProjectRemindMoney());
      this.setStudentAccount(scv.getStudentAccount());
      this.setManager(scv.getManager());
      this.setSignName(scv.getSignName());
      this.setSignTime(scv.getSignTime());
      this.setStudentIdMergeFlagKey(String.valueOf(sc.getStudentId()));
      this.setModelMergeFlag(String.valueOf(sc.getStudentId()+"-"+scv.getModel()));
   }
   

   public Integer getSerialNumber(){
      return serialNumber;
   }

   public void setSerialNumber(Integer serialNumber){
      this.serialNumber = serialNumber;
   }

   public String getStudentName(){
      return studentName;
   }

   public void setStudentName(String studentName){
      this.studentName = studentName;
   }

   public String getSchoolNameStr(){
      return String.format("%s %s", super.getSchoolName(),super.getStudentGradeName());
   }

   public String getContactStr(){
      return String.format("%s %s", super.getContactMobile(),super.getContactName());
   }

   public String getSerialNum(){
      return serialNum;
   }

   public void setSerialNum(String serialNum){
      this.serialNum = serialNum;
   }

   public String getClassPeriodNameStr(){
      if(super.getPeriodNum() != null){
         return String.format("%s %s", super.getClassPeriodName(),super.getPeriodNum());               
      }
      return super.getClassPeriodName();
   }

   public String getTeacherName(){
      return teacherName;
   }

   public void setTeacherName(String teacherName){
      this.teacherName = teacherName;
   }

   public String getPersonalProgressStr(){      
      return  String.format("%s/%s%s", super.getPersonalProgress(),super.getCourseCount(),super.getUnit());
   }

   public String getAttendCountStr(){
      NumberFormat point = NumberFormat.getCurrencyInstance();
      point.setMaximumFractionDigits(2);
      return  String.format("%s %s%s", super.getAttendCount(),super.getUnit(),point.format(super.getAttendMoney()));
   }

   public String getRemindCountStr(){
      NumberFormat point = NumberFormat.getCurrencyInstance();
      point.setMaximumFractionDigits(2);
      
      return  String.format("%s %s%s", super.getRemindCount(),super.getUnit(),point.format(super.getRemindMoney()));
   }

   public BigDecimal getProjectRemindMoney(){
      return projectRemindMoney;
   }

   public void setProjectRemindMoney(BigDecimal projectRemindMoney){
      this.projectRemindMoney = projectRemindMoney;
   }

   public BigDecimal getStudentAccount(){
      return studentAccount;
   }

   public void setStudentAccount(BigDecimal studentAccount){
      this.studentAccount = studentAccount;
   }

   public String getManager(){
      return manager;
   }

   public void setManager(String manager){
      this.manager = manager;
   }

   public String getSignName(){
      return signName;
   }

   public void setSignName(String signName){
      this.signName = signName;
   }

   public String getSignTime(){
      return signTime;
   }

   public void setSignTime(String signTime){
      this.signTime = signTime;
   }

   
   public String getStudentIdMergeFlagKey(){
      return studentIdMergeFlagKey;
   }

   public void setStudentIdMergeFlagKey(String studentIdMergeFlagKey){
      this.studentIdMergeFlagKey = studentIdMergeFlagKey;
   }

   public String getModelMergeFlag(){
      return modelMergeFlag;
   }

   public void setModelMergeFlag(String modelMergeFlag){
      this.modelMergeFlag = modelMergeFlag;
   }
}


import java.math.BigDecimal;
/**
 * 
 * <p>导出对象(临时使用的属性,不做导出)</p> 
 * @ClassName: StudentConsumeExport     
 * @author: sunhr
 * @date: 2016年9月12日 下午7:09:44   
 * @version: V2.0  
 */
public class IExportStudentConsume{
   
   // 合
   private String schoolName;//学校名称
   private String studentGradeName;// 学级
   
   // 合
   private String contactName;//主联系人称谓
   private String contactMobile;//主联系方式   
   
   // 合
   private String classPeriodName;//学习项目(课程名称)
   private Integer periodNum;//班级期数
   
   // 合
   private BigDecimal personalProgress=new BigDecimal(0);//个人进度
   private BigDecimal courseCount=new BigDecimal(0);//报名次数
   
   private BigDecimal attendCount=new BigDecimal(0);//本月消耗次数
   private BigDecimal attendMoney=new BigDecimal(0);//本月消耗金额
   
   private BigDecimal remindCount=new BigDecimal(0);//剩余次数
   
   private BigDecimal remindMoney=new BigDecimal(0);//剩余金额
   
   private Integer chargeType;///班级期收费标准
   private String unit;// 单位
   
   
   public String getSchoolName(){
      return schoolName;
   }
   public void setSchoolName(String schoolName){
      this.schoolName = schoolName;
   }
   public String getStudentGradeName(){
      return studentGradeName;
   }
   public void setStudentGradeName(String studentGradeName){
      this.studentGradeName = studentGradeName;
   }
   public String getContactName(){
      return contactName;
   }
   public void setContactName(String contactName){
      this.contactName = contactName;
   }
   public String getContactMobile(){
      return contactMobile;
   }
   public void setContactMobile(String contactMobile){
      this.contactMobile = contactMobile;
   }
   public String getClassPeriodName(){
      return classPeriodName;
   }
   public void setClassPeriodName(String classPeriodName){
      this.classPeriodName = classPeriodName;
   }
   
   public Integer getPeriodNum(){
      return periodNum;
   }
   
   public void setPeriodNum(Integer periodNum){
      this.periodNum = periodNum;
   }
   
   public BigDecimal getPersonalProgress(){
      return personalProgress;
   }
   public void setPersonalProgress(BigDecimal personalProgress){
      this.personalProgress = personalProgress;
   }
   public BigDecimal getCourseCount(){
      return courseCount;
   }
   public void setCourseCount(BigDecimal courseCount){
      this.courseCount = courseCount;
   }
   public BigDecimal getAttendCount(){
      return attendCount;
   }
   public void setAttendCount(BigDecimal attendCount){
      this.attendCount = attendCount;
   }
   
   public BigDecimal getAttendMoney(){
      return attendMoney;
   }
   public void setAttendMoney(BigDecimal attendMoney){
      this.attendMoney = attendMoney;
   }
   public BigDecimal getRemindCount(){
      return remindCount;
   }
   public void setRemindCount(BigDecimal remindCount){
      this.remindCount = remindCount;
   }
   public BigDecimal getRemindMoney(){
      return remindMoney;
   }
   public void setRemindMoney(BigDecimal remindMoney){
      this.remindMoney = remindMoney;
   }
   public Integer getChargeType(){
      return chargeType;
   }
   public void setChargeType(Integer chargeType){
      this.chargeType = chargeType;
   }
   public String getUnit(){
      if(this.getChargeType() != null){
         if(getChargeType() == 1 || getChargeType() == 2){
            return "次";
         }else if(getChargeType() == 3 || getChargeType() == 4){
            return "月";
         }else{
            return "课时";
         }
      }
      return "";
   }
}
使用案例

        // sheet页名称
        String sheetName ="学生课耗分析";
        /* 表头处理 */
        StringBuffer topParam = headerProcess(studentConsumeParam);
        /** .............................................................................. */   
        /* 合计 */        
        Map<String, Object> total = new LinkedHashMap<String, Object>();
        total.put("课耗收入", studentConsumeParam.getAttendMoney());
        total.put("剩余学费", studentConsumeParam.getRemindMoney());
        total.put("个人账户", studentConsumeParam.getStudentAccount());
        /** .............................................................................. */
        // 合并列,必须和实体类一样key
        int[] StudentId=new int[]{0,1,2,3,10};
        Map<String,int[]> mergeCellsMap=new HashMap<String,int[]>();
        mergeCellsMap.put("studentIdMergeFlagKey", StudentId);
        mergeCellsMap.put("modelMergeFlag", new int[]{9});
        // 设置指定列宽度
        Map<Integer,Integer> cols=new HashMap<Integer,Integer>();
        cols.put(4, 1000*2*4);
        cols.put(5, 1000*2*5);
        
        String topName = studentConsumeParam.getMonthNum()+"月份学生课耗统计-"+"("+topParam.toString()+")";
        String[] title = {"序号","姓名","学校","电话","电子票号","学习项目","授课教师","个人进度","产生课耗","剩余课耗","总剩余","个人账户","班主任/学管师","签单人","首课时间"};
        ExportExcelUtils<ExportStudentConsume> eet = new ExportExcelUtils<ExportStudentConsume>();
        Workbook wb = eet.ExportExcelMoreMergeCells(null,sheetName, topName, title,exportstudentconsumeList,mergeCellsMap,total,cols);
        HttpServletResponse resp = inv.getResponse();
        try {
           resp.setHeader("Content-disposition", "attachment;filename="+new String(sheetName.getBytes("GB2312"),"ISO8859_1")+".xls");
           OutputStream out = resp.getOutputStream();
           wb.write(out);
           out.close();
        } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
        } catch (IOException e) {
           e.printStackTrace();
        }
这个应该已经写的很详细了,有疑问可以问我哟。



本文链接:http://blog.csdn.net/u010264560/article/details/52870301
本文作者:CSDN - jerry.sun

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值