通用的excel报表生成工具类

下面这个工具类是今天半天的劳动成果。

以后自己也可能用得到。在此做一个记录。涉及公司的信息的代码以及注释已经删除。哈哈。。。。

依赖了开源的POI工具包,网址:http://poi.apache.org/

 

这个工具类自己还没经过严格测试,简单测了一下,大体差不多是OK 的。

源码中注释掉的部分即为测试代码

 

上源码罗:

 

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.util.CollectionUtils;


/**
 * 生成Excel报表工具类
 */
public class ExcelProductUtil {

    /**
     * 生成列数固定格式的报表
     * 
     * @param contentList 报表的内容
     * @param title  报表头描述以及T对象的属性描述
     *                Map<String,String>:key : T对象的属性描述
     *                                   value:报表头文字描述 
     * @param seq    关联属性在报表中出现的顺序
     *        Map<String,String>:key : T对象的属性描述 
     *                           value:属性对应的顺序  
     * @param sheetName sheet的名称
     * @param rowNum 起始行(大于等于0)
     * 
     * 注意: title与seq均不能为空
     *      seq中的key必须与title的Key完全一致    
     *      seq中的value必须是从1开始的连续正整数   
     *      title中的Key必须来自于T的属性名称 
     *               
     */
    public static HSSFWorkbook productReportSameColumn(List<? extends Object> contentList,
                                                       Map<String, String> title,
                                                       Map<String, Integer> seq, 
                                                       String sheetName,
                                                       int rowNum) {
        //创建新的Excel工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        try {
            //校验title中的属性值必须在T中存在
            checkBeforeReportSameColumn(contentList, title, seq, sheetName, rowNum);

            HSSFSheet sheet = getSheet(sheetName, workbook);

            //生成报表的头部描述信息
            createReportSameColumnHead(sheet, title, seq, rowNum);

            //生成报表的文件体
            createReportSameColumnBody(sheet, title, contentList, seq, rowNum);

        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return workbook;
    }

    /**
     * 创建新的Excel工作薄
     * @param sheetName
     * @return
     */
    private static HSSFSheet getSheet(String sheetName, HSSFWorkbook workbook) {
        HSSFSheet sheet = workbook.createSheet(sheetName);
        return sheet;
    }

    /**
     * 生成报表的文件体
     * 
     * @param workbook
     * @param title
     * @param contentList
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    private static void createReportSameColumnBody(HSSFSheet sheet, Map<String, String> title,
                                                   List<? extends Object> contentList,
                                                   Map<String, Integer> seq, int rowNum)
                                                    throws IllegalArgumentException,
                                                               IllegalAccessException 
    {
        ++rowNum;
        for (Object content : contentList) {

            HSSFRow row = sheet.createRow(rowNum);

            Field[] fields = content.getClass().getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                String name = f.getName();
                if (title.containsKey(name)) {

                    HSSFCell cell = row.createCell(seq.get(name));
                    cell.setCellValue((String) f.get(content));
                }
            }
            ++rowNum;
        }
    }

    /**
     * 生成报表的头部描述信息
     * 
     * @param workbook
     * @param title
     */
    private static void createReportSameColumnHead(HSSFSheet sheet, Map<String, String> title,
                                                   Map<String, Integer> seq, int rowNum) {
        //获取排序之后的属性列表
        List<Map.Entry<String, Integer>> headDesList = getSoredPropertisList(seq);

        HSSFRow row = sheet.createRow(rowNum);

        for (Map.Entry<String, Integer> entry : headDesList) {
            String headName = title.get(entry.getKey());
            HSSFCell cell = row.createCell(entry.getValue());
            cell.setCellValue(headName);
        }
    }

    /**
     * 获取排序之后的属性列表
     * 
     * @param seq
     * @return
     */
    private static List<Map.Entry<String, Integer>> getSoredPropertisList(Map<String, Integer> seq) {

        List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(seq
            .entrySet());

        //排序
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
        });
        return list;
    }

    /**
     * 校验title中的属性值必须在T中存在
     * 
     * @param contentList
     * @param title
     */
    private static void checkBeforeReportSameColumn(List<? extends Object> contentList,
                                                    Map<String, String> title,
                                                    Map<String, Integer> seq, 
                                                    String sheetName,
                                                    int rowNum) {
        if (CollectionUtils.isEmpty(contentList) || CollectionUtils.isEmpty(title)
            || CollectionUtils.isEmpty(seq) || StringUtil.isBlank(sheetName)) {
            throw new RuntimeException("传入参数不能为空!");
        }
        if (rowNum < 0) {
            throw new RuntimeException("rowNum必须大于等于0!");
        }

        //获取T的属性名称
        List<String> propertiesNamesOfT = getTPropertiesName(contentList.get(0));

        //获取title的属性名称
        List<String> titlesNames = getTitleNames(title);

        //属性比较
        compareProperties(propertiesNamesOfT, titlesNames);

        //seq中的key必须与title的Key完全一致
        compareKey(title, seq);

        //seq中的value必须是从1开始的连续正整数
        compareSeqValue(seq);
    }

    /**
     * seq中的value必须是从1开始的连续正整数
     * 
     * @param seq
     */
    private static void compareSeqValue(Map<String, Integer> seq) {

        List<Map.Entry<String, Integer>> list = getSoredPropertisList(seq);

        if (list.get(0).getValue() != 1 || list.get(list.size() - 1).getValue() != list.size()) {
            throw new RuntimeException("seq中的value必须是从1开始的连续正整数");
        }

    }

    /**
     * seq中的key必须与title的Key完全一致
     * 
     * @param title
     * @param seq
     */
    private static void compareKey(Map<String, String> title, Map<String, Integer> seq) {
        Set<String> titleSet = title.keySet();
        Set<String> seqSet = seq.keySet();

        if (titleSet.size() != seqSet.size()) {
            throw new RuntimeException("seq中的key必须与title的Key必须完全一致!");
        }

        Set<String> titleTempSet = new HashSet<String>();
        titleTempSet.addAll(titleSet);
        titleTempSet.addAll(seqSet);
        if (titleTempSet.size() != seqSet.size()) {
            throw new RuntimeException("seq中的key必须与title的Key必须完全一致!");
        }
    }

    /**
     * 属性比较:titlesNames是否在propertiesNamesOfT中存在
     * 
     * @param propertiesNamesOfT
     * @param titlesNames
     */
    private static void compareProperties(List<String> propertiesNamesOfT, List<String> titlesNames) {
        List<String> tempPropertiesNamesOfT = new ArrayList<String>();
        List<String> tempTitlesNames = new ArrayList<String>();

        //对数组中的字符串转换成小写
        for (String tName : propertiesNamesOfT) {
            String temp = tName.toLowerCase();
            tempPropertiesNamesOfT.add(temp);
        }
        for (String tName : titlesNames) {
            String temp = tName.toLowerCase();
            tempTitlesNames.add(temp);
        }
        if (!tempPropertiesNamesOfT.containsAll(titlesNames)) {
            throw new RuntimeException("title中的某些属性值在T对象中不存在!");
        }
    }

    /**
     * 获取title的属性名称
     * 
     * @param title
     * @return
     */
    private static List<String> getTitleNames(Map<String, String> title) {
        List<String> titleNames = new ArrayList<String>();
        for (Map.Entry<String, String> entry : title.entrySet()) {
            titleNames.add(entry.getKey());
        }
        return titleNames;
    }

    /**
     * 获取T的属性名称
     * 
     * @param t
     * @return
     */
    private static List<String> getTPropertiesName(Object o) {
        List<String> list = new ArrayList<String>();

        Field[] fields = o.getClass().getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            list.add(f.getName());
        }
        return list;
    }

    //    private static class BankLog {
    //        private String name;
    //        private String password;
    //
    //        public String getName() {
    //            return name;
    //        }
    //
    //        public void setName(String name) {
    //            this.name = name;
    //        }
    //
    //        public String getPassword() {
    //            return password;
    //        }
    //
    //        public void setPassword(String password) {
    //            this.password = password;
    //        }
    //    }
    //
    //    public static void main(String[] args) throws Exception {
    //
    //        List<BankLog> bankLog = new ArrayList<BankLog>();
    //        BankLog bankLog1 = new BankLog();
    //        bankLog1.setName("111");
    //        bankLog1.setPassword("222");
    //        BankLog bankLog2 = new BankLog();
    //        bankLog2.setName("0000");
    //        bankLog2.setPassword("333");
    //        bankLog.add(bankLog1);
    //        bankLog.add(bankLog2);
    //
    //        Map<String, String> title = new HashMap<String, String>();
    //        title.put("name", "名字");
    //        title.put("password", "密码");
    //
    //        Map<String, Integer> seq = new HashMap<String, Integer>();
    //        seq.put("name", 2);
    //        seq.put("password", 1);
    //
    //        String sheetName = "Sheet1";
    //        int rowNum = 1;
    //
    //        HSSFWorkbook book = productReportSameColumn(bankLog, title, seq, sheetName, rowNum);
    //        String filename = "text.xls";
    //        FileOutputStream fOut = new FileOutputStream(filename);
    //        book.write(fOut);
    //        fOut.flush();
    //        fOut.close();
    //    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值