Excel工具类

package com.ffnt.comm.util;

 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import javax.servlet.http.HttpServletResponse;

import javax.swing.plaf.synth.Region;

 

import jxl.Cell;

import jxl.Sheet;

import jxl.Workbook;

import jxl.read.biff.BiffException;

 

import org.apache.poi.hssf.usermodel.DVConstraint;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import org.apache.poi.hssf.usermodel.HSSFDataValidation;

import org.apache.poi.hssf.usermodel.HSSFFont;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.util.CellRangeAddress;

import org.apache.poi.ss.util.CellRangeAddressList;

 

/*

* ExcelUtil工具类实现功能:

* 导出时传入list<T>,即可实现导出为一个excel,其中每个对象T为Excel中的一条记录.

* 导入时读取excel,得到的结果是一个list<T>.T是自己定义的对象.

* 需要导出的实体对象只需简单配置注解就能实现灵活导出,通过注解您可以方便实现下面功能:

* 1.实体属性配置了注解就能导出到excel中,每个属性都对应一列.

* 2.列名称可以通过注解配置.

* 3.导出到哪一列可以通过注解配置.

* 4.鼠标移动到该列时提示信息可以通过注解配置.

* 5.用注解设置只能下拉选择不能随意填写功能.

* 6.用注解设置是否只导出标题而不导出内容,这在导出内容作为模板以供用户填写时比较实用.

* 本工具类以后可能还会加功能,请关注我的博客: http://blog.csdn.net/lk_blog

*/

