import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

//需要的jar包:poi-3.15.jar、poi-ooxml-3.15.jar

/**
* 2002、2003的一个工作簿中最多含有256个工作表,默认情况下是三个工作表,工作表由65536行*256列组成,每行列交叉为一个单位格。
* 2007的无论是工作表个数、工作表列数、行数,都大大突破了这个数据,excel默认的工作薄扩展名为".xlsx",
* 这种格式的文件中每个工作页包含1048576行(Row)*16384列(Column)。EXCEL的帮助文件上说的,理论上sheet是无限个,但受可用内存的限制,
* 你可以试着插入一个新工作表,然后按着F4,就会看见工作表不停的增加,我1G内存,工作表增加到10000个,还能正常进行基本操作 。
*/

/**
*
* Excel导出方法
*@param title Excel标题
*@param headersParams 以字符串"header = param"方式存储元素的List<Striing>;header代表的是表头,param代表的是表头对应的属性
*@param dataList 需要导出Excel数据
*@param sheetMaxCount 每一个sheet的最大存储行数(数量)
*@return Workbook
*@since (此方法开始于哪个版本)0.0.3
*@author yangke
*
*/
public class NextExcelUtil {

/**
* 分sheet导出Excel的情况
* @param title Excel表的标题,如果不存在,则传null
* @param headersParams 表头与属性值的对应关系数组
* @param dataList 导出Excel数据
* @param sheetMaxCount 单个sheet存储数据量最大值
* */
@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
public static <T> Workbook getWorkbook(String title, List<String> headersParams, List<T> dataList, int sheetMaxCount) {
//获取导出总数据量
int count = dataList.size();
//获取要分多少个sheet
int page = count%sheetMaxCount > 0 ? count/sheetMaxCount + 1 : count/sheetMaxCount;
//拆分大的List为多个小的List
List<List> splitList = getSplitList(dataList, sheetMaxCount);
//建表
Workbook wb = new HSSFWorkbook();
for(int i = 0;i < page;i++){
int m = 0;
//创建sheet
Sheet sheet = wb.createSheet();
if(title != null){
wb.setSheetName(i, title+i);
//设置标题
for(int j = 0;j < 2;j++){
Row titleRow = sheet.createRow(i);
for(int k = 0;k < headersParams.size();k++){
Cell titleCell = titleRow.createCell(k);
CellStyle titleStyle = getStyle(wb);
titleCell.setCellStyle(titleStyle);
//标题内容只设置一次就行,且值只能设置在标题所占的位置的首行首列,否则合并单元格时值会被覆盖
if(j == 0 && k == 0){
titleCell.setCellValue(title);
titleCell.setCellStyle(titleStyle);
}
}
}
//合并标题单元格
sheet.addMergedRegion(new CellRangeAddress(0, 1,0,headersParams.size()-1));
m = 2;
}

//获取表头及其对应的属性
String[] headers = new String[headersParams.size()];
String[] params = new String[headersParams.size()];
for(int j = 0;j < headersParams.size();j++){
String[] hsPs = headersParams.get(j).toString().split("=");
headers[j] = hsPs[0];
params[j] = hsPs[1];
}

//设置表头
Row headRow = sheet.createRow(m);
for(int j = 0;j < headers.length;j++){
Cell headerCell = headRow.createCell(j);
headerCell.setCellValue(headers[j]);
}
//获取单个sheet需要填充的数据
List<T> smallList = splitList.get(i);
//给单个sheet填充数据
//获取反射模版
Class clazz = null;
for(int j = 0;j < smallList.size();j++){
clazz = smallList.get(0).getClass();
Row paramRow = sheet.createRow(j + 1 + m);
for(int k = 0;k < params.length;k++){
try {
Field field = clazz.getDeclaredField(params[k]);
Method method = clazz.getMethod(getMethodName(params[k]));
Object obj = method.invoke(smallList.get(j));

Cell paramCell = paramRow.createCell(k);
//判断是否为时间格式
if(obj.getClass() == Date.class){
if(obj != null){
CreationHelper creationHelper = wb.getCreationHelper();
CellStyle dateStyle = wb.createCellStyle();
dateStyle.setDataFormat(
creationHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
paramCell.setCellStyle(dateStyle);
paramCell.setCellValue((Date)obj);
}else{
paramCell.setCellValue("");
}
}else{
if(obj != null){
paramCell.setCellValue(obj.toString());
}else{
paramCell.setCellValue("");
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
return wb;
}

/**
* 导出单个sheet的Excel
* @param title Excel表的标题,如果不存在,则传null
* @param headersParams 表头与属性值的对应关系数组
* @param dataList 导出Excel数据
* */
@SuppressWarnings({ "rawtypes", "unused", "unchecked" })
public static <T> Workbook getWorkbook(String title,List<String> headersParams,List<T> dataList) {
//建表
Workbook wb = new HSSFWorkbook();
//创建工作簿
Sheet sheet = wb.createSheet();

//设置起始行,默认为0
int m = 0;
//判断是否存在标题
if(title != null){
wb.setSheetName(0, title);
//设置标题
for(int i = 0;i < 2;i++){
Row titleRow = sheet.createRow(i);
for(int j = 0;j < headersParams.size();j++){
Cell titleCell = titleRow.createCell(j);
CellStyle titleStyle = getStyle(wb);
titleCell.setCellStyle(titleStyle);

//标题内容只设置一次就行,且值只能设置在标题所占的位置的首行首列,否则合并单元格时值会被覆盖
if(j == 0 && i == 0){
titleCell.setCellValue(title);
titleCell.setCellStyle(titleStyle);

}

}
}
//合并标题单元格
sheet.addMergedRegion(new CellRangeAddress(0, 1,0,headersParams.size()-1));
m = 2;
}

String[] headers = new String[headersParams.size()];
String[] params = new String[headersParams.size()];
for(int i = 0;i < headersParams.size();i++){
String[] headerParam = headersParams.get(i).split("=");
headers[i] = headerParam[0];
params[i] = headerParam[1];
}
//设置表头
Row headRow = sheet.createRow(m);
for(int i = 0;i < headers.length;i++){
Cell headerCell = headRow.createCell(i);
headerCell.setCellValue(headers[i]);
}
//填入数据
//获取反射模版
Class clazz = null;
if(dataList != null && dataList.size() > 0){
clazz = dataList.get(0).getClass();
for(int i = 0;i < dataList.size();i++){
Row paramRow = sheet.createRow(i + 1 + m);
for(int j = 0;j < params.length;j++){
try {
Cell paramCell = paramRow.createCell(j);
Field field = clazz.getDeclaredField(params[j]);
Method method = clazz.getMethod(getMethodName(params[j]));
Object obj = method.invoke(dataList.get(i));

//判断是否为时间格式
if(obj.getClass() == Date.class){
if(obj != null){
CreationHelper creationHelper = wb.getCreationHelper();
CellStyle dateStyle = wb.createCellStyle();
dateStyle.setDataFormat(
creationHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
paramCell.setCellStyle(dateStyle);
paramCell.setCellValue((Date)obj);
}else{
paramCell.setCellValue("");
}
}else{
if(obj != null){
paramCell.setCellValue(obj.toString());
}else{
paramCell.setCellValue("");
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

}
}
return wb;
}

/**
*
* 设置标题边框
*@param workbook Excel对象
*@param titleRow 标题行
*@param headersParams 列名属性名,对应关系的List
*@return CellStyle 标题样式
*@since (此方法开始于哪个版本)0.0.3
*@author yk
*
*/
@SuppressWarnings("deprecation")
public static CellStyle getStyle(Workbook wb) {
//创建显示样式
CellStyle style = wb.createCellStyle();
//创建字体样式
Font font = wb.createFont();

font.setFontHeight((short) 280);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);

style.setAlignment(HorizontalAlignment.CENTER);
//设置边框
style.setBorderBottom(CellStyle.BORDER_THIN);
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setBorderRight(CellStyle.BORDER_THIN);
style.setBorderTop(CellStyle.BORDER_THIN);
style.setFont(font);
return style;
}
/*
* 标题样式
*/
@SuppressWarnings("deprecation")
public static <T> CellStyle getTitleStyle(Workbook workbook) {

// 设置字体
Font font = workbook.createFont();
//设置字体大小
font.setFontHeightInPoints((short)11);
//字体加粗
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
//设置字体名字
font.setFontName("Courier New");
//设置样式;
CellStyle style = workbook.createCellStyle();
style.setFont(font);
//设置自动换行;
style.setWrapText(false);
//设置水平对齐的样式为居中对齐;
style.setAlignment(CellStyle.ALIGN_CENTER);
//设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
return style;

}

/*
* 列头单元格样式
*/
@SuppressWarnings("deprecation")
public CellStyle getColumnTopStyle(Workbook workbook) {

// 设置字体
Font font = workbook.createFont();
//设置字体大小
font.setFontHeightInPoints((short)11);
//字体加粗
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
//设置字体名字
font.setFontName("Courier New");
//设置样式;
CellStyle style = workbook.createCellStyle();
//设置底边框;
style.setBorderBottom(CellStyle.BORDER_THIN);
//设置左边框;
style.setBorderLeft(CellStyle.BORDER_THIN);
//设置右边框;
style.setBorderRight(CellStyle.BORDER_THIN);
//设置顶边框;
style.setBorderTop(CellStyle.BORDER_THIN);
//在样式用应用设置的字体;
style.setFont(font);
//设置自动换行;
style.setWrapText(false);
//设置水平对齐的样式为居中对齐;
style.setAlignment(CellStyle.ALIGN_CENTER);
//设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);

return style;

}

/*
* 列数据信息单元格样式
*/
@SuppressWarnings("deprecation")
public CellStyle getCellStyle(Workbook workbook) {
// 设置字体
Font font = workbook.createFont();
//设置字体大小
//font.setFontHeightInPoints((short)10);
//字体加粗
//font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
//设置字体名字
font.setFontName("Courier New");
//设置样式;
CellStyle style = workbook.createCellStyle();
//设置底边框;
style.setBorderBottom(CellStyle.BORDER_THIN);
//设置左边框;
style.setBorderLeft(CellStyle.BORDER_THIN);
//设置右边框;
style.setBorderRight(CellStyle.BORDER_THIN);
//设置顶边框;
style.setBorderTop(CellStyle.BORDER_THIN);
//在样式用应用设置的字体;
style.setFont(font);
//设置自动换行;
style.setWrapText(false);
//设置水平对齐的样式为居中对齐;
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

return style;

}

/*
* 获取方法名
* @param 属性名
* */
private static String getMethodName(String fieldName){
return "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
}

}

利用poi导出Excel的更多相关文章

  1. struts2中利用POI导出Excel文档并下载

    1.项目组负责人让我实现这个接口,因为以前做过类似的,中间并没有遇到什么太困难的事情.其他不说,先上代码: package com.tydic.eshop.action.feedback; impor ...

  2. JAVAWeb SSH框架 利用POI 导出EXCEL,弹出保存框

    导入包这一些不多说,直接贴出关键代码,JSP只要点一个Action链接就行. poi包我是用:poi-3.11-20141221.jar 亲测有效: 效果: Action 类代码: private I ...

  3. Spring Boot利用poi导出Excel

    至于poi的用法就不多说了,网上多得很,但是发现spring boot结合poi的就不多了,而且大多也有各种各样的问题. public class ExcelData implements Seria ...

  4. Java Web利用POI导出Excel简单例子

    采用Spring mvc架构: Controller层代码如下 @Controller public class StudentExportController{ @Autowired private ...

  5. 使用POI导出Excel(二)-利用模板

    一.基本操作见: 使用POI导出Excel 二.本次功能需求 给了一个模板,里面有6个sheet页,每页里面都需要填充相应的数据.如图: 三.需求分析 1.分了6个sheet页,每页的数据都不一样,首 ...

  6. POI导出EXCEL经典实现

    1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则 ...

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

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

  8. java中使用poi导出excel表格数据并且可以手动修改导出路径

    在我们开发项目中,很多时候会提出这样的需求:将前端的某某数据以excel表格导出,今天就给大家写一个简单的模板. 这里我们选择使用poi导出excel: 第一步:导入需要的jar包到 lib 文件夹下

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

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

随机推荐

  1. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

  2. IE的F12开发人员工具不显示问题

    按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的缩略图上,右键-最大化,工具就全屏出现 ...

  3. Android性能优化之利用LeakCanary检测内存泄漏及解决办法

    前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...

  4. zookeeper源码分析之六session机制

    zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...

  5. IdentityServer4 使用OpenID Connect添加用户身份验证

    使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...

  6. 手机web如何实现多平台分享

    话说App一般都带有分享到社交平台的入口,web网页的分享也有很不错的框架,但是随着HTML5的不断发展,手机web页面越来越多的进入到我们的生活中,那如何在我们的手机上完成分享呢?话说各大分享平台都 ...

  7. document.compatMode

    在我电脑屏幕上显示的 电脑是 1920*1080这是在document.compatMode:css1Compat模式 window.screen.availWidth 1920 window.scr ...

  8. Linux的学习笔记

    Linux,1991年,系统安全,良好的可移植性,多用户,多任务,良好的兼容性,良好的用户界面, 主流的是RedHat或者CentOS, CentOS 设置的网关 192.168.2.2 Window ...

  9. Hyper-V上运行的Linux虚拟机验证是否安装了集成服务

    Hyper-V上运行的Linux虚拟机验证是否安装了集成服务 ps aux|grep "hv"root       311  0.0  0.0      0     0 ?     ...

  10. 网站的SEO以及它和站长工具的之间秘密

    博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...