灵活的 反射 多sheet 导入导出 Excel 工具类
2018-03-21 11:55
543 查看
<!--excel导入导出start--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.8</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.8</version> </dependency> <!--excel导入导出end-->在pom.xml中引入导入导出Jar包。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* excel导入导出注解类
* Created by zxy on 2017/11/1.
*/
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {
//导入导出字段在excel中的名字
String title();
}
ExcelField注释类
import org.springframework.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyUtils {
//获取格式化的时间,参数都为空则返回当前时间
public static final String getFormatDate(String style, Date date) {
return new SimpleDateFormat(isEmpty(style) ? "yyyy-MM-dd" : style).format(date == null ? new Date() : date);
}
//判断为null或空字符串
public static final boolean isEmpty(String s) {
return StringUtils.isEmpty(s);
}
//URL 编码, Encode默认为UTF-8.
public static final String urlEncode(String s) throws UnsupportedEncodingException {
return URLEncoder.encode(s, "UTF-8");
}
}
MyUtils工具类import com.zxy.whbackstage.common.MyUtils;
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;
import org.apache.poi.ss.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
*
* @Description: excel导出封装类
* @author zxy
* @date 2017年11月1日
*/
public class ExcelUtil
{
//通用
public static <Q> void writeExcel(HttpServletResponse response, String fileName, List<Q> list, Class<Q> cls) throws IOException, IllegalArgumentException, IllegalAccessException
{
HSSFWorkbook wb = new HSSFWorkbook();
Field[] fields = cls.getDeclaredFields();
ArrayList<String> headList = new ArrayList<String>();
for (Field f : fields)
{
ExcelField field = f.getAnnotation(ExcelField.class);
if (field != null)
{
headList.add(field.title());
}
}
CellStyle style = getCellStyle(wb);
List<List<Q>> listTemp = new ArrayList<>();
if(list!=null){
int total = list.size();
int cycelTotal = total / 65000;
int tt = 0;
for (int i = 0; i <= cycelTotal; i++) {
if(((i+1)*65000)>total){
tt = total;
}else{
tt = ((i+1)*65000);
}
listTemp.add(list.subList(i*65000,tt));
}
}
for (int k = 0; k < listTemp.size(); k++) {
Sheet sheet = wb.createSheet();
/**
* 设置Excel表的第一行即表头
*/
Row row = sheet.createRow(0);
for (int i = 0; i < headList.size(); i++)
{
Cell headCell = row.createCell(i);
headCell.setCellType(Cell.CELL_TYPE_STRING);
headCell.setCellStyle(style);//设置表头样式
headCell.setCellValue(String.valueOf(headList.get(i)));
sheet.autoSizeColumn((short) i);// 设置单元格自适应
//sheet.setColumnWidth(0, 15 * 256);
}
if(listTemp.get(k)!=null){
for (int i = 0; i < listTemp.get(k).size(); i++)
{
Row rowdata = sheet.createRow(i + 1);//创建数据行
Q q = listTemp.get(k).get(i);
Field[] ff = q.getClass().getDeclaredFields();
int j = 0;
for (Field f : ff)
{
ExcelField field = f.getAnnotation(ExcelField.class);
if (field == null)
{
continue;
}
f.setAccessible(true);
Object obj = f.get(q);
Cell cell = rowdata.createCell(j);
cell.setCellType(Cell.CELL_TYPE_STRING);
// 当数字时
if (obj instanceof Integer) cell.setCellValue((Integer) obj);
// 当长整形
if (obj instanceof Long) cell.setCellValue((Long) obj);
// 当为字符串时
if (obj instanceof String) cell.setCellValue((String) obj);
// 当为布尔时
if (obj instanceof Boolean) cell.setCellValue((Boolean) obj);
// 当为时间时
if (obj instanceof Date) cell.setCellValue(MyUtils.getFormatDate("yyyy-MM-dd", (Date) obj));
// 当为时间时
if (obj instanceof Calendar) cell.setCellValue((Calendar) obj);
// 当为小数时
if (obj instanceof Double) cell.setCellValue((Double) obj);
//将序号替换为123456
if (j == 0) cell.setCellValue(i + 1);
j++;
}
}
}
}
response.setContentType( "application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=report.zip");
OutputStream ouputStream = null;
try
{
ouputStream = response.getOutputStream();
ZipOutputStream zip = new ZipOutputStream(ouputStream);
ZipEntry entry = new ZipEntry(MyUtils.urlEncode(fileName));
zip.putNextEntry(entry);
wb.write(zip);
zip.flush();
zip.close();
}
finally
{
ouputStream.flush();
ouputStream.close();
}
}
/**
*
* @Description:设置表头样式
* @author zxy
* @date 2017年11月1日
*/
public static CellStyle getCellStyle(Workbook wb)
{
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);//设置字体大小
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//加粗
style.setFillForegroundColor(HSSFColor.LIME.index);// 设置背景色
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setAlignment(HSSFCellStyle.SOLID_FOREGROUND);//让单元格居中
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
style.setWrapText(true);//设置自动换行
style.setFont(font);
return style;
}
}excel导出封装类
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
*
* @Description: excel导入封装类
* @author zxy
* @date 2017年11月28日
*/
@Slf4j
public class ReadExcelUtil {
public static <Q> List<Q> getExcelAsFile(String file,Class<Q> cls) throws FileNotFoundException, IOException, InvalidFormatException {
List<Q> list = new ArrayList<Q>();
Field[] fields = cls.getDeclaredFields();
ArrayList<String> headList = new ArrayList<String>();
InputStream ins = null;
Workbook wb = null;
ins=new FileInputStream(new File(file));
//得到Excel工作簿对象
wb = WorkbookFactory.create(ins);
ins.close();
int sheetNum = wb.getNumberOfSheets();
boolean falg = false;
for (int i = 0; i < sheetNum; i++) {
//得到Excel工作表对象
Sheet sheet = wb.getSheetAt(i);
//总行数
int trLength = sheet.getLastRowNum();
//数据行读取
for (int j = 1; j < trLength+1; j++) {
try {
Q shixin = cls.newInstance();
Row row = sheet.getRow(j);
falg = false;
for (Field f : fields) {
ExcelField field = f.getAnnotation(ExcelField.class);
if (field != null){
//标题行
Row rowt = sheet.getRow(0);
for (int k = 0; k < rowt.getLastCellNum(); k++) {
Cell cellt = rowt.getCell(k);
if(cellt==null){
continue;
}
int cellTypet = cellt.getCellType();
if(cellTypet==1&&cellt.getStringCellValue().equals(field.title())){
falg = true;
if(row==null){
continue;
}
Cell cell = row.getCell(k);
if(cell==null){
falg = false;
break;
}
int cellType = cell.getCellType();
String typeName = f.getGenericType().getTypeName();
//得到单元格类型
switch (cellType){
case 0:
//CELL_TYPE_NUMERIC
f.setAccessible(true);
if("java.lang.String".equals(typeName)){
if(cellType == HSSFCell.CELL_TYPE_NUMERIC){
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
f.set(shixin,cell.toString());
}
}else if("java.lang.Long".equals(typeName)){
if(cellType == HSSFCell.CELL_TYPE_NUMERIC){
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
f.set(shixin,Long.parseLong(cell.toString()));
}
}else if("java.lang.Integer".equals(typeName)){
f.set(shixin,new Double(cell.getNumericCellValue()).intValue());
}else if("java.lang.Double".equals(typeName)){
f.set(shixin,cell.getNumericCellValue());
}
break;
case 1:
//CELL_TYPE_STRING
f.setAccessible(true);
if("java.lang.String".equals(typeName)){
f.set(shixin,cell.getStringCellValue());
}else if("java.lang.Long".equals(typeName)){
if(!"".equals(cell.getStringCellValue().trim())){
f.set(shixin,Long.parseLong(cell.getStringCellValue()));
}else{
falg = false;
}
}else if("java.lang.Integer".equals(typeName)){
if(!"".equals(cell.getStringCellValue().trim())){
f.set(shixin,Integer.parseInt(cell.getStringCellValue()));
}else{
falg = false;
}
}else if("java.lang.Double".equals(typeName)){
if(!"".equals(cell.getStringCellValue().trim())){
f.set(shixin,Double.parseDouble(cell.getStringCellValue()));
}else{
falg = false;
}
}
break;
case 2:
//CELL_TYPE_FORMULA
//cell.getCellFormula();
//System.out.println(cell.getCellFormula());
break;
case 3:
//CELL_TYPE_BLANK
break;
case 4:
//CELL_TYPE_BOOLEAN
f.setAccessible(true);
if("java.lang.Boolean".equals(typeName)){
f.set(shixin,cell.getBooleanCellValue());
}
//cell.getBooleanCellValue();
//System.out.println(cell.getBooleanCellValue());
break;
case 5:
//CELL_TYPE_ERROR
//cell.getErrorCellValue();
//System.out.println(cell.getErrorCellValue());
break;
default:
break;
}
}
}
}
}
if(falg){
list.add(shixin);
}
} catch (InstantiationException e) {
log.info("第"+j+"行出错");
log.info(e.getMessage());
} catch (IllegalAccessException e) {
log.info("第"+j+"行出错");
log.info(e.getMessage());
}
}
}
return list;
}
}execl导入封装类
完成,以上工具类已经可以导入导出了。下面来介绍下用法。
import com.zxy.whbackstage.common.excelUtils.ExcelField;
import lombok.Data;
@Data
public class ExportAdmin {
@ExcelField(title = "序号")
private Integer No;
@ExcelField(title = "登录账号")
private String userName;
@ExcelField(title = "真实姓名")
private String trueName;
@ExcelField(title = "密码")
private String password;
private String gender;
private String mobile;
}注意看ExportAdmin这个类,你要导出哪个字段的数据就在哪个数据上标识@ExcelField(title="序号"),其中title就是对应的导出的excel的列名。
@RequestMapping(value = "/export", method = RequestMethod.GET)
public void exportOrderList(HttpServletResponse response){
List<ExportAdmin> list = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = sdf.format(new Date())+"excel.xls";
try {
ExcelUtil.writeExcel(response, fileName, list, ExportAdmin.class);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}以上就是Controller调用了。list就是从后台数据库读取的ExportAdmin的集合。至此后台导出功能就完成了。下面介绍导入功能。
import com.zxy.whbackstage.common.excelUtils.ExcelField;
import lombok.Data;
@Data
public class InputAdmin {
@ExcelField(title = "序号")
private Integer No;
@ExcelField(title = "登录账号")
private String userName;
@ExcelField(title = "真实姓名")
private String trueName;
@ExcelField(title = "密码")
private String password;
private String gender;
private String mobile;
}注意InputAdmin这个类和ExportAdmin这个类一样的呢?确实一样的,这些实体类按照你的业务需求可以合并成一个实体类。
导入和导出的正好相反,注意@ExcelField中的title,导入的excel列标题头必须和title中的中文或者英文字符相匹配。例如:
这个excel是要导入的数据,只有序号,登录账号,真实姓名,密码这4个@ExcelField标识的列的数据能读取出来,性别和手机会被忽略。
@ResponseBody
@RequestMapping(value = "/saveGoodsOrderFile", method = RequestMethod.POST,consumes = "multipart/form-data")
public String saveGoodsOrderFile(@RequestParam("fileName") MultipartFile file,
HttpServletRequest request) {
// 判断文件是否为空
if (!file.isEmpty()) {
try {
String filePath = request.getSession().getServletContext().getRealPath("/")+"file/temp/"
+ file.getOriginalFilename();
File file2=new File(filePath);
file.transferTo(file2);
List<InputAdmin> list = ReadExcelUtil.getExcelAsFile(filePath,InputAdmin.class);
//this.orderChildService.saveTicketFile(list);
if(file2.exists()){
file2.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "";
}这个就是Controller调用方法,把excel文件中一行数据包装成一个InputAdmin实体类,通过工具类得到InputAdmin的List集合。至此就把excel文件里面的数据读取出来了。
打完收工,在此希望有大神能把我的代码优化一下,或者提供更好的工具类,欢迎斧正。
版权声明:本文为博主原创文章,未经博主允许不得转载。
http://blog.csdn.net/tavatimsa/article/details/79636817
相关文章推荐
- 导入导出Excel的Java工具类ExcelUtil
- JavaWeb中POI导入和导出Excel、Map键值类型转换、时间格式化、对象赋值等常见工具类集锦
- 详讲:C#快速导出多个sheet到excel的两种方法(Cell和Range方法), 解决了(导入时外部表不是预期的格式)
- POI实现excel的导入导出-[采用反射实现的版本]
- 导入导出Excel工具类ExcelUtil
- Java实现Excel导入导出的工具类
- 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续3篇-导出时动态生成多Sheet EXCEL)
- Excel基于POI利用反射返回Bean导入、Excel基于POI导出、Excel利用jxls导出、Excel模板导出
- excel导入导出工具类
- 导入导出Excel的Java工具类ExcelUtil
- Java类型信息与用反射机制编写通用的Excel导入导出
- Java基于注解和反射导入导出Excel(Bean转Excel,Excel转Bean)
- jxl java工具类,导出excel,导入数据库
- 配置简单功能强大的excel工具类搞定excel导入导出工具类(一)
- JAVA工具类(17)--Java导入导出Excel工具类ExcelUtil
- java导出excel,导入excel,导出csv工具类整理
- java poi导出与导入excel 工具类
- Java 实现Excel导入导出(包含一些简单样式设置)工具类
- excel导入导出操作类 利用泛型 反射 导入excel
- 实现一个配置简单功能强大的excel工具类搞定excel导入导出(二)