public class ExcelUtilReport<T> {

Class<T> clazz;

 

public ExcelUtilReport(Class<T> clazz) {

this.clazz = clazz;

}

 

public List<T> importExcel(String sheetName, InputStream input) {

List<T> list = new ArrayList<T>();

try {

Workbook book = Workbook.getWorkbook(input);

Sheet sheet = null;

if (!sheetName.trim().equals("")) {

sheet = book.getSheet(sheetName);// 如果指定sheet名,则取指定sheet中的内容.

}

if (sheet == null) {

sheet = book.getSheet(0);// 如果传入的sheet名不存在则默认指向第1个sheet.

}

int rows = sheet.getRows();// 得到数据的行数

if (rows > 0) {// 有数据时才处理

Field[] allFields = clazz.getDeclaredFields();// 得到类的所有field.

Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();// 定义一个map用于存放列的序号和field.

for (Field field : allFields) {

// 将有注解的field存放到map中.

if (field.isAnnotationPresent(ExcelVOAttribute.class)) {

ExcelVOAttribute attr = field

.getAnnotation(ExcelVOAttribute.class);

int col = getExcelCol(attr.column());// 获得列号

// System.out.println(col + "====" + field.getName());

field.setAccessible(true);// 设置类的私有字段属性可访问.

fieldsMap.put(col, field);

}

}

for (int i = 1; i < rows; i++) {// 从第2行开始取数据,默认第一行是表头.

Cell[] cells = sheet.getRow(i);// 得到一行中的所有单元格对象.

T entity = null;

for (int j = 0; j < cells.length; j++) {

String c = cells[j].getContents();// 单元格中的内容.

if (c.equals("")) {

continue;

}

entity = (entity == null ? clazz.newInstance() : entity);// 如果不存在实例则新建.

// System.out.println(cells[j].getContents());

Field field = fieldsMap.get(j);// 从map中得到对应列的field.

// 取得类型,并根据对象类型设置值.

Class<?> fieldType = field.getType();

if ((Integer.TYPE == fieldType)

|| (Integer.class == fieldType)) {

field.set(entity, Integer.parseInt(c));

} else if (String.class == fieldType) {

field.set(entity, String.valueOf(c));

} else if ((Long.TYPE == fieldType)

|| (Long.class == fieldType)) {

field.set(entity, Long.valueOf(c));

} else if ((Float.TYPE == fieldType)

|| (Float.class == fieldType)) {

field.set(entity, Float.valueOf(c));

} else if ((Short.TYPE == fieldType)

|| (Short.class == fieldType)) {

field.set(entity, Short.valueOf(c));

} else if ((Double.TYPE == fieldType)

|| (Double.class == fieldType)) {

field.set(entity, Double.valueOf(c));

} else if (Character.TYPE == fieldType) {

if ((c != null) && (c.length() > 0)) {

field.set(entity, Character

.valueOf(c.charAt(0)));

}

}

 

}

if (entity != null) {

list.add(entity);

}

}

}

 

} catch (BiffException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

}

return list;

}

 

/**

* 对list数据源将其里面的数据导入到excel表单

*

* @param sheetName

* 工作表的名称

* @param sheetSize

* 每个sheet中数据的行数,此数值必须小于65536

* @param output

* java输出流

* @throws IOException

*/

public boolean exportExcel(List<T> list, String sheetName, int sheetSize,HttpServletResponse response,String title) throws IOException {

 

Field[] allFields = clazz.getDeclaredFields();// 得到所有定义字段

List<Field> fields = new ArrayList<Field>();

// 得到所有field并存放到一个list中.

for (Field field : allFields) {

if (field.isAnnotationPresent(ExcelVOAttribute.class)) {

fields.add(field);

}

}

 

HSSFWorkbook workbook = new HSSFWorkbook();// 产生工作薄对象

 

// excel2003中每个sheet中最多有65536行,为避免产生错误所以加这个逻辑.

if (sheetSize > 65536 || sheetSize < 1) {

sheetSize = 65536;

}

double sheetNo = Math.ceil(list.size() / sheetSize);// 取出一共有多少个sheet.

for (int index = 0; index <= sheetNo; index++) {

HSSFSheet sheet = workbook.createSheet();// 产生工作表对象

workbook.setSheetName(index, sheetName + index);// 设置工作表的名称.

HSSFRow row;

HSSFCell cell;// 产生单元格

HSSFCellStyle headerStyle = (HSSFCellStyle) workbook.createCellStyle();// 创建标题样式

headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

HSSFFont headerFont = (HSSFFont) workbook.createFont();

headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 字体加粗

headerFont.setFontName("宋体");

headerFont.setFontHeightInPoints((short) 10);

headerStyle.setFont(headerFont);

headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框

headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框

headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框

headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框

row = sheet.createRow(0);// 产生一行

cell=row.createCell(0);

//合并第一行单元格

sheet.addMergedRegion(new CellRangeAddress(0,0,0,(fields.size()-1)));

cell.setCellValue(title);

row = sheet.createRow(1);// 产生一行

// 写入各个字段的列头名称

for (int i = 0; i < fields.size(); i++) {

Field field = fields.get(i);

ExcelVOAttribute attr = field

.getAnnotation(ExcelVOAttribute.class);

int col = getExcelCol(attr.column());// 获得列号

cell = row.createCell(col);// 创建列

cell.setCellStyle(headerStyle);//设置表头单元格格式

cell.setCellType(HSSFCell.CELL_TYPE_STRING);// 设置列中写入内容为String类型

cell.setCellValue(attr.name());// 写入列名

 

// 如果设置了提示信息则鼠标放上去提示.

if (!attr.prompt().trim().equals("")) {

setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, col, col);// 这里默认设了2-101列提示.

}

// 如果设置了combo属性则本列只能选择不能输入

if (attr.combo().length > 0) {

setHSSFValidation(sheet, attr.combo(), 1, 100, col, col);// 这里默认设了2-101列只能选择不能输入.

}

}

int startNo = index * sheetSize;

int endNo = Math.min(startNo + sheetSize, list.size());

// 写入各条记录,每条记录对应excel表中的一行

for (int i = startNo; i < endNo; i++) {

row = sheet.createRow(i + 2 - startNo);

T vo = (T) list.get(i); // 得到导出对象.

for (int j = 0; j < fields.size(); j++) {

Field field = fields.get(j);// 获得field.

field.setAccessible(true);// 设置实体类私有属性可访问

ExcelVOAttribute attr = field

.getAnnotation(ExcelVOAttribute.class);

try {

// 根据ExcelVOAttribute中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.

if (attr.isExport()) {

cell = row.createCell(getExcelCol(attr.column()));// 创建cell

cell.setCellType(HSSFCell.CELL_TYPE_STRING);

cell.setCellValue(field.get(vo) == null ? ""

: String.valueOf(field.get(vo)));// 如果数据存在就填入,不存在填入空格.

}

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

}

 

}

this.writer(workbook,response,sheetName);

return true;

 

}

/**

* 浏览器直接弹出框

* @param wb

* @param response

* @param deliveryId

* @throws IOException

*/

private void writer(HSSFWorkbook wb,HttpServletResponse response,String fileName) throws IOException{

 

OutputStream os = null;

try {

// 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用excel打开

response.setContentType("APPLICATION/OCTET-STREAM");

response.setCharacterEncoding("utf-8");

response.setHeader("Content-Disposition", "attachment; filename="+ new String( fileName.getBytes( "gbk" ), "ISO8859-1" )+ ".xls");

os = response.getOutputStream();

// 创建第一个工作表

wb.write(os);

} catch (Exception e) {

} finally {

os.flush();

os.close();

}

}

/**

* 将EXCEL中A,B,C,D,E列映射成0,1,2,3

*

* @param col

*/

public static int getExcelCol(String col) {

col = col.toUpperCase();

// 从-1开始计算,字母重1开始运算。这种总数下来算数正好相同。

int count = -1;

char[] cs = col.toCharArray();

for (int i = 0; i < cs.length; i++) {

count += (cs[i] - 64) * Math.pow(26, cs.length - 1 - i);

}

return count;

}

 

/**

* 设置单元格上提示

*

* @param sheet

* 要设置的sheet.

* @param promptTitle

* 标题

* @param promptContent

* 内容

* @param firstRow

* 开始行

* @param endRow

* 结束行

* @param firstCol

* 开始列

* @param endCol

* 结束列

* @return 设置好的sheet.

*/

public static HSSFSheet setHSSFPrompt(HSSFSheet sheet, String promptTitle,

String promptContent, int firstRow, int endRow, int firstCol,

int endCol) {

// 构造constraint对象

DVConstraint constraint = DVConstraint

.createCustomFormulaConstraint("DD1");

// 四个参数分别是:起始行、终止行、起始列、终止列

CellRangeAddressList regions = new CellRangeAddressList(firstRow,

endRow, firstCol, endCol);

// 数据有效性对象

HSSFDataValidation data_validation_view = new HSSFDataValidation(

regions, constraint);

data_validation_view.createPromptBox(promptTitle, promptContent);

sheet.addValidationData(data_validation_view);

return sheet;

}

 

/**

* 设置某些列的值只能输入预制的数据,显示下拉框.

*

* @param sheet

* 要设置的sheet.

* @param textlist

* 下拉框显示的内容

* @param firstRow

* 开始行

* @param endRow

* 结束行

* @param firstCol

* 开始列

* @param endCol

* 结束列

* @return 设置好的sheet.

*/

public static HSSFSheet setHSSFValidation(HSSFSheet sheet,

String[] textlist, int firstRow, int endRow, int firstCol,

int endCol) {

// 加载下拉列表内容

DVConstraint constraint = DVConstraint

.createExplicitListConstraint(textlist);

// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列

CellRangeAddressList regions = new CellRangeAddressList(firstRow,

endRow, firstCol, endCol);

// 数据有效性对象

HSSFDataValidation data_validation_list = new HSSFDataValidation(

regions, constraint);

sheet.addValidationData(data_validation_list);

return sheet;

}

//导出excel实体类配置

package com.bigzone.xt.scm.vo.member;

 

import java.io.Serializable;

 

import com.bigzone.xt.scm.util.ExcelVOAttribute;

 

public class StMemberCareVo implements Serializable {

private static final long serialVersionUID = 1L;

/**

* 序号

*/

@ExcelVOAttribute(name = "序号", column = "A", isExport = true)

private String num;

/**

* 会员姓名

*/

@ExcelVOAttribute(name = "会员姓名", column = "B", isExport = true)

private String memberName;

/**

* 性别

*/

@ExcelVOAttribute(name = "性别", column = "C", isExport = true)

private String realSex;

/**

* 生日

*/

@ExcelVOAttribute(name = "生日", column = "D", isExport = true)

private String birthdayStr;

/**

* 手机号码

*/

@ExcelVOAttribute(name = "电话", column = "E", isExport = true)

private String mobile;

 

public String getNum() {

return num;

}

 

public void setNum(String num) {

this.num = num;

}

 

public String getMemberName() {

return memberName;

}

 

public void setMemberName(String memberName) {

this.memberName = memberName;

}

 

public String getRealSex() {

return realSex;

}

 

public void setRealSex(String realSex) {

this.realSex = realSex;

}

 

public String getBirthdayStr() {

return birthdayStr;

}

 

public void setBirthdayStr(String birthdayStr) {

this.birthdayStr = birthdayStr;

}

 

public String getMobile() {

return mobile;

}

 

public void setMobile(String mobile) {

this.mobile = mobile;

}

}

 

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值