一、POI导出报表要用到的包
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.13</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.13</version>
</dependency>
二、POI常用类说明
class | declare |
---|---|
HSSFWorkbook | Excel的文档对象(考虑到对以前老版本格式为.xls的excel的兼容性,以下的实例用HSSF,而不采用XSSF) |
HSSFSheet | Excel中的表单 |
HSSFRow | Excel中的行 |
HSSFCell | Excel中的元素单元 |
HSSFFont | Excel元素的字体 |
HSSFDataFormat | 格子单元的日期格式 |
HSSFHeader | Excel文档工作表的页眉 |
HSSFFooter | Excel文档表的页脚 |
HSSFCellStyle | 格子单元样式(HSSF对应旧的xls格式,XSSF对应新的xlsx格式,SXSSF是在XSSF的基础上,支持导出大批量的excel数据。)【POI HSSFColor 颜色索引对照表】 |
HSSFDateUtil | 日期 |
HSSFPrintSetup | 打印 |
POI快速入门教程,POI有三种API
- POI-HSSF,HSSF是POI项目的Excel '97-2007’文件格式的纯Java实现
- POI-XSSF,XSSF是POI Project的Excel 2007 OOXML(.xlsx)文件格式的纯Java实现
- SXSSF,3.8-beta3以来,SXSSF是XSSF的API兼容流式扩展,用于在必须生成非常大的电子表格时使用,并且堆空间有限。
简单的说,HSSF对应旧的xls格式,XSSF对应新的xlsx格式,SXSSF是在XSSF的基础上,支持导出大批量的excel数据。
要使用POI,要知道以下关键代码
//创建工作簿,对应整个xlsx文件
XSSFWorkbook workbook = new XSSFWorkbook();
//创建sheet,对应excel的单个sheet
XSSFSheet sheet = workbook.createSheet("sheet1");
//创建行,对应excel中的一行
XSSFRow row = sheet.createRow(0)
//创建单元格,对应row中的一格
XSSFCell cell = row.createCell(0);
//单元格设置值
cell.setCellValue("cell");
//单元格设置样式
cell.setCellStyle(style);
其中style要从workbook中创建,简单的style示例
XSSFCellStyle style = workbook.createCellStyle();
//居中
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
//border
style.setBorderLeft(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
将workbook保存到文件
FileOutputStream file = new FileOutputStream("example.xlsx");
workbook.write(file);
file.close();
三、简单示例
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
/**
* 导出报表工具类
*/
public class ExportExcelUtil {
/**
*
* @param title 标题
* @param headers 表头
* @param values 表中元素
* @return
*/
public static HSSFWorkbook getHSSFWorkbook(String title, String headers[], String [][] values){
//创建一个HSSFWorkbook,对应一个Excel文件
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
//在workbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet hssfSheet = hssfWorkbook.createSheet(title);
//创建标题合并行
hssfSheet.addMergedRegion(new CellRangeAddress(0,(short)0,0,(short)headers.length - 1));
//设置标题样式
HSSFCellStyle style = hssfWorkbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); //设置居中样式
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置标题字体
Font titleFont = hssfWorkbook.createFont();
titleFont.setFontHeightInPoints((short) 14);
style.setFont(titleFont);
//设置值表头样式 设置表头居中
HSSFCellStyle hssfCellStyle = hssfWorkbook.createCellStyle();
hssfCellStyle.setAlignment(HorizontalAlignment.CENTER); //设置居中样式
hssfCellStyle.setBorderBottom(BorderStyle.THIN);
hssfCellStyle.setBorderLeft(BorderStyle.THIN);
hssfCellStyle.setBorderRight(BorderStyle.THIN);
hssfCellStyle.setBorderTop(BorderStyle.THIN);
//设置表内容样式
//创建单元格,并设置值表头 设置表头居中
HSSFCellStyle style1 = hssfWorkbook.createCellStyle();
style1.setBorderBottom(BorderStyle.THIN);
style1.setBorderLeft(BorderStyle.THIN);
style1.setBorderRight(BorderStyle.THIN);
style1.setBorderTop(BorderStyle.THIN);
//产生标题行
HSSFRow hssfRow = hssfSheet.createRow(0);
HSSFCell cell = hssfRow.createCell(0);
cell.setCellValue(title);
cell.setCellStyle(style);
//产生表头
HSSFRow row1 = hssfSheet.createRow(1);
for (int i = 0; i < headers.length; i++) {
HSSFCell hssfCell = row1.createCell(i);
hssfCell.setCellValue(headers[i]);
hssfCell.setCellStyle(hssfCellStyle);
}
//创建内容
for (int i = 0; i <values.length; i++){
row1 = hssfSheet.createRow(i +2);
for (int j = 0; j < values[i].length; j++){
//将内容按顺序赋给对应列对象
HSSFCell hssfCell = row1.createCell(j);
hssfCell.setCellValue(values[i][j]);
hssfCell.setCellStyle(style1);
}
}
return hssfWorkbook;
}
}
四、注解实现工具类
1、HSSF模式97-2007Excel
(1)标题注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标题注解类
* @author tangyb
* @date 2020/03/27
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
// excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
public String exportName();
}
(2)数据实体类
import java.util.Date;
/**
* 数据实体类
* @author tangyb
* @date 2020/03/27
*/
public class Testpojo {
@ExcelAnnotation(exportName = "用户名")
String username;
@ExcelAnnotation(exportName = "登录名")
String loginname;
@ExcelAnnotation(exportName = "年龄")
Integer age;
@ExcelAnnotation(exportName = "收入")
Long money;
@ExcelAnnotation(exportName = "时间")
Date createtime;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Long getMoney() {
return money;
}
public void setMoney(Long money) {
this.money = money;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
}
(3)单元格样式
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
/**
* Excel单元格样式
* @author tangyb
* @date 2020/03/27
*/
public class ExcelStyle {
/**
* 表格标题单元格样式
* @param workbook
* @param style
* @return
*/
public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook, HSSFCellStyle style) {
// 设置背景色
style.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
// 设置边框
style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框
style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框
style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
// 设置单元格的中心水平对齐-居中
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 设置单元格的垂直对齐类型-居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 生成字体
HSSFFont font = workbook.createFont();
// 设置字体类型
font.setFontName("微软雅黑");
// 设置字体大小
font.setFontHeightInPoints((short) 10);
// 粗体字体
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
/**
* 表格主体单元格样式
* @param workbook
* @param style
* @return
*/
public static HSSFCellStyle setbodyStyle(HSSFWorkbook workbook, HSSFCellStyle style) {
// 设置背景色
// style.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
// style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
// 设置边框
style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框
style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框
style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
// 生成字体
HSSFFont font = workbook.createFont();
// 字体类型
font.setFontName("微软雅黑");
// 设置字体大小
font.setFontHeightInPoints((short) 9);
// 普通字体
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
}
(4)导入工具类
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 导入工具类
*
* @author tangyb
* @date 2020/03/27
*/
public class ImportExcel<T> {
Class<T> clazz;
public ImportExcel(Class<T> clazz) {
this.clazz = clazz;
}
public Collection<T> importExcel(File file, String... pattern) {
Collection<T> dist = new ArrayList<T>();
try {
/**
* 类反射得到调用方法
*/
// 得到目标目标类的所有的字段列表
Field filed[] = clazz.getDeclaredFields();
// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
Map<String, Method> fieldmap = new HashMap<String, Method>();
// 循环读取所有字段
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
// 得到单个字段上的Annotation
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果标识了Annotationd的话
if (exa != null) {
// 构造设置了Annotation的字段的Setter方法
String fieldname = f.getName();
String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);
// 构造调用的method,
Method setMethod = clazz.getMethod(setMethodName, new Class[] {f.getType()});
// 将这个method以Annotaion的名字为key来存入。
fieldmap.put(exa.exportName(), setMethod);
}
}
/**
* excel的解析开始
*/
// 将传入的File构造为FileInputStream;
FileInputStream in = new FileInputStream(file);
// // 得到工作表
Workbook book = null;
try {
book = new XSSFWorkbook(in);
} catch (Exception ex) {
book = new HSSFWorkbook(in);
}
// HSSFWorkbook book = new HSSFWorkbook(in);
// // 得到第一页
// HSSFSheet sheet = (HSSFSheet) book.getSheetAt(0);
Sheet sheet = book.getSheetAt(0);
// // 得到第一面的所有行
Iterator<Row> row = sheet.rowIterator();
/**
* 标题解析
*/
// 得到第一行,也就是标题行
Row title = row.next();
// 得到第一行的所有列
Iterator<Cell> cellTitle = title.cellIterator();
// 将标题的文字内容放入到一个map中。
Map<Integer, String> titlemap = new HashMap<Integer, String>();
// 从标题第一列开始
int i = 0;
// 循环标题所有的列
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = cell.getStringCellValue();
titlemap.put(i, value);
i = i + 1;
}
/**
* 解析内容行
*/
// 用来格式化日期的DateFormat
SimpleDateFormat sf;
if (pattern.length < 1) {
sf = new SimpleDateFormat("yyyy-MM-dd");
} else
sf = new SimpleDateFormat(pattern[0]);
while (row.hasNext()) {
// 标题下的第一行
Row rown = row.next();
// 行的所有列
Iterator<Cell> cellbody = rown.cellIterator();
// 得到传入类的实例
T tObject = clazz.newInstance();
int k = 0;
// 遍历一行的列
while (cellbody.hasNext()) {
Cell cell = cellbody.next();
// 这里得到此列的对应的标题
String titleString = (String) titlemap.get(k);
// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
if (fieldmap.containsKey(titleString)) {
Method setMethod = (Method) fieldmap.get(titleString);
// 得到setter方法的参数
Type[] ts = setMethod.getGenericParameterTypes();
// 只要一个参数
String xclass = ts[0].toString();
// 判断参数类型
cell.setCellType(Cell.CELL_TYPE_STRING);
if (xclass.equals("class java.lang.String")) {
setMethod.invoke(tObject, cell.getStringCellValue());
} else if (xclass.equals("class java.util.Date")) {
setMethod.invoke(tObject, sf.parse(cell.getStringCellValue()));
} else if (xclass.equals("class java.lang.Boolean")) {
Boolean boolname = true;
if (cell.getStringCellValue().equals("否")) {
boolname = false;
}
setMethod.invoke(tObject, boolname);
} else if (xclass.equals("class java.lang.Integer")) {
setMethod.invoke(tObject, new Integer(cell.getStringCellValue()));
}
else if (xclass.equals("class java.lang.Long")) {
setMethod.invoke(tObject, new Long(cell.getStringCellValue()));
}
}
// 下一列
k = k + 1;
}
dist.add(tObject);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return dist;
}
public static void main(String[] args) {
ImportExcel<Testpojo> test = new ImportExcel<Testpojo>(Testpojo.class);
File file = new File("D:\\testOne.xls");
Long befor = System.currentTimeMillis();
List<Testpojo> result = (ArrayList<Testpojo>) test.importExcel(file);
Long after = System.currentTimeMillis();
System.out.println("此次操作共耗时:" + (after - befor) + "毫秒");
for (int i = 0; i < result.size(); i++) {
Testpojo testpojo = result.get(i);
System.out.println("导入的信息为:" + testpojo.getLoginname() + "----" + testpojo.getAge()
+ "---" + testpojo.getMoney() + "-----" + testpojo.getCreatetime());
}
System.out.println("共转化为List的行数为:" + result.size());
}
}
(5)导出工具类
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* 导出工具类
* @author tangyb
* @date 2020/03/27
*/
public class ExportExcel<T> {
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
*
* @param title 标题
* @param dataset 集合
* @param out 输出流
*/
public void exportExcel(String title, Collection<T> dataset,
OutputStream out) {
// 声明一个工作薄
try {
//首先检查数据看是否是正确的
Iterator<T> its = dataset.iterator();
if(dataset==null||!its.hasNext()||title==null||out==null)
{
throw new Exception("传入的数据不对!");
}
//取得实际泛型类
T ts = (T) its.next();
Class<? extends Object> tCls = ts.getClass();
HSSFWorkbook workbook = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置标题样式
style = ExcelStyle.setHeadStyle(workbook, style);
// 生成一个样式
HSSFCellStyle style2 = workbook.createCellStyle();
// 设置主体样式
style2 = ExcelStyle.setbodyStyle(workbook, style2);
// 得到所有字段
Field filed[] = ts.getClass().getDeclaredFields();
// 标题
List<String> exportfieldtile = new ArrayList<String>();
// 导出的字段的get方法
List<Method> methodObj = new ArrayList<Method>();
// 遍历整个filed
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果设置了annottion
if (exa != null) {
String exprot = exa.exportName();
// 添加到标题
exportfieldtile.add(exprot);
// 添加到需要导出的字段的方法
String fieldname = f.getName();
String getMethodName = "get"
+ fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);
Method getMethod = tCls.getMethod(getMethodName,
new Class[] {});
methodObj.add(getMethod);
}
}
// 产生表格标题行
HSSFRow row = sheet.createRow(0);
for (int i = 0; i < exportfieldtile.size(); i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(
exportfieldtile.get(i));
cell.setCellValue(text);
}
int index = 0;
// 循环整个集合
while (its.hasNext()) {
//从第二行开始写,第一行是标题
index++;
row = sheet.createRow(index);
T t = (T) its.next();
for (int k = 0; k < methodObj.size(); k++) {
HSSFCell cell = row.createCell(k);
cell.setCellStyle(style2);
Method getMethod=methodObj.get(k);
Object value = getMethod.invoke(t, new Object[] {});
String textValue = getValue(value);
cell.setCellValue(textValue);
}
}
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
}
}
public String getValue(Object value) {
String textValue = "";
if (value == null)
return textValue;
if (value instanceof Boolean) {
boolean bValue = (Boolean) value;
textValue = "是";
if (!bValue) {
textValue = "否";
}
} else if (value instanceof Date) {
Date date = (Date) value;
textValue = sdf.format(date);
} else
textValue = value.toString();
return textValue;
}
public static void main(String[] args) throws Exception {
//构造一个模拟的List来测试,实际使用时,这个集合用从数据库中查出来
List<Testpojo> list = new ArrayList<Testpojo>();
for (int i = 0; i < 5000; i++) {
Testpojo pojo = new Testpojo();
pojo.setLoginname("登录名"+i);
pojo.setUsername("用户名"+i);
pojo.setMoney(new Long(1000+i));
pojo.setCreatetime(new Date());
pojo.setAge(28);
list.add(pojo);
}
//构造输出对象,可以从response输出,直接向用户提供下载
OutputStream out = new FileOutputStream("D:\\testOne.xls");
//开始时间
Long l = System.currentTimeMillis();
//注意
ExportExcel<Testpojo> ex = new ExportExcel<Testpojo>();
//
ex.exportExcel("测试", list, out);
out.close();
//结束时间
Long s = System.currentTimeMillis();
System.out.println("总共耗时:" + (s - l));
}
}
2、XSSF模式2007Excel
(1)标题注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标题注解类
* @author tangyb
* @date 2020/03/27
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
// excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
public String exportName();
}
(2)数据实体类
import java.util.Date;
/**
* 数据实体类
* @author tangyb
* @date 2020/03/27
*/
public class Testpojo {
@ExcelAnnotation(exportName = "用户名")
String username;
@ExcelAnnotation(exportName = "登录名")
String loginname;
@ExcelAnnotation(exportName = "年龄")
Integer age;
@ExcelAnnotation(exportName = "收入")
Long money;
@ExcelAnnotation(exportName = "时间")
Date createtime;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Long getMoney() {
return money;
}
public void setMoney(Long money) {
this.money = money;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
}
(3)单元格样式
import java.awt.Color;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* Excel单元格样式
* @author tangyb
* @date 2020/03/27
*/
public class ExcelStyle {
/**
* 表格标题单元格样式
* @param workbook
* @param style
* @return
*/
public static XSSFCellStyle setHeadStyle(XSSFWorkbook workbook, XSSFCellStyle style) {
// 设置背景色
style.setFillForegroundColor(new XSSFColor(new Color(255,255,255)));
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 设置边框
style.setBorderBottom(XSSFCellStyle.BORDER_THIN); // 下边框
style.setBorderRight(XSSFCellStyle.BORDER_THIN);// 右边框
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);// 左边框
style.setBorderTop(XSSFCellStyle.BORDER_THIN);// 上边框
// 设置单元格的中心水平对齐-居中
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 设置单元格的垂直对齐类型-居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 生成字体
XSSFFont font = workbook.createFont();
// 设置字体类型
font.setFontName("微软雅黑");
// 设置字体大小
font.setFontHeightInPoints((short) 10);
// 粗体字体
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
/**
* 表格主体单元格样式
* @param workbook
* @param style
* @return
*/
public static XSSFCellStyle setbodyStyle(XSSFWorkbook workbook, XSSFCellStyle style) {
// 设置背景色
// style.setFillForegroundColor(new XSSFColor(new Color(255,255,255)));
// style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 设置边框
style.setBorderBottom(XSSFCellStyle.BORDER_THIN); // 下边框
style.setBorderRight(XSSFCellStyle.BORDER_THIN);// 右边框
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);// 左边框
style.setBorderTop(XSSFCellStyle.BORDER_THIN);// 上边框
// 生成字体
XSSFFont font = workbook.createFont();
// 字体类型
font.setFontName("微软雅黑");
// 设置字体大小
font.setFontHeightInPoints((short) 9);
// 普通字体
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
}
(4)导入工具类
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 导入工具类
*
* @author tangyb
* @date 2020/03/27
*/
public class ImportExcel<T> {
Class<T> clazz;
public ImportExcel(Class<T> clazz) {
this.clazz = clazz;
}
public Collection<T> importExcel(File file, String... pattern) {
Collection<T> dist = new ArrayList<T>();
try {
/**
* 类反射得到调用方法
*/
// 得到目标目标类的所有的字段列表
Field filed[] = clazz.getDeclaredFields();
// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
Map<String, Method> fieldmap = new HashMap<String, Method>();
// 循环读取所有字段
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
// 得到单个字段上的Annotation
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果标识了Annotationd的话
if (exa != null) {
// 构造设置了Annotation的字段的Setter方法
String fieldname = f.getName();
String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);
// 构造调用的method,
Method setMethod = clazz.getMethod(setMethodName, new Class[] {f.getType()});
// 将这个method以Annotaion的名字为key来存入。
fieldmap.put(exa.exportName(), setMethod);
}
}
/**
* excel的解析开始
*/
// 将传入的File构造为FileInputStream;
FileInputStream in = new FileInputStream(file);
// // 得到工作表
Workbook book = null;
try {
book = new XSSFWorkbook(in);
} catch (Exception ex) {
book = new HSSFWorkbook(in);
}
// HSSFWorkbook book = new HSSFWorkbook(in);
// // 得到第一页
// HSSFSheet sheet = (HSSFSheet) book.getSheetAt(0);
Sheet sheet = book.getSheetAt(0);
// // 得到第一面的所有行
Iterator<Row> row = sheet.rowIterator();
/**
* 标题解析
*/
// 得到第一行,也就是标题行
Row title = row.next();
// 得到第一行的所有列
Iterator<Cell> cellTitle = title.cellIterator();
// 将标题的文字内容放入到一个map中。
Map<Integer, String> titlemap = new HashMap<Integer, String>();
// 从标题第一列开始
int i = 0;
// 循环标题所有的列
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = cell.getStringCellValue();
titlemap.put(i, value);
i = i + 1;
}
/**
* 解析内容行
*/
// 用来格式化日期的DateFormat
SimpleDateFormat sf;
if (pattern.length < 1) {
sf = new SimpleDateFormat("yyyy-MM-dd");
} else
sf = new SimpleDateFormat(pattern[0]);
while (row.hasNext()) {
// 标题下的第一行
Row rown = row.next();
// 行的所有列
Iterator<Cell> cellbody = rown.cellIterator();
// 得到传入类的实例
T tObject = clazz.newInstance();
int k = 0;
// 遍历一行的列
while (cellbody.hasNext()) {
Cell cell = cellbody.next();
// 这里得到此列的对应的标题
String titleString = (String) titlemap.get(k);
// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
if (fieldmap.containsKey(titleString)) {
Method setMethod = (Method) fieldmap.get(titleString);
// 得到setter方法的参数
Type[] ts = setMethod.getGenericParameterTypes();
// 只要一个参数
String xclass = ts[0].toString();
// 判断参数类型
cell.setCellType(Cell.CELL_TYPE_STRING);
if (xclass.equals("class java.lang.String")) {
setMethod.invoke(tObject, cell.getStringCellValue());
} else if (xclass.equals("class java.util.Date")) {
setMethod.invoke(tObject, sf.parse(cell.getStringCellValue()));
} else if (xclass.equals("class java.lang.Boolean")) {
Boolean boolname = true;
if (cell.getStringCellValue().equals("否")) {
boolname = false;
}
setMethod.invoke(tObject, boolname);
} else if (xclass.equals("class java.lang.Integer")) {
setMethod.invoke(tObject, new Integer(cell.getStringCellValue()));
}
else if (xclass.equals("class java.lang.Long")) {
setMethod.invoke(tObject, new Long(cell.getStringCellValue()));
}
}
// 下一列
k = k + 1;
}
dist.add(tObject);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return dist;
}
public static void main(String[] args) {
ImportExcel<Testpojo> test = new ImportExcel<Testpojo>(Testpojo.class);
File file = new File("D:\\testOne.xls");
Long befor = System.currentTimeMillis();
List<Testpojo> result = (ArrayList<Testpojo>) test.importExcel(file);
Long after = System.currentTimeMillis();
System.out.println("此次操作共耗时:" + (after - befor) + "毫秒");
for (int i = 0; i < result.size(); i++) {
Testpojo testpojo = result.get(i);
System.out.println("导入的信息为:" + testpojo.getLoginname() + "----" + testpojo.getAge()
+ "---" + testpojo.getMoney() + "-----" + testpojo.getCreatetime());
}
System.out.println("共转化为List的行数为:" + result.size());
}
}
(5)导出工具类
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 导出工具类
* @author tangyb
* @date 2020/03/27
*/
public class ExportExcel<T> {
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
*
* @param title 标题
* @param dataset 集合
* @param out 输出流
*/
public void exportExcel(String title, Collection<T> dataset,
OutputStream out) {
// 声明一个工作薄
try {
//首先检查数据看是否是正确的
Iterator<T> its = dataset.iterator();
if(dataset==null||!its.hasNext()||title==null||out==null)
{
throw new Exception("传入的数据不对!");
}
//取得实际泛型类
T ts = (T) its.next();
Class<? extends Object> tCls = ts.getClass();
XSSFWorkbook workbook = new XSSFWorkbook();
// 生成一个表格
XSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
// 生成一个样式
XSSFCellStyle style = workbook.createCellStyle();
// 设置标题样式
style = ExcelStyle.setHeadStyle(workbook, style);
// 生成一个样式
XSSFCellStyle style2 = workbook.createCellStyle();
// 设置主体样式
style2 = ExcelStyle.setbodyStyle(workbook, style2);
// 得到所有字段
Field filed[] = ts.getClass().getDeclaredFields();
// 标题
List<String> exportfieldtile = new ArrayList<String>();
// 导出的字段的get方法
List<Method> methodObj = new ArrayList<Method>();
// 遍历整个filed
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果设置了annottion
if (exa != null) {
String exprot = exa.exportName();
// 添加到标题
exportfieldtile.add(exprot);
// 添加到需要导出的字段的方法
String fieldname = f.getName();
String getMethodName = "get"
+ fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);
Method getMethod = tCls.getMethod(getMethodName,
new Class[] {});
methodObj.add(getMethod);
}
}
// 产生表格标题行
XSSFRow row = sheet.createRow(0);
for (int i = 0; i < exportfieldtile.size(); i++) {
XSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
XSSFRichTextString text = new XSSFRichTextString(
exportfieldtile.get(i));
cell.setCellValue(text);
}
int index = 0;
// 循环整个集合
while (its.hasNext()) {
//从第二行开始写,第一行是标题
index++;
row = sheet.createRow(index);
T t = (T) its.next();
for (int k = 0; k < methodObj.size(); k++) {
XSSFCell cell = row.createCell(k);
cell.setCellStyle(style2);
Method getMethod=methodObj.get(k);
Object value = getMethod.invoke(t, new Object[] {});
String textValue = getValue(value);
cell.setCellValue(textValue);
}
}
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
}
}
public String getValue(Object value) {
String textValue = "";
if (value == null)
return textValue;
if (value instanceof Boolean) {
boolean bValue = (Boolean) value;
textValue = "是";
if (!bValue) {
textValue = "否";
}
} else if (value instanceof Date) {
Date date = (Date) value;
textValue = sdf.format(date);
} else
textValue = value.toString();
return textValue;
}
public static void main(String[] args) throws Exception {
//构造一个模拟的List来测试,实际使用时,这个集合用从数据库中查出来
List<Testpojo> list = new ArrayList<Testpojo>();
for (int i = 0; i < 5000; i++) {
Testpojo pojo = new Testpojo();
pojo.setLoginname("登录名"+i);
pojo.setUsername("用户名"+i);
pojo.setMoney(new Long(1000+i));
pojo.setCreatetime(new Date());
pojo.setAge(28);
list.add(pojo);
}
//构造输出对象,可以从response输出,直接向用户提供下载
OutputStream out = new FileOutputStream("D:\\testOne.xlsx");
//开始时间
Long l = System.currentTimeMillis();
//注意
ExportExcel<Testpojo> ex = new ExportExcel<Testpojo>();
//
ex.exportExcel("测试", list, out);
out.close();
//结束时间
Long s = System.currentTimeMillis();
System.out.println("总共耗时:" + (s - l));
}
}