前言

  • 前一段时间我写过通用的导入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数据(包括样式设计)的更多相关文章

  1. HTML导出Excel数据类型转换样式参考

    mso-number-format:"0" NO Decimals mso-number-format:"0/.000" 3 Decimals mso-numb ...

  2. Java利用POI导入导出Excel中的数据

         首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...

  3. [转] Asp.Net 导出 Excel 数据的9种方案

    湛刚 de BLOG 原文地址 Asp.Net 导出 Excel 数据的9种方案 简介 Excel 的强大之处在于它不仅仅只能打开Excel格式的文档,它还能打开CSV格式.Tab格式.website ...

  4. (gridcontrol等)通用导出excel z

    关于DevExpress Winform 的所有可打印控件的导出excel 的通用方法,并且解决DevExpress控件自带的方法存在的缺陷问题 1.解决GridControl自带方法不能导出图片: ...

  5. java的poi技术读取Excel数据

    这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: ja ...

  6. C# 使用Epplus导出Excel [5]:样式

    C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...

  7. POI导入导出excel(附工具类)

    关于POI导出excel的功能我在前面的文章已经写过了,POI导出excel的三种方式 , 导出表格数据到excel并下载(HSSFWorkbook版) ,本篇文章主要是将导入导出功能进一步地封装,在 ...

  8. java的poi技术读取Excel数据到MySQL

    这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...

  9. oracle-sql脚本导出EXCEL数据

    在数据库中,经常有业务人员提出需求导出数据库中的业务数据,而且是每天.每周或每月定时导出.为了方便,可将sql查询的脚本 通过下面脚本来导出EXCEL数据. 1.将查询sql脚本(AAA.sql)放到 ...

随机推荐

  1. Python中文件的读写操作

    文件操作基本流程: 1. 介绍 计算机系统是由计算机硬件,操作系统,和应用程序三部分组成. 内存 存放不持久 硬盘 可以使数据持久化 文件操作  数据持久化的一种 全栈开发  框架类 2. 文件的操作 ...

  2. php中对象类型与数组之间的转换

    1.刚看视频学习的时候看到一个困扰很久的问题, 有时候我们在进行做项目的时候会碰到的一个小问题.举一个小例子.  获取一个xml文件里面的数据. xml.xml文件如下: <?xml versi ...

  3. 利用jenkins实现自动构建、部署,提升团队开发效率

    一大早就被群里的同学刷银川下雪的消息,看着我都发冷,突觉一阵凉风裹身,是不是该考虑秋裤了. 偏离主题,正文走起...... 使用jenkins目标:利用其结合maven完成自动构建,并部署到tomca ...

  4. mysql语句优化原则

    有时候发现数据量大的时候查询起来效率就比较慢了,学习一下mysql语句优化的原则,自己在正常写sql的时候还没注意到这些,先记录下来,慢慢一点一点的学,加油! 这几篇博客写的都可以: https:// ...

  5. .NET多线程之Thread、Task、ThreadPool、Timer

    下表为多线程操作常见对象: 对象 方法/属性 描述 用途 用法 性能 Thread(线程) Start 启动线程,启动后线程处于System.Threading.ThreadState.Running ...

  6. vue组件之间的传值——中央事件总线与跨组件之间的通信($attrs、$listeners)

    vue组件之间的通信有很多种方式,最常用到的就是父子组件之间的传值,但是当项目工程比较大的时候,就会出现兄弟组件之间的传值,跨级组件之间的传值.不可否认,这些都可以类似父子组件一级一级的转换传递,但是 ...

  7. Tomcat CGIServlet enableCmdLineArguments远程代码执行_CVE-2019-0232漏洞复现

    Tomcat CGIServlet enableCmdLineArguments远程代码执行_CVE-2019-0232漏洞复现 一.漏洞描述 该漏洞是由于tomcat CGI将命令行参数传递给Win ...

  8. 将web工程署到Linux简单实现

    1,将数据库文件导出并导入到Linux下的数据库中 2,将数据库连接池的连接IP改为Linux所在服务器的 3,将工程文件以war包形式导出 4,利用secureCRT,Xshell等工具远程连接Li ...

  9. Cesium 学习(二)所支持的模型数据类型,以及转换

    1.Cesium所支持的模型数据类型 目前所知的有glTF.glb.bgltf等格式的模型数据: 想要了解glTF等的知识可以看一下https://www.cnblogs.com/fuckgiser/ ...

  10. Cobbler-自动化部署神器

    Cobbler-自动化部署神器 前言: 网络安装服务器套件 Cobbler(补鞋匠)从前,我们一直在做装机民工这份很有前途的职业.自打若干年前 Red Hat 推出了 Kickstart,此后我们顿觉 ...