`
JavaSam
  • 浏览: 951677 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java POI 操作excel 无硬编码,反射,史上最牛

 
阅读更多

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
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.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
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.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi2.hssf.usermodel.HSSFCell;
import org.apache.poi2.hssf.usermodel.HSSFRow;
import org.apache.poi2.hssf.usermodel.HSSFSheet;
import org.apache.poi2.hssf.usermodel.HSSFWorkbook;

/**
 * Excel工具类,没有硬编码,修改时不要添加硬编码代码
 * @author WSF
 *
 */
@SuppressWarnings("unchecked")
public class ExcelUtil {
	
	private ExcelUtil(){};
	private static List<String> columns;//要解析excel中的列名
	private static int sheetNum = 0;//要解析的sheet下标
	private static boolean dynamicColumn = false;//是否
	private static Map<String, String> dynamicMapConfig  = new ListOrderedMap();//動態列配置文件
	/**
	 * poi读取excle
	 * @return
	 */
	public static String readExcel(File file) throws Exception{
		StringBuilder retJson = new StringBuilder();
		InputStream inStream = null;
		try {
			inStream = new FileInputStream(file);
			HSSFWorkbook workbook = new HSSFWorkbook(inStream);
			HSSFSheet sheet = workbook.getSheetAt(sheetNum);//获得表
			int lastRowNum = sheet.getLastRowNum();//最后一行
			retJson.append("[");
			for(int i = 0 ;i < lastRowNum;i++){
				HSSFRow row = sheet.getRow(i+1);//获得行
				String rowJson = readExcelRow(row);
				retJson.append(rowJson);
				if(i<lastRowNum-1)
					retJson.append(",");
			}
			retJson.append("]");
		} catch (Exception e) {
			try {
				inStream = new FileInputStream(file);
				XSSFWorkbook workbook = new XSSFWorkbook(inStream);
				XSSFSheet sheet = workbook.getSheetAt(sheetNum);
				int lastRowNum = sheet.getLastRowNum();//最后一行
				retJson.append("[");
				for(int i = 0 ;i < lastRowNum;i++){
					XSSFRow row = sheet.getRow(i+1);//获得行
					String rowJson = readExcelRow(row);
					retJson.append(rowJson);
					if(i<lastRowNum-1)
						retJson.append(",");
				}
				retJson.append("]");
			} catch (IOException e1) {
				e1.printStackTrace();
				throw e1;
			}
		}finally{
			close(null,inStream);
		}
		return retJson.toString();
	}
	/**
	 * poi读取excle 生成实体集合
	 * @param <E>
	 * @return
	 */
	public static <E> List<E> readExcel(File file,Class<E> clazz) throws Exception{
		if(columns==null){
			setColumns(clazz);
		}
		InputStream inStream = null;
		List<E> eList = new ArrayList<E>();
		try {
			inStream = new FileInputStream(file);
			HSSFWorkbook workbook = new HSSFWorkbook(inStream);
			HSSFSheet sheet = workbook.getSheetAt(sheetNum);//获得表
			int lastRowNum = sheet.getLastRowNum();//最后一行
			if(dynamicColumn){
				//动态列處理
				HSSFRow header = sheet.getRow(0);//表頭
				List<String> rList = readRow(header);
				setDynamicColumn(rList);
			}
			for(int i = 0 ;i < lastRowNum;i++){
				HSSFRow row = sheet.getRow(i+1);//获得行
				String rowJson = readExcelRow(row);
				E _e = json2Bean(rowJson,clazz);
				eList.add(_e);
			}
		} catch (Exception e) {
			try {
				inStream = new FileInputStream(file);
				XSSFWorkbook workbook = new XSSFWorkbook(inStream);
				XSSFSheet sheet = workbook.getSheetAt(sheetNum);
				int lastRowNum = sheet.getLastRowNum();//最后一行
				if(dynamicColumn){
					//动态列處理
					XSSFRow header = sheet.getRow(0);
					List<String> rList = readRow(header);
					setDynamicColumn(rList);
				}
				for(int i = 0 ;i < lastRowNum;i++){
					XSSFRow row = sheet.getRow(i+1);//获得行
					String rowJson = readExcelRow(row);
					E _e = json2Bean(rowJson,clazz);
					eList.add(_e);
				}
			} catch (Exception e1) {
				e1.printStackTrace();
				throw e1;
			}
		}finally{
			close(null,inStream);
		}
		return eList;
	}
	/**
	 * 动态列配置
	 */
	private static void setDynamicColumn(List<String> headlist) throws Exception{
		List<String> tempcolumns = new ArrayList<String>();
		for (Iterator<String> iterator = headlist.iterator();iterator.hasNext();) {
			String value = iterator.next();
			value = value.replace("(", "(");
			value = value.replace(")", ")");
			value = value.trim();
			String key = findKey(value);
			if(key==null){
				throw new RuntimeException("请上传合法excle!");
			}
			tempcolumns.add(findKey(value));
		}
		setColumns(tempcolumns);//重新设置column
	}
	/**
	 * 根据value动态找到key值
	 * @return
	 */
	private static String findKey(String value){
		for(Map.Entry<String,String> entryconfig:dynamicMapConfig.entrySet()){
			String keyc = entryconfig.getKey();
			String valc = entryconfig.getValue();
			if(valc.equals(value)){
				return keyc;
			}
		}
		return null;
	}
	/**
	 * poi读取excle 生成实体集合
	 * @param file
	 * @param clazz
	 * @param exceptscolumns
	 * @return
	 */
	public static <E> List<E> readExcel(File file,Class<E> clazz,String[] exceptscolumns) throws Exception{
		setColumns(clazz,exceptscolumns);
		return readExcel(file, clazz);
	}
	/**
	 * 读取excle多个sheet到多个对象(对象的顺序固定)
	 * @param file
	 * @param clazz
	 * @return
	 */
	public static <E> List<List<E>> readExcel(File file,Class<E>[] clazz) throws Exception{
		List<List<E>>  eliLists = new ArrayList<List<E>>();//[clazz.length];
		int i = 0;
		for(Class<E> cls:clazz){
			setColumns(null,null);
			setSheetNum(i++);
			List<E> eList = readExcel(file, cls);
			eliLists.add(eList);
		}
		return eliLists;
	}
	/**
	 * 将json转换为Bean实例
	 * @param <E>
	 * @return
	 */
	private static <E> E json2Bean(String json,Class<E> clazz) throws Exception{
		JSONObject jsonObj = JSONObject.fromObject(json);
		Method[] methods = clazz.getDeclaredMethods();
		try {
			E _e = clazz.newInstance();
			for(Method m:methods){
				String name = m.getName();
				if(name.startsWith("set")){
					String keyPrev = name.substring(3,4).toLowerCase();
					String keyNext = name.substring(4);
					String val = "";
					try {
						val = jsonObj.getString(keyPrev+keyNext);
					} catch (Exception e) {
						val = "";
					}
					m.invoke(_e, val);
				}
			}
			return _e;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
	/**
	 * 读取行值
	 * @return
	 */
	private static String readExcelRow(HSSFRow row){
		StringBuilder rowJson = new StringBuilder();
		int lastCellNum = ExcelUtil.columns.size();//最后一个单元格
		rowJson.append("{");
		for(int i = 0 ;i<lastCellNum;i++){
			HSSFCell cell = row.getCell(i);
			String cellVal = readCellValue(cell);
			rowJson.append(toJsonItem(columns.get(i), cellVal));
			if(i<lastCellNum-1)
				rowJson.append(",");
		}
		rowJson.append("}");
		return rowJson.toString();
	}
	/**
	 * 读取行值
	 * @return
	 */
	private static String readExcelRow(XSSFRow row){
		StringBuilder rowJson = new StringBuilder();
		int lastCellNum = ExcelUtil.columns.size();//最后一个单元格
		rowJson.append("{");
		for(int i = 0 ;i<lastCellNum;i++){
			XSSFCell cell = row.getCell(i);
			String cellVal = readCellValue(cell);
			rowJson.append(toJsonItem(columns.get(i), cellVal));
			if(i<lastCellNum-1)
				rowJson.append(",");
		}
		rowJson.append("}");
		return rowJson.toString();
	}
	
	/**
	 * 读取行生称list
	 * @return
	 */
	private static List<String> readRow(XSSFRow row){
		List<String> ret = new ArrayList<String>();
		int cellcount = row.getLastCellNum();
		for(int i = 0 ;i < cellcount;i++){
			XSSFCell cell  = row.getCell(i);
			String cellval = readCellValue(cell);
			if(cellval.trim().length()>0){
				ret.add(cellval);
			}
		}
		return ret;
	}
	/**
	 * 读取行生称list
	 * @return
	 */
	private static List<String> readRow(HSSFRow row){
		List<String> ret = new ArrayList<String>();
		int cellcount = row.getLastCellNum();
		for(int i = 0 ;i < cellcount;i++){
			HSSFCell cell  = row.getCell(i);
			String cellval = readCellValue(cell);
			if(cellval.trim().length()>0){
				ret.add(cellval);
			}
		}
		return ret;
	}

	/**
	 * 读取单元格的值
	 * @param hssfCell
	 * @return
	 */
	@SuppressWarnings("static-access")
	private static String readCellValue(HSSFCell hssfCell) {
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			short format = hssfCell.getCellStyle().getDataFormat();
			SimpleDateFormat sdf = null;
			String str_temp = "";
			if(format == 14 || format == 31 || format == 57 || format == 58){
				//日期
				sdf = new SimpleDateFormat("yyyy/MM/dd");
				double value = hssfCell.getNumericCellValue();
				Date date = DateUtil.getJavaDate(value);
				str_temp = sdf.format(date);
			}else if(format == 10) {
				//百分比
				str_temp = hssfCell.getNumericCellValue()+"";
			}else {
				hssfCell.setCellType(1);//设置为String
				str_temp = String.valueOf(hssfCell.getRichStringCellValue());//得到值
			}
			return str_temp;
		}else if(hssfCell.getCellType() == hssfCell.CELL_TYPE_FORMULA){
			int val = hssfCell.getCachedFormulaResultType();
			return val+"";
		} else {
			return String.valueOf(hssfCell.getRichStringCellValue());
		}
	}
	/**
	 * 读取单元格的值
	 * @param hssfCell
	 * @return
	 */
	@SuppressWarnings("static-access")
	private static String readCellValue(XSSFCell sssfCell) {
		if (sssfCell.getCellType() == sssfCell.CELL_TYPE_BOOLEAN) {
			return String.valueOf(sssfCell.getBooleanCellValue());
		} else if (sssfCell.getCellType() == sssfCell.CELL_TYPE_NUMERIC) {
			short format = sssfCell.getCellStyle().getDataFormat();
			SimpleDateFormat sdf = null;
			String str_temp = "";
			if(format == 14 || format == 31 || format == 57 || format == 58){
				//日期
				sdf = new SimpleDateFormat("yyyy/MM/dd");
				double value = sssfCell.getNumericCellValue();
				Date date = DateUtil.getJavaDate(value);
				str_temp = sdf.format(date);
			}else if(format == 10) {
				//百分比
				str_temp = sssfCell.getNumericCellValue()+"";
			}else {
				sssfCell.setCellType(1);//设置为String
				str_temp = String.valueOf(sssfCell.getRichStringCellValue());//得到值
			}
			return str_temp;
		}else if(sssfCell.getCellType() == sssfCell.CELL_TYPE_FORMULA){
			int val = sssfCell.getCachedFormulaResultType();
			return val+"";
		}else {
			return String.valueOf(sssfCell.getRichStringCellValue());
		}
	}
	/**
	 * 转换为json对
	 * @return
	 */
	private static String toJsonItem(String name,String val){
		return "\""+name+"\":\""+val+"\"";
	}
	/**
	 * 关闭io流
	 * @param fos
	 * @param fis
	 */
	private static void close(OutputStream out, InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                System.out.println("InputStream关闭失败");
                e.printStackTrace();
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                System.out.println("OutputStream关闭失败");
                e.printStackTrace();
            }
        }
    }
	/**
	 * 填出数据到excel book中
	 * @param book
	 * @param data
	 * @param sheetname
	 * @param titles
	 * @param columns
	 */
	public static void data2Book(Workbook book,List<? extends Object> data,String sheetname,String[] titles,String[] columns) throws Exception{
		Sheet sheet = book.createSheet(sheetname);
		Row th = sheet.createRow((short)0);//标题行
		for(int i = 0 ;i <titles.length;i++){
			Cell cell = th.createCell(i);
			cell.setCellValue(titles[i]);
		}
		Object _d = data.get(0);
		if(_d instanceof Map){
			//Map集合
			for (int j = 0;j<data.size();j++) {
				Map _dm = (Map)data.get(j);
				Row tr = sheet.createRow((short)(j+1));//内容行
				for(int k = 0 ;k <columns.length;k++){
					Cell cell = tr.createCell(k);
					Object val = _dm.get(columns[k]);
					String value = val==null?"":val.toString();
					cell.setCellValue(value);
				}
				
			}
		}else {
			//Bean集合
			for (int j = 0;j<data.size();j++) {
				Object _do = data.get(j);
				Row tr = sheet.createRow((short)(j+1));//内容行
				for(int k = 0 ;k <columns.length;k++){
					String column = columns[k];
					Method method = getTargetGetMethod(_do, column);//获取目标方法
					try {
						Cell cell = tr.createCell(k);
						Object val = method.invoke(_do);
						String value = val==null?"":val.toString();
						value = value.replace("00:00:00.0","");//处理时间中非法字符
						cell.setCellValue(value);
					} catch (Exception e) {
						e.printStackTrace();
						throw e;
					}
				}
				
			}
		}
	}
	/**
	 * 获取bean的指定getter方法
	 * @param o
	 * @param name
	 * @return
	 */
	private static Method getTargetGetMethod(Object o,String name) throws Exception{
		try {
			String mname  = "get"+name.substring(0,1).toUpperCase()+name.substring(1);
			return o.getClass().getMethod(mname);
		} catch (Exception e) {
			e.printStackTrace();
			throw  e;
		} 
	}
	/**
	 * 将bean所有属性放入map中
	 */
	private static <E> void beanProp2List(Class<E> clazz,List<String> excepts){
		Field[] fields = clazz.getDeclaredFields();
		columns = new ArrayList<String>();//顺序固定可重复
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			String fieldName = field.getName();
			if(excepts!=null&&excepts.contains(fieldName))continue;
			columns.add(fieldName);
		}
	}
	
	public static List<String> getColumns() {
		return ExcelUtil.columns;
	}
	public static void setColumns(List<String> columns) {
		ExcelUtil.columns = columns;
	}
	public static void setColumns(Class<?> clazz){
		beanProp2List(clazz,null);
	}
	/**
	 * 设置列,不包括excepts指定的字段
	 * @param clazz
	 * @param excepts
	 */
	public static void setColumns(Class<?> clazz,String[] excepts){
		beanProp2List(clazz,Arrays.asList(excepts));
	}
	public static int getSheetNum() {
		return sheetNum;
	}
	public static void setSheetNum(int sheetNum) {
		ExcelUtil.sheetNum = sheetNum;
	}
	public static boolean isDynamicColumn() {
		return dynamicColumn;
	}
	public static void setDynamicColumn(boolean dynamicColumn) {
		ExcelUtil.dynamicColumn = dynamicColumn;
	}
	public static Map<String, String> getDynamicMapConfig() {
		return dynamicMapConfig;
	}
	public static void setDynamicMapConfig(Map<String, String> dynamicMapConfig) {
		ExcelUtil.dynamicMapConfig = dynamicMapConfig;
	}
	
}

 

 

分享到:
评论
1 楼 open_sea 2015-09-17  
的确很牛,赞一个

相关推荐

    java_poi实现excel导入导出

    Java POI 实现 Excel 导入导出 Java POI 是一个流行的 Java 库,用于处理 Microsoft Office 文件格式,包括 Excel 文件。在本文中,我们将详细介绍如何使用 Java POI 实现 Excel 导入导出功能。 1. 什么是 Java ...

    Java Poi 操作excel的API 好用

    二、Java POI操作Excel的核心功能 1. 创建新的Excel工作簿 使用`WorkbookFactory.create()`方法可以创建一个新的Excel工作簿对象,然后通过工作簿对象创建工作表。 2. 读取Excel工作簿 同样,使用`WorkbookFactory....

    java poi 操作Excel

    在Java世界中,如果你想对Excel进行读写操作,POI库是不可或缺的工具。下面将详细介绍如何使用Java POI来操作Excel以及相关的知识点。 1. **基本概念** - HSSF(Horrible Spreadsheet Format):这是POI库处理...

    java poi操作excel小例子

    Java POI 操作 Excel 是一个常见的任务,在许多业务场景中都需要用到,比如数据导入导出、数据分析等。Apache POI 是一个流行的开源库,它允许开发者使用 Java 来读写 Microsoft Office 格式的文件,其中包括 Excel ...

    java poi操作excel批量导入导出项目需要的jar包

    Java中的Apache POI库是处理Microsoft Office文档的强大工具,尤其在Excel操作方面。它允许开发者在Java应用程序中创建、修改和读取Excel文件。在进行批量导入和导出Excel数据时,Apache POI是一个非常实用的选择。...

    java poi对于excel的读写与反射的结合使用

    本文将深入探讨如何使用Java POI库来读取和写入Excel数据,并结合反射技术来实现更灵活的功能。 首先,让我们了解Java POI的基本用法。在读取Excel文件时,我们可以使用`XSSFWorkbook`类来处理.xlsx格式的文件,而`...

    java的poi生成excel图表demo

    Java的Apache POI库是一个强大的工具,用于读取、创建和修改Microsoft Office格式的文件,尤其是Excel(.xlsx)文档。在本示例中,我们将深入探讨如何利用POI库来生成Excel中的图表曲线,这对于数据可视化和报告生成...

    java poi导出excel

    Java POI库是Apache软件基金会开发的一个开源项目,专门用于读写Microsoft Office格式的文件,包括Excel。在Java中,如果你需要导出Excel文件,Java POI是一个非常实用的工具。下面将详细介绍如何使用Java POI来实现...

    java 通过poi操作excel jar包

    Java通过Apache POI库操作Excel是Java开发人员处理Microsoft Office文档的一种常见方法,特别是当需要在应用程序中生成、读取或修改Excel数据时。Apache POI是一个开源项目,提供了丰富的API,使得Java开发者能够...

    java使用POI操作excel (支持excel2007)

    Java 使用Apache POI库操作Excel 2007文件详解 在Java开发中,处理Excel文件是一项常见的任务,特别是对于数据分析、数据导入导出或报表生成等场景。Apache POI是一个流行的开源库,它允许开发者读写Microsoft ...

    Java POI 生成Excel时显示货币格式

    对于Excel操作,Java POI提供了HSSF(对应.xls文件)和XSSF(对应.xlsx文件)两个组件,分别用于处理不同版本的Excel文件。 ### 二、显示货币格式 在使用Java POI生成Excel时,为了使数据更易读和专业,我们经常...

    Java Poi 解析EXCEL数据

    在Java世界中,Poi是解析和操作这些文件的首选工具,尤其在数据导入导出、自动化测试、数据分析等领域应用广泛。 Excel文件通常以.XLS或.XLSX格式存在,其中.XLS是早期版本的二进制格式,而.XLSX则是基于Open XML...

    java poi处理excel数据

    Java POI是Apache软件基金会下的一个开源项目,主要用于读写Microsoft Office格式的文件,特别是Excel。在Java开发中,当你需要处理Excel数据时,POI库是一个强大的工具。本压缩包包含了一些关键资源,帮助你理解和...

    JAVA POI Excel转Html

    JAVA POI Excel转Html,代码和所需的jar都在压缩包,项目在线预览需求,实现后分享下

    Java poi 实现excel导入导出

    在提供的“java-excel导入导出”压缩包中,可能包含了示例代码、说明文档以及测试数据,可以帮助初学者快速理解和使用Java POI进行Excel操作。通过学习和实践这些示例,你可以掌握Java POI库的基本用法,并能灵活...

    Java Poi 导出excel(支持各种设置字体、颜色、垂直居中)

    Java Poi 导出excel(支持各种设置字体、颜色、垂直居中)

    JAVA POI导出EXCEL代码

    Java POI库是Apache软件基金会的一个项目,专门用于读写Microsoft Office格式的文件,包括Excel。在Java开发中,我们经常使用POI库来处理Excel数据,如读取、写入和修改Excel文件。本篇文章将详细介绍如何使用JAVA ...

    Java POI 生成Excel(xlsx)文件

    在Java中,如果你需要生成或操作Excel文件,尤其是.xlsx格式(这是Excel 2007及以上版本使用的Open XML格式),那么Apache POI库就是首选工具。下面将详细介绍如何使用Java POI库来生成Excel(xlsx)文件。 首先,...

    JAVA poi 做EXCEL导出(包含图片) 完整版

    在Java编程环境中,Apache POI库是一个非常实用的工具,用于读取、写入和修改Microsoft Office格式的文件,特别是Excel(.xlsx 和 .xls)文件。本教程将详细介绍如何使用JAVA POI库来创建一个包含图片的完整Excel...

    java poi导出图片到excel示例代码

    Java POI导出图片到Excel示例代码详解 Java POI是Java开发中常用的开源库,用于读写Microsoft Office文件格式,包括Excel、Word、PowerPoint等。今天,我们将介绍如何使用Java POI将图片导出到Excel中。 标题解释 ...

Global site tag (gtag.js) - Google Analytics