ExcelUtil

阅读更多

说明:数据库使用mysql,导入的字段类型只能是有varchar,Date 类型

火狐导出文件时做特殊设置,不能用url编码

源代码参考附件:

 

ExcelUtil.java:  导入核心代码

package com.lw.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Excel组件
 * 
 * @author liwei
 * @version 1.0
 * @since 1.0
 */
public class ExcelUtil {

	/**
	 * Excel 2003
	 */
	private final static String XLS = "xls";
	/**
	 * Excel 2007
	 */
	private final static String XLSX = "xlsx";

	
	public static void main(String[] args) {
		String file = "d://importStudentDatas.xls";
		String[] columnArray = new String[]{"code", "name", "birthDate"};
		Map checkColumn = new HashMap();
		checkColumn.put("code", ColumnCheckTypeEnum.CHECK_TYPE_PRICE_1);

		try {
			List list = ExcelUtil.excelToList(new File(file), 0, Student.class, columnArray, checkColumn);
			System.out.println(list.size());
			for (int i = 0; i < list.size(); i++) {
				Student stu = list.get(i);
				System.out.println("编码:" + stu.getCode() + " >>>>> 名称:" + stu.getName() + " >>>>> 生日:" + stu.getBirthDate());
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
	}

	
	/***
	 * 导入Excel数据
	 * 
	 * 
  • 1、读取excel数据
  • *
  • 2、校验数据的合法性(日期,金额,字符长度(和数据库结构比较))
  • *
  • 3、合法数据绑定到bean对象中(反射)
  • *
  • 4、得到数据层面校验通过的bean对象集合,
  • * @param file 导入数据文件 * @param entityClass bean对象类型bean.class * @param sheetIndex sheet索引 * @param columnArray 字段列数组 (需要导入的字段数组) * @param checkColumn 需要校验格式的字段列Map * @throws IOException * @throws NoSuchFieldException * @throws SecurityException * @throws InstantiationException * @throws SQLException * @throws IllegalAccessException * @throws ParseException */ public static List excelToList(File file, Integer sheetIndex, Class entityClass, String[] columnArray, Map checkColumn) throws IOException, SecurityException, NoSuchFieldException, InstantiationException, SQLException, IllegalAccessException, ParseException { List list = new ArrayList(); Workbook workbook = null; if (XLS.equalsIgnoreCase(FilenameUtils.getExtension(file.getName()))) { workbook = new HSSFWorkbook(new FileInputStream(file)); } else if (XLSX.equalsIgnoreCase(FilenameUtils.getExtension(file.getName()))) { workbook = new XSSFWorkbook(new FileInputStream(file)); } else { throw new IOException("导入excel出错,不支持文件类型!"); } if(sheetIndex==null) { sheetIndex = 0; } if((sheetIndex+1)>workbook.getNumberOfSheets()) { throw new IndexOutOfBoundsException("导入excel出错,指定sheet索引越界!"); } // sheet中要导出的列 if(columnArray==null || columnArray.length<1) { throw new NullPointerException("导入excel出错,导入列设置错误!"); } // 拿到sheet Sheet sheet = workbook.getSheetAt(sheetIndex); String sheetName = sheet.getSheetName(); // sheetName 使用表名称 // 解析公式结果 FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); // 每个sheet中的数据 List> dataList = readSheet(sheet, evaluator, columnArray); // 数据库表对应的字段列信息 List columnDatas = null; try { columnDatas = ProDataUtil.getMySqlColumnDatas(sheetName, "scp"); } catch (SQLException e) { throw new SQLException("导入excel出错,获取表信息错误!"); } // 遍历数据库表对应的字段列信息 for(int j=0; j rowData = dataList.get(j); T o = null; try { o = (T) entityClass.newInstance(); } catch (IllegalAccessException e) { throw new IllegalAccessException("导入excel出错,错误信息:" + e.getMessage()); } for(int k=0; k-1 && price.split("\\.")[1].length()>2) { throw new InputMismatchException(errMsg + "此列为金额数值列,小数点后不超过2位小数,请检查excel数据是否合格!"); } } catch (NumberFormatException e) { throw new NumberFormatException(errMsg + "此列为金额数值列,请检查excel数据是否合格!"); } } // 价格类型校验,取4位小数 else if(ColumnCheckTypeEnum.CHECK_TYPE_PRICE_1.equals(checkType)) { try { String price = value.toString(); new BigDecimal(price); if(price.indexOf(".")>-1 && price.split("\\.")[1].length()>4) { throw new InputMismatchException(errMsg + "此列为金额数值列,小数点后不超过4位小数,请检查excel数据是否合格!"); } } catch (NumberFormatException e) { throw new NumberFormatException(errMsg + "此列为金额数值列,请检查excel数据是否合格!"); } } // 2、自定义校验完成后,进行常规校验 // 通过属性名称获取属性,把值设置到属性里面 Field field = entityClass.getDeclaredField(cd.getColumnLowName()); field.setAccessible(true); // 设置属性可访问, private if("java.lang.String".equalsIgnoreCase(cd.getJavaType())) { if(value.toString().length()>Integer.parseInt(cd.getDataMaxLength())) { throw new SQLException(errMsg + "字符长度超过数据库设置长度限制!数据库长度【"+cd.getDataMaxLength()+"】,当前文本长度【"+value.toString().length()+"】"); } try { field.set(o, value.toString()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(errMsg + e.getMessage()); } catch (IllegalAccessException e) { throw new IllegalAccessException(errMsg + e.getMessage()); } } else if("java.util.Date".equalsIgnoreCase(cd.getJavaType())) { try { field.set(o, (Date)value); } catch (ClassCastException e) { throw new ClassCastException(errMsg + "数据格式错误,无法将【"+value+"】转换为java.util.Date类型日期格式。" + e.getMessage()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(errMsg + e.getMessage()); } catch (IllegalAccessException e) { throw new IllegalAccessException(errMsg + e.getMessage()); } } else if("java.lang.Integer".equalsIgnoreCase(cd.getJavaType())) { try { // field.setInt(o, Integer.parseInt(value.toString())); // Int to Integer 赋值时类型不匹配 field.set(o, Integer.parseInt(value.toString())); } catch (NumberFormatException e) { throw new NumberFormatException(errMsg + "数据格式错误,无法将【"+value+"】转换为java.lang.Integer类型。" + e.getMessage()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(errMsg + e.getMessage()); } catch (IllegalAccessException e) { throw new IllegalAccessException(errMsg + e.getMessage()); } } } list.add(o); } return list; } /*** * 读取单个sheet *

    导入Excel数据使用私有方法

    * @param sheet 单个sheet * @param evaluator 解析公式结果 * @param columnArray 字段列数组 */ private static List> readSheet(Sheet sheet, FormulaEvaluator evaluator, String... columnArray) { List> list = new ArrayList>(); int firstRowNum = sheet.getFirstRowNum(); int lastRowNum = sheet.getLastRowNum(); // 从第二行开始读取数据 for (int rowIndex = firstRowNum + 1; rowIndex <= lastRowNum; rowIndex++) { Row row = sheet.getRow(rowIndex); short firstCellNum = row.getFirstCellNum(); // short maxColIx = row.getLastCellNum(); Map rowMap = new HashMap(); // 读取列的时候,按照设置好的字段列的数量长度循环读取 for (short colIndex = firstCellNum; colIndex < columnArray.length; colIndex++) { Cell cell = row.getCell(new Integer(colIndex)+1); // 从第二列开始导入, 第一列序号列不做导入 CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { continue; } // 经过公式解析,最后只存在Boolean、Numeric和String三种数据类型,此外就是Error了 // 其余数据类型,根据官方文档,完全可以忽略http://poi.apache.org/spreadsheet/eval.html switch (cellValue.getCellType()) { case Cell.CELL_TYPE_BOOLEAN: rowMap.put(columnArray[colIndex], cellValue.getBooleanValue()); break; case Cell.CELL_TYPE_NUMERIC: // 这里的日期类型会被转换为数字类型,需要判别后区分处理 if (HSSFDateUtil.isCellDateFormatted(cell)) { rowMap.put(columnArray[colIndex], cell.getDateCellValue()); } else { rowMap.put(columnArray[colIndex], cellValue.getNumberValue()); } break; case Cell.CELL_TYPE_STRING: rowMap.put(columnArray[colIndex], cellValue.getStringValue()); break; case Cell.CELL_TYPE_FORMULA: break; case Cell.CELL_TYPE_BLANK: break; case Cell.CELL_TYPE_ERROR: break; default: break; } } list.add(rowMap); } return list; } private static int getIndexOfArrayItem(String arrItem, String[] array) { int index = -1; for (int i = 0; i < array.length; i++) { if(array[i].equals(arrItem)) { index = i; break; } } return index; } /*** * 导出Excel数据 * @param sheetName sheet名称 * @param fileName 导出文件名 * @param list 要导出的数据 * @param response * @throws IOException */ public static void exportDatas(String sheetName, String fileName, List> list, HttpServletRequest request, HttpServletResponse response) throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(sheetName); int rowNum = 0; // 设置单元格样式(标题样式) HSSFCellStyle styleTitle = wb.createCellStyle(); styleTitle.setBorderBottom(HSSFCellStyle.BORDER_THIN); styleTitle.setBorderLeft(HSSFCellStyle.BORDER_THIN); styleTitle.setBorderRight(HSSFCellStyle.BORDER_THIN); styleTitle.setBorderTop(HSSFCellStyle.BORDER_THIN); // 对齐方式 styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER); styleTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 字体 HSSFFont font = wb.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); styleTitle.setFont(font); // 设置单元格样式(数据值样式) HSSFCellStyle styleContent = wb.createCellStyle(); styleContent.setBorderBottom(HSSFCellStyle.BORDER_THIN); styleContent.setBorderLeft(HSSFCellStyle.BORDER_THIN); styleContent.setBorderRight(HSSFCellStyle.BORDER_THIN); styleContent.setBorderTop(HSSFCellStyle.BORDER_THIN); styleContent.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 标题行 HSSFRow rowTitle = sheet.createRow(rowNum++); int i = 0; HSSFCell cellH0 = rowTitle.createCell(i++); cellH0.setCellValue("序号"); cellH0.setCellStyle(styleTitle); for(Map.Entry tmp : list.get(0).entrySet()) { HSSFCell cellH = rowTitle.createCell(i++); cellH.setCellValue(tmp.getKey()); cellH.setCellStyle(styleTitle); } int cellOrder = 1; for (Map map : list) { HSSFRow row = sheet.createRow(rowNum++); int j = 0; // 序号 HSSFCell cellC0 = row.createCell(j++); cellC0.setCellValue(cellOrder++); cellC0.setCellStyle(styleContent); for(Map.Entry entry : map.entrySet()) { HSSFCell cellC = row.createCell(j++); sheet.setColumnWidth(cellC.getColumnIndex(), 256 * (11 + 10)); cellC.setCellValue(entry.getValue()+""); cellC.setCellStyle(styleContent); } } String agent = request.getHeader("User-Agent"); // 火狐浏览器导出文件不会url解码 if(StringUtil.isEmpty(agent)==false && agent.toLowerCase().indexOf("firefox")>-1) { response.setHeader("Content-disposition", "attachment;filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1")+".xls\""); } else { response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName+".xls", "UTF-8")); } response.setContentType("application/vnd.ms-excel;charset=UTF-8"); OutputStream out = response.getOutputStream(); wb.write(out); out.flush(); out.close(); } }

     

    ProDataUtil.java  获取数据库表信息

    package com.lw.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ProDataUtil {
    
    	private static String url = "jdbc:mysql://192.168.1.1:3306/dbName?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";
    	private static String username = "root";
    	private static String password = "root";
    	private static String driverClassName = "com.mysql.jdbc.Driver";
    
    	/**
    	 * 查询表的字段,封装成List
    	 * 
    	 * @param tableName 表名
    	 * @param schemaName 数据库名
    	 * @return
    	 * @throws SQLException
    	 */
    	public static List getMySqlColumnDatas(String tableName, String schemaName) throws SQLException {
    		String SQLColumns = " select COLUMN_NAME,DATA_TYPE,column_comment,numeric_scale,numeric_precision,character_maximum_length,ordinal_position from information_schema.COLUMNS where table_name =  '" + tableName + "'" + " and TABLE_SCHEMA='" + schemaName + "' " + " ORDER by  ordinal_position";
    		Connection con = getConnection();
    		PreparedStatement ps = con.prepareStatement(SQLColumns);
    		List columnList = new ArrayList();
    		ResultSet rs = ps.executeQuery();
    		while (rs.next()) {
    			String name = rs.getString(1);
    			String lowName = getColumnBeanName(name); // 将XXX_XXX转换成xxxXxx的格式
    			String type = rs.getString(2).toUpperCase(); // mysql 区分大小写
    			String javaType = getType(rs.getString(2), rs.getString(4), rs.getString(5)); // mysql 区分大小写
    			String comment = rs.getString(3);
    			String dataScale = rs.getString(4);
    			String dataPrecision = rs.getString(5);
    			String dataMaxLength = rs.getString(6);
    			
    			ColumnData cd = new ColumnData(name, lowName, type, javaType, comment, dataScale, dataPrecision, dataMaxLength);
    			columnList.add(cd);
    		}
    		rs.close();
    		ps.close();
    		con.close();
    		return columnList;
    	}
    
    	public static Connection getConnection() throws SQLException {
    		try{
    			Class.forName(driverClassName);
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		return DriverManager.getConnection(url, username, password);
    	}
    
    	private static String getColumnBeanName(String column) {
    		String[] split = column.split("_");
    		StringBuffer columnVal = new StringBuffer();
    		if (split.length > 1) {
    			for (int i = 0; i < split.length; i++) {
    				String colVal = "";
    				if (i == 0) {
    					colVal = split[i].toLowerCase();
    					columnVal.append(colVal);
    				} else {
    					colVal = split[i].substring(0, 1).toUpperCase() + split[i].substring(1, split[i].length()).toLowerCase();
    					columnVal.append(colVal);
    				}
    			}
    			columnVal.toString();
    		} else {
    			String colVal = column.toLowerCase();
    			columnVal.append(colVal);
    		}
    		return columnVal.toString();
    	}
    
    	/***
    	 * 获取java类型
    	 * @param type 数据库数据类型
    	 * @param dataScale 小数位数
    	 * @param dataPrecision 数据精度
    	 * @return
    	 */
        private static String getType(String type, String dataScale, String dataPrecision){
        	type=type.toLowerCase();
        	if("char".equalsIgnoreCase(type) || "varchar".equalsIgnoreCase(type)|| "varchar2".equalsIgnoreCase(type)){
    			return "java.lang.String";
    		}else if("NUMBER".equalsIgnoreCase(type)|| "numeric".equalsIgnoreCase(type)){//
    			if((dataScale!=null&&!dataScale.equals("")&&!dataScale.equals("0"))){
    				if(dataPrecision!=null&&dataPrecision.equals("38")){
    					return "java.math.BigDecimal";
    				}else{
    					return "java.lang.Double";
    				}
    			}else {
    				if(dataPrecision!=null&&dataPrecision.equals("38")){
    					return "java.math.BigDecimal";
    				}else{
    					return "java.lang.Long";
    				}
    			}
    		}else if("decimal".equalsIgnoreCase(type)){//
    			return "java.math.BigDecimal";
    		}else if( "DATE".equalsIgnoreCase(type)){
    			return "java.util.Date";
    		}else if( "DATETIME".equalsIgnoreCase(type)){
    			return "java.util.Date";
    		}else if( "BLOB".equalsIgnoreCase(type)){
    			return "java.sql.Blob";
    		}else if( "CLOB".equalsIgnoreCase(type)){
    			return "java.sql.Clob";
    		}else if("int".equalsIgnoreCase(type)){
    			return "java.lang.Integer";
    		}else if("TINYINT".equalsIgnoreCase(type)){
    			return "java.lang.Boolean";
    		}else if("double".equalsIgnoreCase(type)){
    			return "java.math.BigDecimal";
    		}else if("datetime".equalsIgnoreCase(type)){
    			return "java.util.Date";
    		}
        	return null;
        }
    
    	
    }
    

      

     

    • ExcelUtil.rar (8 MB)
    • 下载次数: 12

    你可能感兴趣的:(excel,import,export)