java的excel导出[poi]

Excel生成的主要的类

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
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.ss.util.CellRangeAddress;

import com.hnair.callcenter.common.StringUtil;

/**
 * 创建Excel
 * 
 * @author [email protected]
 * 
 */
@SuppressWarnings("all")
public class CreateExcel {

	private static CreateExcel ce = new CreateExcel();
	private HSSFWorkbook wb = null;
	private Sheet sheet = null;

	public final static String DATA_START = "data";
	/* 初始化列数 */
	private int initColIndex;
	/* 初始化行数 */
	private int initRowIndex;
	/* 当前列数 */
	private int curColIndex;
	/* 当前行数 */
	private int curRowIndex;
	/* 最后一行的数据 */
	private int lastRowIndex;

	private Row curRow;

	private CellStyle style;

	private CreateExcel() {
	}

	public static CreateExcel getInstance() {
		return ce;
	}

	public CreateExcel initDataNoTemplate() {
		// 没有模板时初始化创建
		wb = new HSSFWorkbook();
		sheet = this.wb.createSheet("sheet1");
		initRowIndex = 0;
		initColIndex = 0;
		initStyle();
		return this;
	}
	
	public CreateExcel initStyle(){
		// 初始化样式
		style = wb.createCellStyle();
		style.setAlignment(CellStyle.ALIGN_CENTER); // 居中
		return this;
	}

	/**
	 * 初始化当前的行列
	 * @return
	 */
	private CreateExcel initConfigDataNoTemplate() {
		curRowIndex  = initRowIndex;
		curColIndex= initColIndex ;
		return this;
	}

	/**
	 * 创建新的行
	 * 
	 * @return
	 */
	private CreateExcel createRow() {
		curColIndex = initColIndex;
		curRow = this.sheet.createRow(curRowIndex);
		curRowIndex++;
		return this;
	}

