最近工作中需要导出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. Python说文解字_Python之多任务_04

    问:并发.并行.同步.异步.阻塞.非阻塞 答: 并发.并行: 并发是指一个时间段内(不是指的时间点),有几个程序在同一个CPU上运行,但是任意时刻只有一个程序在CPU上运行.对人类的时钟来说1秒钟能干 ...

  2. CTF -攻防世界-crypto新手区(1~4)

    题目已经提示用base64直接解密就行 base64解密网址 http://tool.oschina.net/encrypt?type=3 题目提示是凯撒密码 http://www.zjslove.c ...

  3. Cracking Digital VLSI Verification Interview 第一章

    目录 Digital Logic Design Number Systems, Arithmetic and Codes Basic Gates Combinational Logic Circuit ...

  4. kaggle——TMDB 电影票房收入预测

    介绍 看电影是目前人们休闲娱乐,消遣时光的选择之一.我们都知道,有些电影的票房很高,有的电影票房却很低,那么决定票房的因素是什么呢?本次将介绍,如何根据电影上映前的一些信息来预测出该电影的票房. 知识 ...

  5. 批量导入数据表(oracle)

    批量导入数据表(oracle) 1.登陆plsql 2.找到菜单栏 工具>>导入数据>>新增图标(会提示选择*.csv文件) 选择如上图所示 3.选择数据并导入 4.下图为执行 ...

  6. Pmw大控件(二)

    Pmw大控件英文名Pmw Python megawidgets 官方参考文档:Pmw 1.3 Python megawidgets 一,如何使用Pmw大控件 下面以创建一个计数器(Counter)为例 ...

  7. CF round #622 (div2)

    CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...

  8. awk中传参方式

    结合编辑数据文件的shell脚本学习awk传参方式,该脚本功能: a.取VIDEOUSR_11082017_0102_ONLINE_STASTIC.dat文件中第87个字段的低8位: b.将每行数据的 ...

  9. UVA 10158 并查集的经典应用

    这个题目一看就是用并查集,有N个国家代表,在M行给出两两之间的关系,敌人或者朋友,(当然如果该关系跟已知关系冲突,则输出-1) 关系的几个约束条件时这样的 在朋友方面,朋友的朋友就是自己的朋友,这个就 ...

  10. HDU-4460 Friend Chains(BFS&权为1所有最短路的最大值)

    题目: For a group of people, there is an idea that everyone is equals to or less than 6 steps away fro ...