POI通用导出Excel数据(包括样式设计)
2016-10-19 11:16
465 查看
前言
前一段时间我写过通用的导入Excel,前几天也写了导出pdf格式的,还有我之前搞得导出Word,我在之前的博客也都介绍了导出和导入是一个道理,无非是一个获取一个是赋值。昨天有一位同仁看了我的Excel通用导入导出那个源码,说不是太懂。顺道今天整理了一下导出那块的知识,导入我之前已经介绍的很详细了。今天我们就来说说Excel导出的那些事!前期准备
jar包下载,我们使用对Excel,Word操作的都是借助poi来实现的,所以首先我们需要下载jar包。POI 下载 猛戳我
代码解析
通过javabean来实现数据的导出
数据准备:String[] headers = { "学号", "姓名", "年龄", "性别", "出生日期" }; List<Student> dataset = new ArrayList<Student>(); dataset.add(new Student(10000001, "张三", 20, true, new Date())); dataset.add(new Student(20000002, "李四", 24, false, new Date())); dataset.add(new Student(30000003, "王五", 22, true, new Date()));
然后我用导出的工具类开始导数据
ExportExcel<Student> ex = new ExportExcel<Student>(); ex.exportExcel(headers, dataset, out);
ExportExcel是我写的一个模板,这个模板下面有两个exportExcel这个方法,一个是穿map数据的,另一个是传javabean的,我们上面穿的是javabean所以会调用javabean的方法。也就是说exportExcel会调用下面这个方法
最终我们调用的是exportExcelByBean这个方法。
下面我们详细解说exportExcelByBean这个方法内容。
1、首先声明一个Excel工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
2、生成一个表格,传的title就是表格sheet也得名字
HSSFSheet sheet = workbook.createSheet(title);
3、设置表格默认宽度
sheet.setDefaultColumnWidth((short) 15);
4、设置样式
HSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(HSSFColor.SKY_BLUE.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
需要补充一下,我设置这个样式就是让导出Excel变得美观一点,你可以不要这个。
设置导出的字体样式并把这个字体加入到上面那个样式中
// 生成另一个字体 HSSFFont font2 = workbook.createFont(); font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); // 把字体应用到当前的样式 style2.setFont(font2);
其他的一些样式设置
“`
// 声明一个画图的顶级管理器
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
// 定义注释的大小和位置,详见文档
HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
0, 0, 0, (short) 4, 2, (short) 6, 5));
// 设置注释内容
comment.setString(new HSSFRichTextString(“可以在POI中添加注释!”));
// 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
comment.setAuthor(“leno”);
设置表格的表头
// 产生表格标题行 HSSFRow row = sheet.createRow(0); for (short i = 0; i < headers.length; i++) { HSSFCell cell = row.createCell(i); cell.setCellStyle(style); HSSFRichTextString text = new HSSFRichTextString(headers[i]); cell.setCellValue(text); }
到这里表格的容器样式已经设置完了,下面就是导出数据到我们准备的Excel中了。
拿到集合中的所有javabean
Iterator<T> it = dataset.iterator();
在遍历数据的时候我们用的既然javabean就需要用到反射机制,这个简单的介绍一下反射这个神奇的东西。
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 Field[] fields = t.getClass().getDeclaredFields();
然后遍历属性,拿到单一属性后判断该用get还是is方法
Field field = fields[i]; String fieldName = field.getName(); String[] split=field.toString().split(" "); String getMethodName=""; if("boolean".equalsIgnoreCase(split[1])||"bool".equalsIgnoreCase(split[1])){ getMethodName = "is" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); }else { getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); }
然后就是通过反射区调用javabean的方法获取值了
Class tCls = t.getClass(); Method getMethod = tCls.getMethod(getMethodName,new Class[] {}); Object value = getMethod.invoke(t, new Object[] {});
我们获取到了值,现在我们就需要对值进行判断了,如果是日期类型的,我们需要指定格式输出到Excel中,如果是数字我们就输出数字,如果是字符串我们输出字符串,如果是bool那么我们根据需求输出两种值得其中一种。
// 判断值的类型后进行强制类型转换 String textValue = null; if (value instanceof Boolean) { boolean bValue = (Boolean) value; textValue = "男"; if (!bValue) { textValue = "女"; } } else if (value instanceof Date) { Date date = (Date) value; SimpleDateFormat sdf = new SimpleDateFormat(pattern); textValue = sdf.format(date); } else if (value instanceof byte[]) { // 有图片时,设置行高为60px; row.setHeightInPoints(60); // 设置图片所在列宽度为80px,注意这里单位的一个换算 sheet.setColumnWidth(i, (short) (35.7 * 80)); // sheet.autoSizeColumn(i); byte[] bsValue = (byte[]) value; HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6, index); anchor.setAnchorType(2); patriarch.createPicture(anchor, workbook.addPicture( bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG)); } else { // 其它数据类型都当作字符串简单处理 textValue = value.toString(); }
然后就是将数据写入Excel
if (textValue != null) { Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$"); Matcher matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { HSSFRichTextString richString = new HSSFRichTextString( textValue); HSSFFont font3 = workbook.createFont(); font3.setColor(HSSFColor.BLUE.index); richString.applyFont(font3); cell.setCellValue(richString); } }
最后写出这个工作簿
try { workbook.write(out); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
调用说明,OutputStream out = new FileOutputStream(“D://zxh//test//a.xls”);
给一个输出流 工Excel输出,如果是JavaWeb中应用,那就直接将这个工作簿输出到前台让浏览器下载就行了。
通过Map来实现数据的导出
通过Map的好处就是我们不用去准备javabean了,也就自然没有反射那块难点了,既方便有易懂,何乐而不为呢。也就是说最后我们选择的是
exportExcelByMap
这个方法
基于上面javabean介绍的很详细了,我这个map就不在赘述了,我只说一下关键点的地方,通过Map和通过javabean的,我们的表格样式是不变的,所以不一样的地方就是在遍历数据的时候讲数据赋值到Excel中的,最后输出的那个也不便,说白了就是获取数据的方式不一样了,javabean我是通过反射获取的,如果用了map我们直接用get就行了。
for(int i=0;i<list.size();i++){
Map<String, Object> map = list.get(i);
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style2);
//拿到第一个数据
for(String field : headers){
//遍历字段进行顺序赋值
Object value = map.get(field);
// 判断值的类型后进行强制类型转换 String textValue = null; if (value instanceof Boolean) { boolean bValue = (Boolean) value; textValue = "男"; if (!bValue) { textValue = "女"; } } else if (value instanceof Date) { Date date = (Date) value; SimpleDateFormat sdf = new SimpleDateFormat(pattern); textValue = sdf.format(date); } else if (value instanceof byte[]) { // 有图片时,设置行高为60px; row.setHeightInPoints(60); // 设置图片所在列宽度为80px,注意这里单位的一个换算 sheet.setColumnWidth(i, (short) (35.7 * 80)); // sheet.autoSizeColumn(i); byte[] bsValue = (byte[]) value; HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6, index); anchor.setAnchorType(2); patriarch.createPicture(anchor, workbook.addPicture( bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG)); } else { // 其它数据类型都当作字符串简单处理 textValue = value.toString(); }
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成if (textValue != null) { Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$"); Matcher matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { HSSFRichTextString richString = new HSSFRichTextString( textValue); HSSFFont font3 = workbook.createFont(); font3.setColor(HSSFColor.BLUE.index); richString.applyFont(font3); cell.setCellValue(richString); } }
}
}
try { workbook.write(out); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
总结
整个博客我一直强调,用Map好,因为现在JavaWeb中框架主流是mybatis等框架,而这些框架封装的数据库数据正好就是通过map格式传输的,所以我们直接获取的就是Map数据,然后直接传到我的方法中就可以导出了,就不用javabean了。源码下载 猛戳!!!!
相关文章推荐
- POI通用导出Excel数据(包括样式设计)
- 详解JAVA POI导出EXCEL报表的操作(包括各种格式及样式的实现)
- 详解JAVA POI导出EXCEL报表的操作(包括各种格式及样式的实现)
- POI分sheet导出Excel或者zip通用高速方法(万条数据以上)
- 通用方法:用建立Excel对象的方法来导出数据
- Ext2.0的通用grid包括(增、删、改、查、导出excel) (转)
- 用POI把数据导出为Excel
- 通用导出数据到Excel ,效率有点低,希望大家能提提意见
- 导出数据到Excel表中--用Apache的POI实现简单封装
- Java程序员从笨鸟到菜鸟之(一百零四)java操作office和pdf文件(二)利用POI实现数据导出excel报表
- Java使用POI实现数据导出excel报表
- 使用poi将数据导出为excel文件的几点注意
- 使用Apache的POI,将数据导出至EXCEL
- 使用Java POI导入导出Excel数据
- Java程序员从笨鸟到菜鸟之(一百零五)java操作office和pdf文件(三)利用jxl实现数据导出excel报表以及与POI的区别
- Java程序员从笨鸟到菜鸟之(一百零四)java操作office和pdf文件(二)利用POI实现数据导出excel报表
- POI : 解决大批量数据导出Excel产生内存溢出的方案
- 基于struts2、spring、ibatis、poi的案例,将数据导出致Excel中
- Ext2.0的通用grid包括(增、删、改、查、导出excel)
- 使用JDBC+POI把Excel中的数据导出到MySQL