最近工作中需要导出excel。这次机智一点做个笔记,顺便写了一个比较通用的工具类。自然目前不能生成java实体类属性嵌套多次的这种没办法导出了,后续有需要的时候我再改改。

首先,java后端导出excel需要的HSSFWorkbook或者XSSFWorkbook,实际上他们并没有什么区别,只是导出的格式不同而已(在我看来)。前者导出.xls格式,后者导出.xlsx格式的。不过新版的好像就没有这个区别了吧,因为我也是使用HSSFWorkbook,但是同样也能导出.xlsx格式的文件呦。

HSSFWorkbook(XSSFWorkbook)他们都是Apache的产品,你可以按照需求随意切换!他们没有实质上的太多的差别,听别人说他们还有一个差别就是HSSFWorkbook只能导出65535条数据,再大的话就会报错,而XSSFWorkbook可以导出数据量是非常大的(在下并没有测试,感兴趣的兄弟可以试一下),实际上一般我们也用不了导出超过65535条数据吧。

先看一下api吧!http://poi.apache.org/apidocs/dev/org/apache/poi/hssf/usermodel/HSSFWorkbook.html

接下来我就直接粘代码了

package com.ml.code.one.until;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors; /**
* @author lhf
* @param <T>
* @since 1.0
* <p>
* 导出excel工具类,比较通用的呦
* </p>
*/
public class ExcelUtil<T> { /**
* 导出excel
* @param datas 要导出的数据
* @param excelName excel名字
* @param sheetHead 表头 key对应java中的属性名,每个key前边
* 加01-99,为了排序。value对应表头的中文名
* @param path 路径
* @param entity 分装属性名(如果有连表查询的话)
* @return -1其他异常 1导出成功 2目标文件被占用(文件已存在但是被其他应用占用) 0 导出失败(io)
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public int outExcel(Collection<T>datas, String excelName,
Map<String, String> sheetHead,String path,String... entity) throws IllegalAccessException, InvocationTargetException {
HSSFWorkbook workbook = new HSSFWorkbook(); //excel对象
HSSFSheet sheet = workbook.createSheet(excelName);
sheet.autoSizeColumn(1,true); //第一行表名
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue(excelName); //获取表头集合中所有的key(那么顺序可能会乱)
Set<String> sheetKeySet = sheetHead.keySet();
//转换为list集合,并排序
List<String> sheetKey = sheetKeySet.stream().sorted().collect(Collectors.toList());//将set集合进行排序并转换成List集合
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, sheetKey.size() - 1)); //设置单元格文字垂直居中,水平居中
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
cell.setCellStyle(cellStyle); //日期格式
HSSFCellStyle style = workbook.createCellStyle();
// HSSFDataFormat dataFormat = workbook.getCreationHelper().createDataFormat();
HSSFDataFormat dataFormat = workbook.createDataFormat();
style.setDataFormat(dataFormat.getFormat("yyyy/m/d")); //表头
HSSFRow row1 = sheet.createRow(1);
for (int i = 0; i < sheetKey.size(); i++) {
HSSFCell cell1 = row1.createCell(i);
cell1.setCellValue(sheetHead.get(sheetKey.get(i)));
cell1.setCellStyle(cellStyle);
} List<T> data = datas.stream().collect(Collectors.toList()); //将Collection转为List集合
T t=null; //获取到的泛型
//开始向excel表中添加信息
for (int i = 0; i < data.size(); i++) {//生成行
HSSFRow row2 = sheet.createRow(i + 2);
t=data.get(i);
Method[] declaredMethods = t.getClass().getDeclaredMethods();
for (int m = 0; m < sheetKey.size(); m++) {//拿到key值 key的数量代表列的数量
String key = sheetKey.get(m).substring(2);
String newKey = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);//key首字母大写 for (int k = 0; k < declaredMethods.length; k++) {//遍历字段进行比较并添加信息//添加列信息
String methodName = declaredMethods[k].getName();//方法名
Object invoke1=null;
if (methodName.equals(newKey)) {//执行方法获取属性值
invoke1= declaredMethods[k].invoke(t);
}else if (entity.length>0){//如果有分装属性 A类中封装了B类 一下代码块就是执行B类中get方法
for (int j=0;j<entity.length;j++){
String s = "get"+entity[j].substring(0,1).toUpperCase()+entity[j].substring(1);
if (s.equals(methodName)){
Object oo = declaredMethods[k].invoke(t);
Method[] mes = oo.getClass().getDeclaredMethods();
for (int p=0;p<mes.length;p++){
if (mes[p].getName().equals(newKey)){
invoke1 = mes[p].invoke(oo);
}
} }
}
} if (invoke1 instanceof String){
boolean matches = Pattern.matches("[0-9]*", invoke1.toString());
if (matches){
Double invoke = (Double)invoke1;
row2.createCell(m).setCellValue(invoke);
}else {
String invoke= (String) invoke1;
row2.createCell(m).setCellValue(invoke);
}
} else if (invoke1 instanceof Integer){
Integer invoke = (Integer) invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Short){
Short invoke = (Short) invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Long){
Long invoke = (Long)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Boolean){
Boolean invoke = (Boolean)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Double){
Double invoke = (Double)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Float){
Float invoke = (Float)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Byte){
Byte invoke = (Byte)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Character){
Character invoke = (Character)invoke1;
row2.createCell(m).setCellValue(invoke);
} else if (invoke1 instanceof Date){
Date invoke = (Date)invoke1;
HSSFCell cell1 = row2.createCell(m);
cell1.setCellStyle(style);
cell1.setCellValue(invoke);
} else if (invoke1 instanceof java.sql.Date){
java.sql.Date invoke = (java.sql.Date)invoke1;
HSSFCell cell1 = row2.createCell(m);
cell1.setCellStyle(style);
cell1.setCellValue(invoke);
} //if 类型转换
}//for k
}//for m
}//for i //写入到文件
try {
File file = new File(path + excelName + ".xlsx");
if (!file.exists()) {
file.createNewFile();
}
workbook.write(file);
return 1;//导出成功
} catch (FileNotFoundException e){
e.printStackTrace();
return 2;//目标文件被占用
} catch (IOException e) {
e.printStackTrace();
return 0;//导出失败
} catch (Exception e){
e.printStackTrace();
return -1;//其他异常
}finally {
try {
if (workbook!=null)
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

代码很简单,相信大家看的懂。有什么不明白的加我qq1490030544。

以下的伪代码是表名什么情况下不能用该类:

以上这种情况通过A类导出Excel时可以拿到B类的id,但是拿不到C类的id(虽然可以拿到C类的对象),这个后续可能我会改造一下,看时间安排吧

java后端导出excel的更多相关文章

  1. java后端导出excel表格

    转载 :https://www.cnblogs.com/zhaoyuwei/p/9038135.html 不需要在实体类些@Excel(name = "登录名", width = ...

  2. 重构:以Java POI 导出EXCEL为例

    重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...

  3. java 实现导出Excel文件

    java 实现导出Excel(java生成 excel 并导出文件) 经常有有一些数据需要导出成   excel  格式 ,所以就需要实现啦 开始: 1.加入jar poi-3.6-20091214. ...

  4. java:POI导出excel

    POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel. 下面是使用示例: 1.maven中先添加依赖项 <dependency> < ...

  5. Java POI 导出EXCEL经典实现 Java导出Excel

    转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...

  6. java导入导出excel常用操作小结及简单示例

    POI中常用设置EXCEL的操作小结: 操作excel如下 HSSFWorkbook wb = new HSSFWorkbook();  //创建一个webbook,对应一个Excel文件 HSSFS ...

  7. java web 导出Excel 的工具类公用实现

    平时我们在开发后端管理的系统时,经常会出现导出Excel的功能.这个功能很简单,但是呢,我一般就会使用公用的工具类,在一个Util中,暴露公用导出的接口,只需要传入需要导出的数据(一般使用list集合 ...

  8. [ExtJS5学习笔记]第三十四节 sencha extjs 5 grid表格之java后台导出excel

    继上次使用js前端导出excel之后,还有一个主要大家比较关注的是后台实现导出excel,因为本人开发使用的java所以这里使用apache的开源项目poi进行后台excel的导出. 本文目录 本文目 ...

  9. 重构:以Java POI 导出EXCEL为例2

    前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...

随机推荐

  1. Servlet过滤器基础及使用场景

    Servlet过滤器详解 一.过滤器基础 1.Servlet过滤器是Servlet的一种特殊用法,主要用来完成一些通用的操作.比如编码的过滤,判断用户的登陆状态等等.Servlet过滤器的适用场合: ...

  2. UVA 11552 序列划分模型 状态设计DP

    这个题目刚看到还真不好下手,把一个是 k的倍数的长度的字符串分成len/k块,每块是k个字母,每个块可以重新组合,最后使得整个序列的相同字母尽量在一起,也就是说,最后会把序列从前往后扫,相连的相同字母 ...

  3. 吴裕雄--天生自然MySQL学习笔记:MySQL 删除数据库

    使用普通用户登陆 MySQL 服务器,可能需要特定的权限来创建或者删除 MySQL 数据库,所以使用 root 用户登录,root 用户拥有最高权限. 在删除数据库过程中,务必要十分谨慎,因为在执行删 ...

  4. [题解] 洛谷P3950 部落冲突

    传送门 拿到题目,一看 裸LCT (其实是我懒得打,splay又臭又长) 首先,这道题的意思就是删掉一些边 所以常规操作 点权转边权 之后对于战争操作,在对应的边上+1 对于和平操作,在对应的边上-1 ...

  5. 23. docker 数据持久化 bind mounting

    1. bind mounting 和 data volume 的区别 data volume 需要在 Dockerfile 定义 Volume bind mounting 只需要 -v 指明 容器外部 ...

  6. MySQL的InnoDB的幻读问题

    MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ). 未提交读(READ UNCOMMITTED).另一个事务修改了数据,但尚未提交,而本事务中的SEL ...

  7. dp--背包--开心的金明

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天 ...

  8. cisco3900板卡sm-es3g-24-p使用方法

    不知道是不是叫板卡,还是叫线卡希望不予深究.本文摘自:https://zhidao.baidu.com/question/1669814353056144947.html 插上板卡后,在配置界面仅显示 ...

  9. PAT Basic 1017 A除以B (20) [数学问题-⼤整数运算]

    题目 本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成⽴. 输⼊格式: 输⼊在1⾏中依次给出A和B,中间以1空格分隔. ...

  10. Python中的encode和decode

    原文地址:http://www.cnblogs.com/tingyugetc/p/5727383.html 1.Python3中对文本和二进制数据进行了比较清晰的区分,文本总是 unicode ,由  ...