java 根据任意List<Object>输出excel表格
原来阿里的easyexcel有这个功能,我这个代码还是留在这里吧,就当是练习注解和反射了
-------------------------------------------------------
使用方法:将自定义的pojo类,添加到list中,直接调用输出类的out方法就可以
(注意:这个pojo类的属性上必须使用自定义注解,index属性用来标识该属性放在哪一列,value则标示输出的中文列名)目前支持的属性:String、int、double、Date
准备两个类:1.自定义注解类、2.输出类
用到的依赖,这些依赖也可以用其他类似的工具类替换
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.8.1</version> </dependency>
自定义注解类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelCell {
//输出列的中文列名
String value();
//该属性输出列的位置
int index();
}
输出类:
/** * * @author: hrw * time: 2022/9/17 12:15 * description:根据list<Object>直接输出excel文件 */ public class ExcelOutUtilByList { static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * @param fileName 文件名,不包含后缀 * @param path excel保存路径,不包含文件名 * @param data 数据list,里面的pojo属性需要有注解@ExcelVaue,才能识别 * @param sdf2 自定义时间格式化类,传null则使用默认格式 “yyyy-MM-dd HH:mm:ss” * @param comment 备注,会显示在标题旁边 * @return 文件位置 */ public static String out(String fileName, String path, List data,SimpleDateFormat sdf2,String comment) { if (fileName.contains(".")) { fileName = fileName.substring(0, fileName.indexOf(".")); } if (data == null || data.size() < 1) { return "没有数据"; } Map indexMap = new HashMap(); Map titleMap = new HashMap(); Class<?> aClass = data.get(1).getClass(); boolean isOk = getValueIndex(new ArrayList(), titleMap, indexMap, aClass);//获取列名和位置 if (!isOk) { return "所有参数都没有@ExcelCell注解,读取列名失败"; } Method[] methods = aClass.getMethods();//获取方法列表 //创建表格 HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(fileName + 1); setHerderRow(fileName,titleMap,wb,comment);//设置标题栏 和样式 第1行 setCellName(titleMap,indexMap,wb,sheet);//设置列名 第2行 HSSFCellStyle style = getContent(wb);//获取单元格样式 for (int i = 0; i < data.size(); i++) {//循环插入数据 从第三行开始插入 HSSFRow row = sheet.createRow(i + 2); Set indexSet = indexMap.keySet(); Iterator iterator = indexSet.iterator(); while (iterator.hasNext()) { String keyParam = (String) iterator.next(); int index = (int) indexMap.get(keyParam); Object o = data.get(i); for (Method method : methods) { if (method.getName().equals(keyParam)) { HSSFCell cell = row.createCell(index - 1); String type = method.getGenericReturnType().toString(); try { if (type.equals("int")) { //取出来的值类型跟excel支持的类型匹配 int value = (int) method.invoke(o,null); cell.setCellValue(value); } else if (type.equals("class java.util.Date")) { Date value = (Date) method.invoke(o,null); String format = ""; if (sdf2 != null) { format = sdf2.format(value); } else { format = sdf.format(value);//Date类先格式化成String再存到cell的value中 } cell.setCellValue(format); } else if (type.equals("double")) { double value = (double) method.invoke(o,null); cell.setCellValue(value); } else { String value = (String) method.invoke(o,null); cell.setCellValue(value); } cell.setCellStyle(style); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } } //输出文件 String fileName2 = path + fileName + ".xls"; File file = new File(fileName2); //创建文件输出流 try { FileOutputStream fileOutputStream = new FileOutputStream(file); //用最开始创建的工作簿.write进行文件写出 wb.write(fileOutputStream); } catch (IOException e) { e.printStackTrace(); System.out.println("导出excel异常:" + e.getMessage()); return "导出excel异常:" + e.getMessage(); } System.out.println("导出成功:" + fileName2); return fileName2; } /** * 根据标题栏创建 各个列名 * @param titleMap 位置-中文标题 * @param indexMap 属性名-位置 * @param wb * @param sheet */ private static void setCellName(Map titleMap, Map indexMap, HSSFWorkbook wb,HSSFSheet sheet) { HSSFRow row = sheet.createRow(1); HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); // 居中 style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());// 设置背景色 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setBorderBottom(BorderStyle.THIN); //下边框 style.setBorderLeft(BorderStyle.THIN);//左边框 style.setBorderTop(BorderStyle.THIN);//上边框 style.setBorderRight(BorderStyle.THIN);//右边框 Set set = indexMap.keySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { String cellName = (String) iterator.next();//英文属性名 int index = (int) indexMap.get(cellName);//对应位置 sheet.autoSizeColumn(index-1);//自动列宽 HSSFCell cell = row.createCell(index - 1); cell.setCellValue((String) titleMap.get(index));//将中文名设置进去 cell.setCellStyle(style); } } /** * 设置sheet页的标题栏和样式 * @param fileName * @param titleMap * @param wb * @param comment */ private static void setHerderRow(String fileName,Map titleMap,HSSFWorkbook wb,String comment) { HSSFSheet sheet = wb.getSheetAt(0); HSSFCell cell = sheet.createRow(0).createCell(0); if (comment != null && comment.length() > 0) {//设置备注 fileName += "(" + comment +")"; } cell.setCellValue(fileName);//第一行第一列设置为标题栏 HSSFCellStyle style = wb.createCellStyle(); style.setBorderBottom(BorderStyle.THIN); //下边框 style.setBorderLeft(BorderStyle.THIN);//左边框 style.setBorderTop(BorderStyle.THIN);//上边框 style.setBorderRight(BorderStyle.THIN);//右边框 // style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置加粗 HSSFFont font1 = wb.createFont(); font1.setColor((short)16);; font1.setFontHeightInPoints((short)18); style.setFont(font1); style.setAlignment(HorizontalAlignment.CENTER); sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleMap.size()-1));//合并标题栏 cell.setCellStyle(style); } /** * 根据要输出的类属性上的注解,获取标题栏和列位置 * @param count 固定传空list * @param titleMap * @param indexMap * @param classzz * @return */ public static boolean getValueIndex(List count,Map titleMap,Map indexMap, Class<?> classzz) { boolean flag = true; Field[] fields = classzz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; ExcelCell annotation = field.getAnnotation(ExcelCell.class); if (annotation == null) { continue; } String name = fields[i].getName(); name = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); indexMap.put(name, annotation.index()); titleMap.put(annotation.index(),annotation.value()); count.add(1); } if (classzz.getSuperclass() != null) { getValueIndex(count,titleMap,indexMap,classzz.getSuperclass()); } if (count.size() == 0) { flag = false; System.out.println("所有参数都没有@ExcelCell注解,读取列名失败"); } return flag; } /** * 设置数据的单元格格式 * @param wb * @return */ public static HSSFCellStyle getContent(HSSFWorkbook wb){ HSSFCellStyle style = wb.createCellStyle(); style.setBorderBottom(BorderStyle.THIN); //下边框 style.setBorderLeft(BorderStyle.THIN);//左边框 style.setBorderTop(BorderStyle.THIN);//上边框 style.setBorderRight(BorderStyle.THIN);//右边框 return style; } }
测试用的pojo
public class Suanshu { @ExcelCell(value = "参数1",index = 1) private int oneCell; @ExcelCell(value = "参数2",index = 2) private int twoCell; @ExcelCell(value = "加法结果",index = 3) private String jiafaResult; @ExcelCell(value = "减法结果",index = 4) private String jianfaResult; @ExcelCell(value = "乘法结果",index = 5) private String chengfaResult; get set等等方法。。。 }
输出效果: