您的位置:首页 > 编程语言 > Java开发

关于excel表格的导入导出(java)

2018-01-31 14:28 561 查看
第一次写,不知道分享什么,思来想去,觉得分享一个小工具吧。

---------------------------------------------------------我是分隔符----------------------------------------------



import
java.io.InputStream;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Date;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

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

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

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

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

public class ExeclUtil {

static int sheetsize = 5000;

/**

* @author Lyy

* @param data 导入到excel中的数据

* @param out 数据写入的文件

* @param fields 字段名字/ 需要注意的是这个方法中的map中:英文为键,中文名名为值

* @throws Exception

*/

public static <T> void ListtoExecl(List<T> data,
OutputStream out,

Map<String, String> fields)
throws Exception {

HSSFWorkbook workbook = new HSSFWorkbook();

// 如果导入数据为空,则抛出异常。

if (data == null || data.size() == 0) {

workbook.close();

throw new Exception("导入的数据为空");

}

// 根据data计算有多少页sheet

int pages = data.size() / sheetsize;

if (data.size() % sheetsize > 0) {

pages += 1;

}

// 提取表格的字段名(英文字段名是为了对照中文字段名的)

String[] egtitles = new String[fields.size()];

String[] cntitles = new String[fields.size()];

Iterator<String> it = fields.keySet().iterator();

int count = 0;

while (it.hasNext()) {

String egtitle = (String) it.next();

String cntitle = fields.get(egtitle);

egtitles[count] = egtitle;

cntitles[count] = cntitle;

count++;

}

// 添加数据

for (int i = 0; i < pages; i++) {

int rownum = 0;

// 计算每页的起始数据和结束数据

int startIndex = i * sheetsize;

int endIndex = (i + 1) * sheetsize - 1 > data.size() ? data.size()

: (i + 1) * sheetsize - 1;

// 创建每页,并创建第一行

HSSFSheet sheet = workbook.createSheet();

HSSFRow row = sheet.createRow(rownum);

// 在每页sheet的第一行中,添加字段名

for (int f = 0; f < cntitles.length; f++) {

HSSFCell cell = row.createCell(f);

cell.setCellValue(cntitles[f]);

}

rownum++;

// 将数据添加进表格

for (int j = startIndex; j < endIndex; j++) {

row = sheet.createRow(rownum);

T item = data.get(j);

for (int h = 0; h < cntitles.length; h++) {

Field fd = item.getClass().getDeclaredField(egtitles[h]);

fd.setAccessible(true);

Object o = fd.get(item);

String value = o == null ? "" : o.toString();

HSSFCell cell = row.createCell(h);

cell.setCellValue(value);

}

rownum++;

}

}

// 将创建好的数据写入输出流

workbook.write(out);

// 关闭workbook

workbook.close();<
4000
br>
}



[b]
/**

* @author Lyy

* @param [b]entityClass

excel中每一行数据的实体类

* @param in
excel读入的文件

* @param fields 字段名字

* 需要注意的是这个方法中的map中:excel表格中每一列名为键,每一列对应的实体类的英文名为值

* @throws Exception

*/[/b]

public static <T> List<T> ExecltoList(InputStream
in, Class<T> entityClass,

Map<String, String> fields)
throws Exception {

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

HSSFWorkbook workbook = new HSSFWorkbook(in);

// excel中字段的中英文名字数组

String[] egtitles = new String[fields.size()];

String[] cntitles = new String[fields.size()];

Iterator<String> it = fields.keySet().iterator();

int count = 0;

while (it.hasNext()) {

String cntitle = (String) it.next();

String egtitle = fields.get(cntitle);

egtitles[count] = egtitle;

cntitles[count] = cntitle;

count++;

}

// 得到excel中sheet总数

int sheetcount = workbook.getNumberOfSheets();

if (sheetcount == 0) {

workbook.close();

throw new Exception("Excel文件中没有任何数据");

}

// 数据的导出

for (int i = 0; i < sheetcount; i++) {

HSSFSheet sheet = workbook.getSheetAt(i);

if (sheet == null) {

continue;

}

// 每页中的第一行为标题行,对标题行的特殊处理

HSSFRow firstRow = sheet.getRow(0);

int celllength = firstRow.getLastCellNum();

String[] excelFieldNames = new String[celllength];

LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();

// 获取Excel中的列名

for (int f = 0; f < celllength; f++) {

HSSFCell cell = firstRow.getCell(f);

excelFieldNames[f] = cell.getStringCellValue().trim();

// 将列名和列号放入Map中,这样通过列名就可以拿到列号

for (int g = 0; g < excelFieldNames.length; g++) {

colMap.put(excelFieldNames[g], g);

}

}

// 由于数组是根据长度创建的,所以值是空值,这里对列名map做了去空键的处理

colMap.remove(null);

// 判断需要的字段在Excel中是否都存在

// 需要注意的是这个方法中的map中:中文名为键,英文名为值

boolean isExist = true;

List<String> excelFieldList = Arrays.asList(excelFieldNames);

for (String cnName : fields.keySet()) {

if (!excelFieldList.contains(cnName)) {

isExist = false;

break;

}

}

// 如果有列名不存在,则抛出异常,提示错误

if (!isExist) {

workbook.close();

throw new Exception("Excel中缺少必要的字段,或字段名称有误");

}

// 将sheet转换为list

for (int j = 1; j <= sheet.getLastRowNum(); j++) {

HSSFRow row = sheet.getRow(j);

// 根据泛型创建实体类

T entity = entityClass.newInstance();

// 给对象中的字段赋值

for (Entry<String, String> entry : fields.entrySet()) {

// 获取中文字段名

String cnNormalName = entry.getKey();

// 获取英文字段名

String enNormalName = entry.getValue();

// 根据中文字段名获取列号

int col = colMap.get(cnNormalName);

// 获取当前单元格中的内容

String content = row.getCell(col).toString().trim();

// 给对象赋值

setFieldValueByName(enNormalName, content, entity);

}

resultList.add(entity);

}

}

workbook.close();

return resultList;

}

/**

* @MethodName : setFieldValueByName

* @Description : 根据字段名给对象的字段赋值

* @param fieldName

* 字段名

* @param fieldValue

* 字段值

* @param o

* 对象

*/

private 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)) {

field.set(o, Integer.parseInt(fieldValue.toString()));

} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {

field.set(o, Long.valueOf(fieldValue.toString()));

} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {

field.set(o, Float.valueOf(fieldValue.toString()));

} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {

field.set(o, Short.valueOf(fieldValue.toString()));

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

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

field.set(o, Double.valueOf(fieldValue.toString()));

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

if ((fieldValue != null)

&& (fieldValue.toString().length() > 0)) {

field.set(o,

Character.valueOf(fieldValue.toString().charAt(0)));

}

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

field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

.parse(fieldValue.toString()));

} else {

a5cb
field.set(o, fieldValue);

}

} else {

throw new Exception(o.getClass().getSimpleName() + "类不存在字段名 "

+ fieldName);

}

}

