Excel文件操作
来源:互联网 发布:开淘宝初期卖什么好呢 编辑:程序博客网 时间:2024/06/07 07:51
package com.zzy.skd.dao.utils;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
public class ExcelUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelUtils.class);
/**
* 将Excel转化为List
*
* @param in :承载着Excel的输入流
* @param sheetName :要导入的工作表序号
* @param entityClass :List中对象的类型(Excel中的每一行都要转化为该类型的对象)
* @param fieldMap :Excel中的中文列头和类的英文属性的对应关系Map
* @param uniqueFields :指定业务主键组合(即复合主键),这些列的组合不能重复
* @return list集合
* @throws Exception 异常
*/
public static <T> List<T> excelToList(InputStream in, String sheetName, Class<T> entityClass,
LinkedHashMap<String, String> fieldMap, String[] uniqueFields) throws Exception {
// 定义要返回的list
List<T> resultList = new ArrayList<T>();
try {
// 根据Excel数据源创建WorkBook
Workbook wb = Workbook.getWorkbook(in);
// 获取工作表
Sheet sheet = null;
if(StringUtils.isNotBlank(sheetName)){
sheet = wb.getSheet(sheetName);
}else{
sheet = wb.getSheet(0);
}
// 获取工作表的有效行数
int realRows = 0;
for (int i = 0; i < sheet.getRows(); i++) {
int nullCols = 0;
for (int j = 0; j < sheet.getColumns(); j++) {
Cell currentCell = sheet.getCell(j, i);
if (currentCell == null || "".equals(currentCell.getContents().toString())) {
nullCols++;
}
}
if (nullCols == sheet.getColumns()) {
break;
} else {
realRows++;
}
}
// 如果Excel中没有数据则提示错误
if (realRows <= 1) {
LOGGER.error("[ExcelUtil][listToExcel] no data row is {}", realRows);
throw new Exception("Excel文件中没有任何数据");
}
// 如果Excel中数据太大
if (realRows > 20001) {
LOGGER.error("[ExcelUtil][listToExcel] realRows is out of 20000! current row is {}", realRows);
throw new Exception("Excel文件中数据行数 " + realRows + " 超过两万,请分批导入");
}
Cell[] firstRow = sheet.getRow(0);
String[] excelFieldNames = new String[firstRow.length];
// 获取Excel中的列名
for (int i = 0; i < firstRow.length; i++) {
excelFieldNames[i] = firstRow[i].getContents().toString().trim();
}
// 判断需要的字段在Excel中是否都存在
boolean isExist = true;
List<String> excelFieldList = Arrays.asList(excelFieldNames);
for (String cnName : fieldMap.keySet()) {
if (!excelFieldList.contains(cnName)) {
isExist = false;
break;
}
}
// 如果有列名不存在,则抛出异常,提示错误
if (!isExist) {
throw new Exception("Excel中缺少必要的字段,或字段名称有误");
}
// 将列名和列号放入Map中,这样通过列名就可以拿到列号
LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();
for (int i = 0; i < excelFieldNames.length; i++) {
colMap.put(excelFieldNames[i], firstRow[i].getColumn());
}
// 判断是否有重复行
// 1.获取uniqueFields指定的列
Cell[][] uniqueCells = new Cell[uniqueFields.length][];
for (int i = 0; i < uniqueFields.length; i++) {
int col = colMap.get(uniqueFields[i]);
uniqueCells[i] = sheet.getColumn(col);
}
// 2.从指定列中寻找重复行
for (int i = 1; i < realRows; i++) {
int nullCols = 0;
for (int j = 0; j < uniqueFields.length; j++) {
String currentContent = uniqueCells[j][i].getContents();
Cell sameCell = sheet.findCell(currentContent, uniqueCells[j][i].getColumn(),
uniqueCells[j][i].getRow() + 1, uniqueCells[j][i].getColumn(),
uniqueCells[j][realRows - 1].getRow(), true);
if (sameCell != null) {
nullCols++;
}
}
if (nullCols == uniqueFields.length) {
throw new Exception("Excel中有重复行,请检查");
}
}
// 将sheet转换为list
for (int i = 1; i < realRows; i++) {
// 新建要转换的对象
T entity = entityClass.newInstance();
// 给对象中的字段赋值
for (Entry<String, String> entry : fieldMap.entrySet()) {
// 获取中文字段名
String cnNormalName = entry.getKey();
// 获取英文字段名
String enNormalName = entry.getValue();
// 根据中文字段名获取列号
int col = colMap.get(cnNormalName);
// 获取当前单元格中的内容
String content = sheet.getCell(col, i).getContents().toString().trim();
// 给对象赋值
setFieldValueByName(enNormalName, content, entity);
}
resultList.add(entity);
}
} catch (Exception e) {
LOGGER.error("[ExcelUtil][listToExcel] error!{}", ExceptionUtils.getStackTrace(e));
// 如果是Exception,则直接抛出
if (e instanceof Exception) {
throw (Exception) e;
// 否则将其它异常包装成Exception再抛出
} else {
throw new Exception("导入Excel失败");
}
}
return resultList;
}
/**
* 根据字段名给对象的字段赋值
*
* @param fieldName 字段名
* @param fieldValue 字段值
* @param o 对象
* @throws Exception 异常
*/
public static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception {
Field field = getFieldByName(fieldName, o.getClass());
if (field != null) {
field.setAccessible(true);
// 获取字段类型
Class<?> fieldType = field.getType();
// 根据字段类型给字段赋值
if (String.class == fieldType) {
field.set(o, String.valueOf(fieldValue));
} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, NumberUtils.toInt(fieldValue.toString()));
}
} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, NumberUtils.toLong(fieldValue.toString()));
}
} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, NumberUtils.toFloat(fieldValue.toString()));
}
} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, NumberUtils.toShort(fieldValue.toString()));
}
} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, NumberUtils.toDouble(fieldValue.toString()));
}
} else if (Character.TYPE == fieldType) {
if ((fieldValue != null) && (StringUtils.isNotBlank(fieldValue.toString()))) {
field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));
}
} else if (Date.class == fieldType) {
Date date = DateUtils.parseDate(fieldValue.toString(), "yyyy-MM-dd", "yyyy/MM/dd", "yyyy-MM-dd HH:mm:ss");
field.set(o, date);
} else if (BigDecimal.class == fieldType) {
if (NumberUtils.isNumber(fieldValue.toString())) {
field.set(o, new BigDecimal(fieldValue.toString()));
}
} else {
field.set(o, fieldValue);
}
} else {
throw new Exception(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
}
}
/**
* 根据字段名获取字段
*
* @param fieldName 字段名
* @param clazz 包含该字段的类
* @return 字段
*/
public static Field getFieldByName(String fieldName, Class<?> clazz) {
// 拿到本类的所有字段
Field[] selfFields = clazz.getDeclaredFields();
// 如果本类中存在该字段,则返回
for (Field field : selfFields) {
if (field.getName().equals(fieldName)) {
return field;
}
}
// 否则,查看父类中是否存在此字段,如果有则返回
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
return getFieldByName(fieldName, superClazz);
}
// 如果本类和父类都没有,则返回空
return null;
}
}
- JAVA操作EXCEL文件
- 直接操作excel文件
- asp操作excel文件
- vb操作EXCEL文件
- JAVA 操作EXCEL文件
- vb操作Excel文件
- Excel文件操作类
- Excel文件操作类
- c#操作 Excel 文件
- Java操作Excel文件
- Sql操作Excel文件
- Excel-VBA文件操作
- java操作excel文件()
- jxl操作excel文件
- c#操作excel文件
- JAVA操作Excel文件
- poi操作excel文件
- poi操作excel文件
- 四大线程池详解
- Python中的staticmethod与classmethod
- 基于Android的“健康宝”体检APP(四)
- JEESZ-Redis分布式缓存安装和使用
- MyEclipse快捷键
- Excel文件操作
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
- Spring Bean 的 scope属性为何要设置为prototype
- Linux进程管理
- HDU---1875 畅通工程再续 最小生成树 (kruskal)
- ios视频循环播放实现
- perl 每次需要输入验证码 登录网站
- BST_常用操作
- 一、android XML资源文件详解 —— 从物理上分析