	/**
	 * 创建表头
	 * 
	 * @param title
	 *            表头内容
	 * @param colSpan
	 *            表头宽度(占据的单元格的列的数量)
	 * @return
	 */
	public CreateExcel createTitle(String title, int colSpan) {
		createRow();
		sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, colSpan));
		// 头部占据2行所以要继续加一行
		curRowIndex++;
		Cell c = curRow.createCell(curColIndex);
		c.setCellValue(title);
		// 重置样式防止出现样式不对
		CellStyle style = wb.createCellStyle();
		// 居中
		style.setAlignment(CellStyle.ALIGN_CENTER);
		Font f = wb.createFont();
		// 字体
		f.setFontHeightInPoints((short) 14);
		style.setFont(f);
		c.setCellStyle(style);
		return this;
	}

	/**
	 * 新建表头
	 * 
	 * @param head
	 *            包含表头字符串的集合
	 * @return
	 */
	public CreateExcel createHead(List<String> head) {
		createRow();
		Cell c = null;
		for (String query : head) {
			c = curRow.createCell(curColIndex);
			curColIndex++;
			this.setCellValue(String.class, query, c);
			c.setCellStyle(style);
		}
		return this;
	}

	/**
	 * 表的内容
	 * 
	 * @param body
	 *            包含行数据的集合
	 * @return
	 */
	public CreateExcel createBody(List<?> body) {
		for (Object t : body) {
			createRow();
			Map<String, ColProperty> indexMap = findBeanProperty(t.getClass());
			Method m = null;
			try {
				for (int i = 0; i < indexMap.size(); i++) {
					Iterator<String> it = indexMap.keySet().iterator();
					while (it.hasNext()) {
						String key = it.next();
						ColProperty value = indexMap.get(key);
						// 从1开始查找字段
						if (value.getIndex() != (i + 1)) {
							continue;
						}
						// 得到get方法
						m = t.getClass().getMethod(
								"get" + StringUtil.toUpperCaseFirstOne(key),
								null);
						Class<?> clazz = value.getType();
						// 反射得到值
						Object oo = m.invoke(t, null);
						
						setCellValue(clazz, oo,createCell());
					}
				}
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}

		}
		return this;
	}
	
	public CreateExcel createBodyCoalition(List<?> body) {
		
		if(null == body||body.size() == 0){
			throw new RuntimeException("表内容不能为空!");
		}
		
		for (Object t : body) {
			curColIndex = 0;
			createRow();
			Method m = null;
			try {
				m = t.getClass().getMethod("getL",null);
				Object oo = m.invoke(t, null);
				List<Object> ol = (List)oo;

				Field fs[] = t.getClass().getDeclaredFields();
				for (Field f : fs) {
					String methodName = f.getName().substring(0, 1).toUpperCase()
							+ f.getName().substring(1);
					if(f.getType() != java.util.List.class){
						m = t.getClass().getDeclaredMethod("get" + methodName);
						Object oper = m.invoke(t,null);
						System.out.println(oper);
						setCellValue(f.getType(), oper, createCell(ol.size()-1, 1));
					}
				}
				for(int i = 0;i<ol.size();i++){
					if(i != 0){
						createRow();
						curColIndex = 3;
					}
					
					Field fields[] = ol.get(i).getClass().getDeclaredFields();
					for (Field field : fields) {
						String methodNameL = field.getName().substring(0, 1).toUpperCase()
								+ field.getName().substring(1);
						m = ol.get(i).getClass().getDeclaredMethod("get" + methodNameL);
						Object value = m.invoke(ol.get(i), null);
						setCellValue(value.getClass(), value, createCell());
					}
					System.out.println("");
				}
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return this;
	}
	
	public CreateExcel createBodyCoalition(Map<String, Map<String, List<List<Object>>>> result) {
		
		if(result == null || result.size() == 0)
			throw new RuntimeException("表内容不能为空!");
		Iterator<String> resultIt = result.keySet().iterator();
		while(resultIt.hasNext()){
			curColIndex = 0;
			createRow();
			String resultKey = resultIt.next();
			Map<String, List<List<Object>>> map = result.get(resultKey);
			setCellValue(String.class, resultKey, createCell(countMapList(map)-1, 1));
			boolean isSecondColFirst = true;
			
			Iterator<String> mapIt = map.keySet().iterator();
			while(mapIt.hasNext()){
				if(!isSecondColFirst){
					createRow();
					curColIndex = 1;
				}
				isSecondColFirst = false;
				String mapKey = mapIt.next();
				List<List<Object>> l = map.get(mapKey);
				setCellValue(String.class, mapKey, createCell(l.size()-1, 1));
				
				for(int i=0;i<l.size();i++){
					if(i!=0){
						createRow();
						curColIndex = 2;
					}
					for(int j=0;j<l.get(i).size();j++){
						setCellValue(String.class, l.get(i).get(j), createCell());
					}
				}
			}
		}
		return this;
	}
	
	private int countMapList(Map<String, List<List<Object>>> map){
		int count = 0;
		Iterator<String> mapIt = map.keySet().iterator();
		while(mapIt.hasNext()){
			count += map.get(mapIt.next()).size();
		}
		return count;
	}

	/**
	 * 创建新内容
	 * 
	 * @param clazz
	 *            单元格内容的类型
	 * @param value
	 *            单元格内容的数据
	 * @return
	 */
	public CreateExcel setCellValue(Class<?> clazz, Object value,Cell c) {
		if(null == value){
			c.setCellValue("");
			return this;
		}
		
		// 根据数据的类型set值
		if (clazz == java.lang.String.class) {
			c.setCellValue(value.toString());
		} else if (clazz == java.lang.Integer.class || clazz == int.class
				|| clazz == java.lang.Double.class || clazz == double.class
				|| clazz == java.lang.Long.class || clazz == long.class
				|| clazz == java.lang.Short.class || clazz == short.class
				|| clazz == java.lang.Float.class || clazz == float.class) {
			c.setCellValue(Double.parseDouble(value.toString()));
		} else if (clazz == java.lang.Boolean.class || clazz == boolean.class) {
			c.setCellValue(Boolean.parseBoolean(value.toString()));
		} else if (clazz == java.util.Date.class) {
			CreationHelper createHelper = wb.getCreationHelper(); 
			if(value.toString().length()>=8&&value.toString().length()<=10)
				this.style.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd"));
			else
				this.style.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd hh:mm:ss"));
			c.setCellValue((Date)value);
		} else {
			throw new RuntimeException("setCellValue:未知的参数类型!");
		}
		c.setCellStyle(this.style);
		initStyle();
		return this;
	}

	/**
	 * 创建新的单元格(合并单元格)
	 * @param rowSpan
	 * 		  跨行数
	 * @param colSpan
	 * 	 	  跨列数
	 * @return
	 */
	public Cell createCell(int rowSpan,int colSpan){
		Cell c = curRow.createCell(curColIndex); 
		sheet.addMergedRegion(new CellRangeAddress(curRowIndex-1, curRowIndex+rowSpan-1, curColIndex, curColIndex+colSpan-1));
		curColIndex+=colSpan;
		c.setCellStyle(style);
		return c;
	} 
	
	/**
	 * 创建新的单元格
	 * @return
	 */
	public Cell createCell(){
		Cell c = curRow.createCell(curColIndex); 
		curColIndex++;
		return c;
	}
	
	/**
	 * 得到实体的带有注解的字段的内容
	 * 
	 * @param class1
	 * @return
	 */
	private Map<String, ColProperty> findBeanProperty(Class<?> clazz) {
		Field fs[] = clazz.getDeclaredFields();
		Map<String, ColProperty> indexMap = new HashMap<String, ColProperty>();
		for (Field f : fs) {
			// 寻找有注解的字段
			TabCol tabCol = f.getAnnotation(TabCol.class);
			if (null == tabCol) {
				continue;
			} else {
				ColProperty colProperty = new ColProperty(f.getType(),
						tabCol.Index(), tabCol.title());
				indexMap.put(f.getName(), colProperty);
			}
		}

		return indexMap;
	}

	/**
	 * 得到表头的集合
	 * @param map
	 * @return
	 */
	private List<String> getHead(Map<String, ColProperty> map) {
		List<String> heads = new ArrayList<String>();
		
		for(int i=0;i<map.size();i++){
			Iterator<String> it = map.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				ColProperty value = map.get(key);
				if(value.getIndex() != (i+1)){
					continue;
				}
				heads.add(value.getTitle());
			}
		}
		return heads;
	}

	/**
	 * 创建统计数据
	 * @param t
	 * 		包含统计数据的实体
	 * @return
	 */
	public CreateExcel createCounts(Object t) {
		createRow();
		Map<String, CountProperty> map = getCountProperty(t.getClass());
		Method m = null;
		for (int i = 0; i < map.size(); i++) {
			Iterator<String> it = map.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				//查找注解字段
				CountProperty countProperty = map.get(key);
				if (countProperty.getIndex() != (i + 1)) {
					continue;
				}
				try {
					m = t.getClass().getMethod(
							"get" + StringUtil.toUpperCaseFirstOne(key), null);
					Class<?> clazz = countProperty.getType();
					Object oo;
					//反射得到值
					oo = m.invoke(t, null);
					if (countProperty.getColSpan() == 1) {
						this.setCellValue(clazz, oo,createCell());
					} else {
						// 根据注解判断是否合并单元格
						if (countProperty.getIsCoalition()) {
							setCellValue(clazz, oo, createCell(0, countProperty.getColSpan()));
						} else {
							setCellValue(clazz, oo,createCell());
							//填充空的单元格
							for (int j = 0; j < countProperty.getColSpan() - 1; j++) {
								setCellValue(String.class, "",createCell());
							}
						}
					}
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}

			}
		}

		return this;
	}

	/**
	 * 处理统计数据的属性,得到值
	 * @param clazz
	 * @return
	 */
	public Map<String, CountProperty> getCountProperty(Class<?> clazz) {
		Field fs[] = clazz.getDeclaredFields();
		Map<String, CountProperty> indexMap = new HashMap<String, CountProperty>();
		for (Field f : fs) {
			// 寻找有注解的字段
			CountData countData = f.getAnnotation(CountData.class);
			if (null == countData) {
				continue;
			} else {
				CountProperty countProperty = new CountProperty(f.getType(),
						countData.index(), countData.colSpan(),
						countData.isCoalition());
				indexMap.put(f.getName(), countProperty);
			}
		}
		return indexMap;
	}

	/**
	 * 生成Excel文件
	 * @param filePath
	 */
	public void writeToFile(String filePath) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(new File(filePath));
			wb.write(fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 返回workbook对象
	 * @return
	 */
	public Workbook getWorkbook() {
		return wb;
	}

	/**
	 * 生成带有统计数据的excel
	 * @param title
	 * 		  表头数据
	 * @param body
	 * 		  表的内容-->带有注解的泛型实体  注解见:com.hnair.callcenter.common.excel.TabCol
	 * @param t
	 * 		统计数据
	 * @return
	 */
	public CreateExcel CreateNewExcelNoTemplate(String title, List<?> body, Object t) {
		if (null == title || "".equals(title)) {
			throw new RuntimeException("表头不能为空!");
		}
		if (null == body || body.size() == 0) {
			throw new RuntimeException("表内容为空!");
		}
		if (null == t) {
			throw new RuntimeException("统计数据为空!");
		}
		initDataNoTemplate();
		initConfigDataNoTemplate();
		List<String> heads = getHead(findBeanProperty(body.get(0).getClass()));
		createTitle(title, heads.size()-1);
		createHead(heads);
		createBody(body);
		createCounts(t);
		return this;
	};

	public CreateExcel CreateNewExcelNoTemplate(String title, List<?> body) {
		if (null == title || "".equals(title)) {
			throw new RuntimeException("表头不能为空!");
		}
		if (null == body || body.size() == 0) {
			throw new RuntimeException("表内容为空!");
		}
		initDataNoTemplate();
		initConfigDataNoTemplate();
		List<String> heads = getHead(findBeanProperty(body.get(0).getClass()));
		createTitle(title, heads.size());
		
		createHead(heads);
		createBody(body);
		return this;
	};

	public CreateExcel CreateNewExcelWithTemplate(String title, List<?> body,
			Object o, String filePath) {
		if (null == title || "".equals(title)) {
			throw new RuntimeException("表头不能为空!");
		}
		if (null == body || body.size() == 0) {
			throw new RuntimeException("表内容为空!");
		}
		if (null == o) {
			throw new RuntimeException("统计数据为空!");
		}
		readTemplate(filePath);
		initConfigData();
		List<String> heads = getHead(findBeanProperty(body.get(0).getClass()));
		createTitle(title, heads.size()-1);
		createHead(heads);
		createBody(body);
		createCounts(o);
		return this;
	}

	public CreateExcel CreateNewExcelWithTemplate(String title, List<?> body,
			String filePath) {
		if (null == title || "".equals(title)) {
			throw new RuntimeException("表头不能为空!");
		}
		if (null == body || body.size() == 0) {
			throw new RuntimeException("表内容为空!");
		}
		readTemplate(filePath);
		initConfigData();
		List<String> heads = getHead(findBeanProperty(body.get(0).getClass()));
		createTitle(title, heads.size()-1);
		createHead(heads);
		createBody(body);
		CreateNewExcelNoTemplate(title, body);
		return this;
	}

	/**
	 * 读取表头模板
	 * 
	 * @param filePath
	 * @return
	 */
	public CreateExcel readTemplate(String filePath) {
		try {
			wb = new HSSFWorkbook(new FileInputStream(new File(filePath)));
			sheet = wb.getSheetAt(0);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("未找到相关模板!");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 查找数据的起始标记
	 */
	@SuppressWarnings("static-access")
	private void initConfigData() {
		boolean findData = false;
		for (Row row : sheet) {
			if (findData)
				break;
			for (Cell cell : row) {
				if (cell.getCellType() != cell.CELL_TYPE_STRING)
					continue;
				String str = cell.getStringCellValue();
				// DATA_START就是默认的起始标记
				if (str.equals(DATA_START)) {
					initColIndex = cell.getColumnIndex();
					initRowIndex = row.getRowNum();
					// 初始化数据
					curColIndex = initColIndex;
					curRowIndex = initRowIndex;
					findData = true;
					break;
				}
			}
		}
	}
}


封装的实体

 

 

public class ColProperty {
	private Class<?> type;
	private Integer index;
	private String title;

	public ColProperty() {
	}

	public ColProperty(Class<?> type, Integer index, String title) {
		this.type = type;
		this.index = index;
		this.title = title;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}

	public Integer getIndex() {
		return index;
	}

	public void setIndex(Integer index) {
		this.index = index;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

}

 

 

 

public class CountProperty {

	private int index;
	private int colSpan;
	private Class<?> type;
	private boolean isCoalition;

	public CountProperty() {
	}

	public CountProperty(Class<?> type, int index, int colSpan, boolean isCoalition) {
		this.type = type;
		this.index = index;
		this.colSpan = colSpan;
		this.isCoalition = isCoalition;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public int getColSpan() {
		return colSpan;
	}

	public void setColSpan(int colSpan) {
		this.colSpan = colSpan;
	}

	public boolean getIsCoalition() {
		return isCoalition;
	}

	public void setIsCoalition(boolean isCoalition) {
		this.isCoalition = isCoalition;
	}
}



 


CountData统计字段的实体注解信息(一般统计有合并单元格的操作)

 

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface CountData {
	int index();
	int colSpan();
	boolean isCoalition();
}


表内容对应的实体注解的信息

 

 

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
/**
 * 表内容对应的实体的信息
 * @author [email protected]
 *
 */
public @interface TabCol {
	/**
	 * 字段在表中列的顺序 1 开始
	 * @return
	 */
	int Index();
	
	/**
	 * 字段在表头
	 * @return
	 */
	String title();
}



 

你可能感兴趣的:(java的excel导出[poi])