Excel的导入与导出(POI)
ExcelAnnotation.java;
package cn.chn.chen.dev.excel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* ExcelAnnotation类主要用于-.
* </p>
* <p>
* 创建时间 2011-4-18 - 下午10:05:47
* </p>
* <blockquote>
* <h4>历史修改记录</h4>
* <ul>
* <li>修改人 修改时间 修改描述
* </ul>
* </blockquote>
* <p>
* copyright cd×××× 2010-2011, all rights reserved.
* </p>
*
* @author IT山人
* @since 1.0
* @version 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
// excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
public String exportName();
}
ExcelStyle.java;
package cn.chn.chen.dev.excel;
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;
/**
* <p>
* ExcelStyle类主要用于-excel导出样式控制.
* </p>
* <p>
* 创建时间 2011-4-21 - 下午12:43:11
* </p>
* @author IT山人
*/
public class ExcelStyle {
public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook,
HSSFCellStyle style) {
style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 生成字体
HSSFFont font = workbook.createFont();
font.setColor(HSSFColor.VIOLET.index);
font.setFontHeightInPoints((short) 12);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样样式
style.setFont(font);
return style;
}
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.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 生成字体
HSSFFont font = workbook.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样样式
style.setFont(font);
return style;
}
}
ImportExcel.java;
package cn.chn.chen.dev.excel;
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.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
/**
* <p>
* ImportExcel类主要用于-Excel导入(POI).
* </p>
* <p>
* 创建时间 2011-4-18 - 下午10:33:52
* </p>
* @author IT山人
*/
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[] fields = clazz.getDeclaredFields();
// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
Map<String, Method> fieldMap = new HashMap<String, Method>();
// 循环读取所有字段
for (Field field : fields) {
// 得到单个字段上的Annotation
ExcelAnnotation excelAnnotation = field.getAnnotation(ExcelAnnotation.class);
// 如果标识了Annotationd
if (excelAnnotation != null) {
String fieldName = field.getName();
// 构造设置了Annotation的字段的Setter方法
String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
// 构造调用的method
Method setMethod = clazz.getMethod(setMethodName, new Class[] {field.getType()});
// 将这个method以Annotaion的名字为key来存入
fieldMap.put(excelAnnotation.exportName(), setMethod);
}
}
/**
* excel的解析开始
*/
// 将传入的File构造为FileInputStream;
FileInputStream inputStream = new FileInputStream(file);
// 得到工作表
HSSFWorkbook book = new HSSFWorkbook(inputStream);
// 得到第一页
HSSFSheet sheet = book.getSheetAt(0);
// 得到第一面的所有行
Iterator<Row> row = sheet.rowIterator();
/**
* 标题解析
*/
// 得到第一行,也就是标题行
Row titleRow = row.next();
// 得到第一行的所有列
Iterator<Cell> cellTitle = titleRow.cellIterator();
// 将标题的文字内容放入到一个map中
Map<Integer, String> titleMap = new HashMap<Integer, String>();
// 从标题第一列开始
int i = 0;
// 循环标题所有的列
while (cellTitle.hasNext()) {
Cell cell = (Cell) cellTitle.next();
String value = cell.getStringCellValue();
titleMap.put(i, value);
i++;
}
/**
* 解析内容行
*/
while (row.hasNext()) {
// 标题下的第一行
Row rown = row.next();
// 行的所有列
Iterator<Cell> cellBody = rown.cellIterator();
// 得到传入类的实例
T tObject = clazz.newInstance();
// 遍历一行的列
int col = 0;
while (cellBody.hasNext()) {
Cell cell = (Cell) cellBody.next();
// 这里得到此列的对应的标题
String titleString = titleMap.get(col++);
// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
if (fieldMap.containsKey(titleString)) {
Method setMethod = fieldMap.get(titleString);
//得到setter方法的参数
Type[] types = setMethod.getGenericParameterTypes();
//只要一个参数
String xclass = String.valueOf(types[0]);
//判断参数类型
if ("class java.lang.String".equals(xclass)) {
setMethod.invoke(tObject, cell.getStringCellValue());
} else if ("class java.util.Date".equals(xclass)) {
setMethod.invoke(tObject, cell.getDateCellValue());
} else if ("class java.lang.Boolean".equals(xclass)) {
Boolean boolName = true;
if ("否".equals(cell.getStringCellValue())) {
boolName = false;
}
setMethod.invoke(tObject, boolName);
} else if ("class java.lang.Integer".equals(xclass)) {
setMethod.invoke(tObject, new Integer(String.valueOf((int)cell.getNumericCellValue())));
} else if ("class java.lang.Long".equals(xclass)) {
setMethod.invoke(tObject, new Long(cell.getStringCellValue()));
} else {
//
}
}
}
dist.add(tObject);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
return dist;
}
public static void main(String[] args) {
ImportExcel<TestVo> test = new ImportExcel<TestVo>(TestVo.class);
File file = new File("D:\\testOne.xls");
List<TestVo> results = (List<TestVo>) test.importExcel(file);
SimpleDateFormat simpleDateFormat;
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (TestVo testVo : results) {
System.out.println(testVo.getName() + "\t" + testVo.getSex() + "\t" + simpleDateFormat.format(testVo.getBrith()));
}
}
}
ExcelExport.java;
package cn.chn.chen.dev.excel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
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;
/**
* <p>
* ExcelExport类主要用于-excel导出(POI).
* </p>
* <p>
* 创建时间 2011-4-21 - 下午12:34:33
* </p>
* @author IT山人
*/
public class ExcelExport<T> {
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* <p>
* exportExcel方法-poi Excel导出.
* </p>
* <p>
* 创建人 IT山人 创建时间 2011-4-21 - 下午09:36:21
* </p>
* @param title 工作簿名称
* @param dataset 导出的数据集
* @param out 输出流
*/
@SuppressWarnings("unchecked")
public void exportExcel(String title, Collection<T> dataset, OutputStream out) {
// 声明一个工作薄
try {
//首先检查数据看是否是正确的
Iterator<T> iterator = dataset.iterator();//返回在此 collection 的元素上进行迭代的迭代器即泛
型中的类。
if (dataset == null || !iterator.hasNext() || title == null || out == null) {
throw new Exception("传入的数据不对!");
}
//取得实际泛型类
T tObject = iterator.next();
Class<T> clazz = (Class<T>) tObject.getClass();
HSSFWorkbook workbook = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为20个字节
sheet.setDefaultColumnWidth(20);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置标题样式
style = ExcelStyle.setHeadStyle(workbook, style);
// 得到所有字段
Field filed[] = tObject.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 field = filed[i];
ExcelAnnotation excelAnnotation = field.getAnnotation(ExcelAnnotation.class);
// 如果设置了annottion
if (excelAnnotation != null) {
String exprot = excelAnnotation.exportName();
// 添加到标题
exportfieldtile.add(exprot);
// 添加到需要导出的字段的方法
String fieldname = field.getName();
String getMethodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1);
Method getMethod = clazz.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;
iterator = dataset.iterator();
while (iterator.hasNext()) {
//从第二行开始写,第一行是标题
index++;
row = sheet.createRow(index);
T t = (T) iterator.next();
for (int k = 0; k < methodObj.size(); k++) {
HSSFCell cell = row.createCell(k);
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();
}
}
/**
* <p>
* getValue方法-cell值处理.
* </p>
* <p>
* 创建人 IT山人 创建时间 2011-4-21 - 下午09:38:31
* </p>
* @param value
* @return
*/
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 IOException {
OutputStream out = new FileOutputStream("D:\\testOne1.xls");
ExcelExport<TestVo> ex = new ExcelExport<TestVo>();
ImportExcel<TestVo> test = new ImportExcel<TestVo>(TestVo.class);
File file = new File("D:\\testOne.xls");
List<TestVo> results = (List<TestVo>) test.importExcel(file);
ex.exportExcel("测试", results, out);
out.close();
}
}
ImportExcell.java;
package cn.chn.chen.dev.excel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
/**
* <p>
* ImportExcell类主要用于-.
* </p>
* <p>
* 创建时间 2011-4-21 - 下午04:45:33
* </p>
* @author IT山人
*/
public class ImportExcell {
private static final Log log = LogFactory.getLog(ImportExcell.class);
/**
* <p>
* readExcel方法-读取excel,行为list,列为Map.
* </p>
* <p>
* 创建人 IT山人 创建时间 2011-4-21 - 下午09:46:33
* </p>
* @param file excel文件
* @return excel表数据集合-行为list,列为Map
*/
public List<Map<String, String>> readExcel(File file) {
log.info("读取excel开始...");
List<Map<String, String>> dataset = new ArrayList<Map<String, String>>();
try {
// 将传入的File构造为FileInputStream;
FileInputStream inputStream = new FileInputStream(file);
// 得到工作表
HSSFWorkbook book = new HSSFWorkbook(inputStream);
// 得到第一页
HSSFSheet sheet = book.getSheetAt(0);
// 得到第一面的所有行
Iterator<Row> rowIterator = sheet.rowIterator();
// 得到第一行,也就是标题行
@SuppressWarnings("unused")
Row titleRow = rowIterator.next();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Map<String, String> map = this.creatObjectByRow(row);
dataset.add(map);
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
}
log.info("读取excel结束...");
return dataset;
}
/**
* <p>
* creatObjectByRow方法-将每行的数据装载Map中.
* </p>
* <p>
* 创建人 IT山人 创建时间 2011-4-21 - 下午09:48:17
* </p>
* @param row
* @return
*/
private Map<String, String> creatObjectByRow(Row row) {
// 行的所有列
Iterator<Cell> cellBody = row.cellIterator();
// 遍历一行的列
int col = 1;
Map<String, String> map = new HashMap<String, String>();
while (cellBody.hasNext()) {
String field = String.valueOf(col++);
Cell cell = cellBody.next();
if (cell != null) {
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING: // 字符
map.put(field, StringUtils.trim(cell.getStringCellValue()));
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // 布尔
map.put(field, StringUtils.trim(cell.getStringCellValue()));
break;
case HSSFCell.CELL_TYPE_NUMERIC: // 数字
if (HSSFDateUtil.isCellDateFormatted(cell)) {// 是否为日期格式
map.put(field, String.valueOf(cell.getDateCellValue()));
} else {
Double cellValue_dob = cell.getNumericCellValue();// 读取cell内数据
if (String.valueOf(cellValue_dob).length() > 11) { // 如果读取到的是手机号码,需要匹配数字格式
DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
//format.applyPattern("00000000000");
map.put(field, format.format(cellValue_dob));
} else { // 如果读取到的是比较短的数字,则去掉尾数(.0)后显示
map.put(field, cellValue_dob.toString().substring(0, cellValue_dob.toString().length() - 2));
}
}
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
map.put(field, String.valueOf(cell.getNumericCellValue()));
break;
case HSSFCell.CELL_TYPE_BLANK: // 空
map.put(field, StringUtils.trim(cell.getStringCellValue()));
break;
case HSSFCell.CELL_TYPE_ERROR: // 异常
map.put(field, StringUtils.trim(cell.getStringCellValue()));
break;
default:
map.put(field, StringUtils.trim(cell.getStringCellValue()));
break;
}
}
}
return map;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ImportExcell inport = new ImportExcell();
File file = new File("D:\\testOne.xls");
List<Map<String, String>> mapList = inport.readExcel(file);
for (Map<String, String> map : mapList) {
// Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
// while (iterator.hasNext()) {
// Map.Entry<String, String> entry = iterator.next();
// String key = entry.getKey();
// String value = entry.getValue();
// System.out.println("key:" + key + "\tvalue:" + value);
// }
TestVo t = new TestVo();
t.setName(map.get("1"));
System.out.println(t.getName());
}
}
}
TestVo.java;
public class TestVo {
@ExcelAnnotation(exportName="姓名")
private String name;
@ExcelAnnotation(exportName="性别")
private Integer sex;
@ExcelAnnotation(exportName="出生年月")
private Date brith;
/**
* @return 返回 name
*/
public String getName() {
return name;
}
/**
* @param name 设置 name
*/
public void setName(String name) {
this.name = name;
}
/**
* @return 返回 sex
*/
public Integer getSex() {
return sex;
}
/**
* @param sex 设置 sex
*/
public void setSex(Integer sex) {
this.sex = sex;
}
/**
* @return 返回 brith
*/
public Date getBrith() {
return brith;
}
/**
* @param brith 设置 brith
*/
public void setBrith(Date brith) {
this.brith = brith;
}
}