用反射、注解、poi实现的excel导出

项目特殊,数据源多种,导致导出sheet页各不相同且列超多(200+),客户变更频繁(开发阶段)。

设计用注解导出,节省开发时间。

涉及到注解的repeatable使用。

package com.hp.portal.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;

import com.hp.portal.util.MyAnnotations.MyColumn;
import com.hp.portal.util.MyAnnotations.MyColumns;
import com.hp.portal.util.MyAnnotations.MySheet;

public class ExcelUtils {

	private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
	private static String DATE_FORMAT = "yyyy-MM-dd";
	private static String NUMBER_MATCHER = "^(-?\\d+)(\\.\\d+)?$";

	public static SXSSFWorkbook getSXSSFWorkbook() {
		return new SXSSFWorkbook(-1);
	}

	@SuppressWarnings("unchecked")
	public static void sheetSort(SXSSFWorkbook wb, Collection categorys) {
		List sheets = new ArrayList();
		for (String category : categorys) {
			sheets.add((MySheet) DocumentUtils.getClazz(category).getAnnotation(MySheet.class));
		}
		if (wb != null && !CollectionUtils.isEmpty(sheets) && wb.getNumberOfSheets() == sheets.size()) {
			Collections.sort(sheets, new Comparator() {
				@Override
				public int compare(MySheet sheet1, MySheet sheet2) {
					return sheet1.order() - sheet2.order();
				}
			});
			for (int i = 0; i < sheets.size(); i++) {
				wb.setSheetOrder(sheets.get(i).value(), i);
			}
			wb.setActiveSheet(0);
		}
	}

	@SuppressWarnings("unchecked")
	public static  void createSheet(SXSSFWorkbook wb, List rows, List column, Pageable page) {
		if (!CollectionUtils.isEmpty(rows)) {
			Class clazz = (Class) rows.get(0).getClass();
			if (clazz.isAnnotationPresent(MySheet.class)) {
				List columns = getColumns(clazz, column);
				String sheetName = StringUtils.isEmpty(clazz.getAnnotation(MySheet.class).value())
						? clazz.getSimpleName() : clazz.getAnnotation(MySheet.class).value();
				Sheet sheet = wb.getSheet(sheetName);
				if (sheet == null) {
					sheet = wb.createSheet(sheetName);
					wb.setSheetOrder(sheetName, clazz.getAnnotation(MySheet.class).order() >= wb.getNumberOfSheets()
							? wb.getNumberOfSheets() - 1 : clazz.getAnnotation(MySheet.class).order());
					createTitle(sheet.createRow(0), columns, clazz);
				}
				fillDatas(sheet, columns, rows, page.getPageNumber() * page.getPageSize() + 1);
			}
		}
	}

	private static  List getColumns(Class clazz, List column) {
		List columns = new ArrayList();
		Field[] fields = clazz.getDeclaredFields();
		Field[] supFields = clazz.getSuperclass().getDeclaredFields();
		if (CollectionUtils.isEmpty(column)) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(MyColumn.class) && field.getAnnotation(MyColumn.class).display()) {
					columns.add(field);
				}
			}
			for (Field field : supFields) {
				MyColumn mc = getMyColumnAnnotation(field, clazz);
				if (mc != null && mc.display()) {
					columns.add(field);
				}
			}
		} else {
			for (Field field : fields) {
				if (field.isAnnotationPresent(MyColumn.class) && column.contains(field.getName())) {
					columns.add(field);
				}
			}
			for (Field field : supFields) {
				MyColumn mc = getMyColumnAnnotation(field, clazz);
				if (mc != null && column.contains(field.getName())) {
					columns.add(field);
				}
			}
		}
		columns.sort(new Comparator() {
			public int compare(Field f1, Field f2) {
				return getOrder(f1) >= getOrder(f2) ? 1 : -1;
			}

			private int getOrder(Field field) {
				int order = 0;
				MyColumn mc = getMyColumnAnnotation(field, clazz);
				if (mc != null) {
					order = mc.order();
				}
				return order;
			}
		});
		return columns;
	}

	private static  void createTitle(Row row, List columns, Class clazz) {
		int i = 0;
		for (Field field : columns) {
			Cell cell = row.createCell(i);
			cell.getSheet().setColumnWidth(i, getMyColumnAnnotation(field, clazz).length() * 256);
			cell.setCellValue(getMyColumnAnnotation(field, clazz).value());
			i++;
		}
	}

	private static  void fillDatas(Sheet sheet, List columns, Collection rows, int startRow) {
		CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
		DataFormat format = sheet.getWorkbook().createDataFormat();
		cellStyle.setDataFormat(format.getFormat(DATE_FORMAT));
		PropertyDescriptor pd;
		try {
			for (T t : rows) {
				Row row = sheet.createRow(startRow);
				int j = 0;
				for (Field field : columns) {
					Cell cell = row.createCell(j);
					pd = new PropertyDescriptor(field.getName(), t.getClass());
					Object o = pd.getReadMethod().invoke(t);
					Class clazz = pd.getPropertyType();
					if (o != null) {
						if (Date.class.equals(clazz)) {
							cell.setCellValue((Date) o);
							cell.setCellStyle(cellStyle);
						} else if (StringUtils.isNotEmpty(String.valueOf(o))) {
							if (String.valueOf(o).matches(NUMBER_MATCHER)) {
								cell.setCellValue(Double.parseDouble(String.valueOf(o)));
							} else {
								cell.setCellValue(String.valueOf(o));
							}
						}
					}
					j++;
				}
				if (startRow % 1000 == 0) {
					((SXSSFSheet) sheet).flushRows(1000);
				}
				startRow++;
			}
		} catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
				| IOException e) {
			logger.debug(e.getMessage());
		}
	}

	private static  MyColumn getMyColumnAnnotation(Field field, Class clazz) {
		MyColumn myColumn = null;
		if (field.isAnnotationPresent(MyColumn.class)) {
			myColumn = field.getAnnotation(MyColumn.class);
			if (StringUtils.isNotEmpty(myColumn.sheetName())
					&& !StringUtils.equals(myColumn.sheetName(), clazz.getSimpleName())) {
				myColumn = null;
			}
		} else if (field.isAnnotationPresent(MyColumns.class)) {
			MyColumn[] mcs = field.getAnnotationsByType(MyColumn.class);
			for (MyColumn mc : mcs) {
				if (StringUtils.equals(mc.sheetName(), clazz.getSimpleName())) {
					myColumn = mc;
					break;
				}
			}
		}
		return myColumn;
	}
}

package com.hp.portal.util;


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


import org.springframework.stereotype.Component;


public class MyAnnotations {
	@Repeatable(MyColumns.class)
	@Target({ ElementType.FIELD })
	@Retention(RetentionPolicy.RUNTIME)
	@Documented
	public @interface MyColumn {
		String value();
		int order();
		boolean display() default true;
		String sheetName() default "";
		int length() default 15;
	}


	@Target({ ElementType.FIELD })
	@Documented
	@Retention(RetentionPolicy.RUNTIME)
	public @interface MyColumns {
		MyColumn[] value();
	}


	@Target({ ElementType.TYPE })
	@Retention(RetentionPolicy.RUNTIME)
	@Documented
	@Component
	public @interface MySheet {
		String value() default "";
		int order();
	}


}

你可能感兴趣的:(java)