注解动态导出excel

无事,正好有点想法,就顺手组装了一个动态导出excel的组件

主要是利用阿帕奇的poi组件。

在需要导出到excel的实体类型对象上加入自定义注解。

注解类源码:

 
package com.gome.meidian.annotation;

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

/**
 * @ClassName: ColumnTitle
 * @Description: 导出时对vo每个字段列名的标识 无注解的字段不导出
 * @author li
 * @date 2018年1月15日 上午10:28:08
 */

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelColumn {

	/**
	 * @Title: title
	 * @return
	 * @Description: 表头列名 必填
	 */
	public String title();

	/**
	 * @Title: width
	 * @return
	 * @Description: 列宽 默认15
	 */
	public short width() default 15;

	public enum Alignment {
		LEFT(0x1), CENTER(0x2), RIGHT(0x3);
		private int value;

		private Alignment(int value) {
			this.value = value;
		}
		public int getValue() {
			return value;
		}
	};

	/**
	 * @Title: alignment
	 * @return
	 * @Description: 文字样式 默认居中(Alignment.CENTER)
	 */
	public Alignment alignment() default Alignment.CENTER;

	/**
	 * @Title: boder
	 * @return
	 * @Description: 单元格是否需要边框 环绕包围 默认false
	 */
	public boolean boder() default false;

	public enum StyleColor {
		WHITE(0x9), BLACK(0x8), BLUE(0xc), RED(0xa), YELLOW(0xd);
		private int value;

		private StyleColor(int value) {
			this.value = value;
		}
		public int getValue() {
			return value;
		}
	};

	/**
	 * @Title: styleColor
	 * @return
	 * @Description: 单元格背景色 默认白色
	 */
	public StyleColor styleColor() default StyleColor.WHITE;

	public enum FontColor {
		BLACK(0x8), BLUE(0xc), RED(0xa), YELLOW(0xd);
		private int value;

		private FontColor(int value) {
			this.value = value;
		}
		public int getValue() {
			return value;
		}
	};

	/**
	 * @Title: fontColor
	 * @return
	 * @Description: 文字颜色 默认黑色(FontColor.BLACK) 暂支持 BLACK BLUE RED YELLO
	 */
	public FontColor fontColor() default FontColor.BLACK;

	/**
	 * @Title: fontSize
	 * @return
	 * @Description: 字号大小 默认12
	 */
	public short fontSize() default 12;

	/**
	 * @Title: fontName
	 * @return
	 * @Description: 字体 默认微软雅黑
	 */
	public String fontName() default "微软雅黑";

}

 

实体类除了表头必填,还实现了 列宽 单元格背景色 环绕边框 字体位置 字体 字号 颜色 等可以动态配置。

 

导出工具类:反射获取泛型类,接受注解值,动态导出。

接收参数为map<String,Collection<T>> ,一个key对应一个sheet页面 实现多sheet输出。

源码:

 
package com.gome.meidian.tool;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.hssf.util.HSSFColor;
import org.springframework.stereotype.Component;

import com.gome.meidian.annotation.ExcelColumn;
import com.gome.meidian.annotation.ExcelColumn.Alignment;

/**
 * @ClassName: ExcelUtil
 * @Description: 导出excel通用工具类 
 * @author li
 * @date 2018年4月3日 下午5:48:37
 * @param <T>
 */
@Component
public class ExcelUtil<T> {

	/**
	 * @Title: exportExcel
	 * @param dataMap
	 *            map key为sheet value为sheet内的数据集合
	 * @param out
	 * @throws IOException
	 * @Description: 使用默认字体导出excel
	 */
	public void exportExcel(Map<String, Collection<T>> dataMap, OutputStream out) throws IOException {
		HSSFWorkbook workbook = new HSSFWorkbook();
		for (String sheetName : dataMap.keySet()) {
			HSSFSheet sheet = workbook.createSheet(sheetName);
			creatSheet(workbook, sheet, dataMap.get(sheetName));
		}
		try {
			workbook.write(out);
			// 自行处理out 例:out.flush(); out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @Title: creatSheet
	 * @param workbook
	 * @param sheet
	 * @param dataSet
	 *            单页的数据集合
	 * @param fontName
	 *            全局字体设置
	 * @throws IOException
	 * @Description: 创建页数单位
	 */
	private void creatSheet(HSSFWorkbook workbook, HSSFSheet sheet, Collection<T> dataSet)
			throws IOException {
		if (null == dataSet || dataSet.size() == 0) {
			return;
		}
		// 列名集合
		List<String> headers = new ArrayList<String>();
		// 列宽
		List<Short> columnWidth = new ArrayList<Short>();
		// 内文样式位置
		List<Integer> alignList = new ArrayList<Integer>();
		// 是否需要边框
		List<Boolean> boderList = new ArrayList<Boolean>();
		// 字体颜色集合
		List<Integer> fontColorList = new ArrayList<Integer>();
		// 字体集合
		List<String> fontNameList = new ArrayList<String>();
		// 字号集合
		List<Short> fontSizeList = new ArrayList<Short>();
		// 单元格背景色
		List<Integer> styleColorList = new ArrayList<Integer>();
		
		//存放有注解的字段  也就是需要导出的字段  无注解字段排除
		Field[] excelFileds = new Field[] {};
		T t = (T) dataSet.toArray()[0];
		Annotation annotation = null;
		Field[] fields = t.getClass().getDeclaredFields();int j=0;
		for (short i = 0; i < fields.length; i++) {
			Field field = fields[i];
			annotation = field.getAnnotation(ExcelColumn.class);
			if (null == annotation) {
				continue;
			} else {
				excelFileds[j] = field;
				ExcelColumn excelColumn = (ExcelColumn) annotation;
				headers.add(excelColumn.title());
				columnWidth.add(excelColumn.width());
				alignList.add(excelColumn.alignment().getValue());
				boderList.add(excelColumn.boder());
				fontColorList.add(excelColumn.fontColor().getValue());
				fontNameList.add(excelColumn.fontName());
				fontSizeList.add(excelColumn.fontSize());
				styleColorList.add(excelColumn.styleColor().getValue());j++;
			}
		}
		// 循环设置列宽
		for (int i = 0; i < columnWidth.size(); i++) {
			sheet.setColumnWidth(i, columnWidth.get(i) * 256);
		}
		// 产生表格标题行
		HSSFRow row = sheet.createRow(0);
		for (int i = 0; i < headers.size(); i++) {
			HSSFCell cell = row.createCell(i);
			setCellStyle(workbook, cell, alignList.get(i), boderList.get(i),styleColorList.get(i), fontColorList.get(i),  fontNameList.get(i),fontSizeList.get(i),true);
			HSSFRichTextString text = new HSSFRichTextString(headers.get(i));
			cell.setCellValue(text);
		}
		// 遍历集合数据,产生数据行
		Iterator<T> it = dataSet.iterator();
		int index = 0;
		while (it.hasNext()) {
			index++;
			row = sheet.createRow(index);
			t = (T) it.next();
			// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
			for (int i = 0; i < excelFileds.length; i++) {
				HSSFCell cell = row.createCell(i);
				setCellStyle(workbook, cell, alignList.get(i), boderList.get(i),styleColorList.get(i), fontColorList.get(i),  fontNameList.get(i),fontSizeList.get(i),false);
				String fieldName = excelFileds[i].getName();
				String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
				try {
					Method getMethod = t.getClass().getMethod(getMethodName, new Class[] {});
					Object value = getMethod.invoke(t, new Object[] {});
					String textValue = value.toString();
					if (textValue != null) {
						HSSFRichTextString richString = new HSSFRichTextString(textValue);
						cell.setCellValue(richString);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}


	/** 
	 * @Title: setCellStyle 
	 * @param workbook
	 * @param cell       要配置的单元格
	 * @param alignment  单元格内文样式 
	 * @param needBoder  否需要环绕边框
	 * @param sytleColor 单元格背景色
	 * @param fontColor  文字颜色
	 * @param fontName   字体
	 * @param fontSize   字号
	 * @param isBold     表头是否加粗
	 * @Description: 设置单元格以及字体的整体样式 
	 */ 
	private void setCellStyle(HSSFWorkbook workbook, HSSFCell cell, int alignment, Boolean needBoder, int sytleColor,int fontColor,
			 String fontName,short fontSize,boolean isBold) {
		// 生成一个通用样式 默认背景为白色
		HSSFCellStyle style = workbook.createCellStyle();
		style.setFillForegroundColor((short)sytleColor);
		// 单元格内容样式
		style.setAlignment((short) alignment);
		// 单元格是否需要边框
		if (needBoder) {
			style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
			style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
			style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
			style.setBorderRight(HSSFCellStyle.BORDER_THIN);
			style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		}
		// 生成一个字体 默认字体微软雅黑
		HSSFFont font = workbook.createFont();
		font.setFontName(fontName);
		font.setColor((short) fontColor);
		// 设置字体大小
		font.setFontHeightInPoints(fontSize);
		// 字体是否加粗
		if (isBold) {
			font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		}
		// 把字体应用到当前的样式
		style.setFont(font);
		cell.setCellStyle(style);
	}
}

 

 

 

自己实现下载流的设置 关闭 。

 

public static void setRepensehead(HttpServletRequest request, HttpServletResponse response, String filename)
			throws Exception {
		String agent = request.getHeader("USER-AGENT").toLowerCase();
		response.setContentType("application/vnd.ms-excel");
		if (agent.contains("firefox")) {
			response.setCharacterEncoding("utf-8");
			response.setHeader("content-disposition",
					"attachment;filename=" + new String(filename.getBytes(), "ISO8859-1") + ".xls");
		} else {
			response.setHeader("content-disposition", "attachment;filename=" + filename + ".xls");
		}
	}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值