/**

* @MethodName : getFieldByName

* @Description : 根据字段名获取字段

* @param fieldName

* 字段名

* @param clazz

* 包含该字段的类

* @return 字段

*/

private 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;

}

}

[/b]

------------------------------------------我是分隔符----------------------------------------------------------------------

下面是这个工具包的使用:








以下是代码:

public String test(HttpServletRequest req, Student stu1) throws Exception {

List<Student> li = new ArrayList<Student>();

li.add(stu1);

OutputStream out = new FileOutputStream("d://aa.xls");

Map<String, String> fields = new HashMap<String, String>();

fields.put("uid", "学号");

fields.put("uname", "姓名");

fields.put("sex", "性别");

fields.put("nation", "民族");

ExeclUtil.ListtoExecl(li, out, fields);

out.close();

return "index";

}

public String test1(ModelMap mm) throws Exception {

InputStream in = new FileInputStream("d://aa.xls");

Map<String, String> fieldd = new HashMap<String, String>();

fieldd.put("学号", "uid");

fieldd.put("姓名", "uname");

fieldd.put("性别", "sex");

fieldd.put("民族", "nation");

List<Student> resultList = new ArrayList<Student>();

resultList = ExeclUtil.ExecltoList(in, Student.class, fieldd);

mm.put("lists", resultList);

return "index";

}



[b]
[b]------------------------------------------我是分隔符----------------------------------------------------------------------
[/b]

[/b]

第一次写 还是希望多多提意见。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: