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. ...
随机推荐
- 大数据攻城狮之进阶技能-使用Git上传自己的项目至GitHub仓库
在开始讲解之前我们默认已经存在仓库和安装Git,没有下载的可以去https://git-scm.com/ Git官方网站下载或者是私聊博主. 下面我们说一说Git的使用,比如说如何生成密钥,连接远程仓 ...
- tfield的字段名和显示名
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- html标签title属性效果优化
html标签title属性效果不友好,最致命的是响应慢,体验不好,JQuery-UI提供了很好的支持.在jquery.tip的基础上又做了修改,这样子定制效果更强. 代码如下: <!DOCTYP ...
- Windows 远程桌面连接 CentOS7 (xrdp)
Windows 远程桌面连接 CentOS7 (xrdp) 前提: CentOS安装桌面,如果无桌面,请执行: yum -y groups install "GNOME Desktop&qu ...
- Python心得--新手开发注意
1 注释 介绍 在大多数编程语言当中,注释都是一项非常有用的功能.我们开始编写的程序之中都只包含Python代码,但是随着程序越来越大.越来越复杂,就应在其中添加说明,对你解决问题的方法进行大致的阐 ...
- 汪慧和201771010123《面向对象程序设计JAVA》第四周实验总结
第一部分:理论知识学习部分 1.类 类(class)是具有相同属性和行为的一组对象的集合,是构造程序的基本单元,是构造对象的模板或蓝图. 2.对象 对象:即数据,对象有三个特性——1.行为 2.状态 ...
- ElasticSearch的9200和9300端口的区别
9200用于外部通讯,基于http协议,程序与es的通信使用9200端口. 9300jar之间就是通过tcp协议通信,遵循tcp协议,es集群中的节点之间也通过9300端口进行通信.
- 1017A.The Rank#排名
题目出处:http://codeforces.com/problemset/problem/1017/A #include<iostream> using namespace std; i ...
- eureka学习之二:自我保护机制
提供者和消费者:消费者通过注册服务名称,找rpc远程地址,调用提供者的接口 Eureka的自我保护机制:
- 洛谷P1435 回文子串
题目背景 IOI2000第一题 题目描述 回文词是一种对称的字符串.任意给定一个字符串,通过插入若干字符,都可以变成回文词.此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数. 比如 “A ...