通用的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(); // }}