java后端导出excel
最近工作中需要导出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的更多相关文章
- java后端导出excel表格
转载 :https://www.cnblogs.com/zhaoyuwei/p/9038135.html 不需要在实体类些@Excel(name = "登录名", width = ...
- 重构:以Java POI 导出EXCEL为例
重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...
- java 实现导出Excel文件
java 实现导出Excel(java生成 excel 并导出文件) 经常有有一些数据需要导出成 excel 格式 ,所以就需要实现啦 开始: 1.加入jar poi-3.6-20091214. ...
- java:POI导出excel
POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel. 下面是使用示例: 1.maven中先添加依赖项 <dependency> < ...
- Java POI 导出EXCEL经典实现 Java导出Excel
转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...
- java导入导出excel常用操作小结及简单示例
POI中常用设置EXCEL的操作小结: 操作excel如下 HSSFWorkbook wb = new HSSFWorkbook(); //创建一个webbook,对应一个Excel文件 HSSFS ...
- java web 导出Excel 的工具类公用实现
平时我们在开发后端管理的系统时,经常会出现导出Excel的功能.这个功能很简单,但是呢,我一般就会使用公用的工具类,在一个Util中,暴露公用导出的接口,只需要传入需要导出的数据(一般使用list集合 ...
- [ExtJS5学习笔记]第三十四节 sencha extjs 5 grid表格之java后台导出excel
继上次使用js前端导出excel之后,还有一个主要大家比较关注的是后台实现导出excel,因为本人开发使用的java所以这里使用apache的开源项目poi进行后台excel的导出. 本文目录 本文目 ...
- 重构:以Java POI 导出EXCEL为例2
前言 上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数.这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等. 上一篇博文地址:http://www. ...
随机推荐
- 传输层上的TCP和UDP
参考: 知乎 传输层概述 “三次握手,四次挥手”你真的懂吗? 传输层上的TCP和UDP TCP/IP协议是一个协议簇.里面包括很多协议的,UDP只是其中的一个, 之所以命名为TCP/IP协议,因为TC ...
- (函数)P1217 [USACO1.5]回文质数 Prime Palindromes
题解: 第一次: 算法复杂度过高,导致编译超时,需要优化 #include<stdio.h>#include<math.h>int a[100000001] = { 0 };i ...
- linux环境java程序cpu爆表问题查证
1.top命令查找导致cup爆表的进程 2. top -H -p10832 (10832是Java进程的PID)命令找出了具体的线程 3.使用用命令 jstack 10832> jstack.t ...
- Mybatis之二级缓存(八)
1. 介绍 Mybatis缓存分为一级缓存和二级缓存,在本节中我们介绍下二级缓存的使用及其特性 MyBatis的一级缓存是在一个Session域内有效的,当Session关闭后,缓存内容也随之销毁.但 ...
- faster rcnn 源码学习-------数据读入及RoIDataLayer相关模块解读
参考博客:::https://www.cnblogs.com/Dzhen/p/6845852.html 非常全面的解读参考:::https://blog.csdn.net/DaVinciL/artic ...
- String,StringBuffer与StringBuilder的区别与选择
三者的区别 String:不可变类,一旦一个对象被建立的时候,包含在这个对象中的字符串序列是不可变的,直到这个对象被销毁.StringBuffer:可变字符序列的字符串.当其对象被创建的时候,可以用a ...
- openlayers的loaders方式加载
openlayers loaders方式加载 let layerVector = new ol.layer.Vector({ source : new ol.source.Vector({ loade ...
- Ubuntu系统的软件源更换
参考:https://www.daweibro.com/node/142 什么是Ubuntu的软件源? 我们在使用Debian或者Ubuntu的apt-get工具来安装需要的软件时,其实就是从服务器获 ...
- catalina.out日志膨胀问题解决实例,日志门面commons-logging的实践
声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635 笔者在公司的时候,遇到一个问题,2个模块A.B Tomcat中的catalina.out及catalina ...
- java 利用管道实现线程间通信
package com.lb; import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutpu ...