jxl根据实体类注解导出excel工具类

工具类 

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springrain.busi.annotation.ExcelField;

import jxl.Cell;
import jxl.Sheet;
import jxl.SheetSettings;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.format.VerticalAlignment;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

/**
 * excel操作工具类
 */
public class JxlExcelUtils {

	/**
	 * 根据title导出excel
	 *
	 * @param response
	 * @param columns
	 * @param list
	 * @param filename
	 * @throws Exception
	 */
	public static void exportToExcelByTitles(HttpServletResponse response, List<String> columns
			, List<LinkedHashMap<String, Object>> objData, String filename) throws Exception {
		OutputStream os = null;
		WritableWorkbook wwb = null;
		try {

			// 设置弹出对话框
			response.setContentType("application/vnd.ms-excel");
			// 设置工作表的标题
			response.setHeader("Content-Disposition",
					"attachment;filename=" + new String(filename.getBytes("gb2312"), "ISO8859-1") + ".xls");// 设置生成的文件名字

			// 根据传进来的file对象创建可写入的Excel工作薄
			os = response.getOutputStream();
			wwb = Workbook.createWorkbook(os);

			/*
			 * 创建一个工作表、sheetName为工作表的名称、"0"为第一个工作表
			 * 打开Excel的时候会看到左下角默认有3个sheet、"sheet1、sheet2、sheet3"这样 代码中的"0"就是sheet1、其它的一一对应。
			 * createSheet(sheetName, 0)一个是工作表的名称,另一个是工作表在工作薄中的位置
			 */
			WritableSheet ws = wwb.createSheet(filename, 0);
			ws.setColumnView(1, 30);

			// 单元格设置
			SheetSettings ss = ws.getSettings();
			ss.setVerticalFreeze(1);// 冻结表头
			ss.setDefaultColumnWidth(16);// 给sheet电子版中所有的列设置默认的列的宽度;
			ss.setShowGridLines(true);

			/*
			 * WritableFont.createFont("宋体"):设置字体为宋体 18:设置字体大小
			 * WritableFont.BOLD:设置字体加粗(BOLD:加粗 NO_BOLD:不加粗) false:设置非斜体
			 * UnderlineStyle.NO_UNDERLINE:没有下划线
			 */
			WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 11, WritableFont.BOLD, false,
					UnderlineStyle.NO_UNDERLINE);
			WritableCellFormat wcf = new WritableCellFormat(font);
			wcf.setBackground(Colour.WHITE);// 背景颜色
			wcf.setWrap(true);// 设置自动换行;
			wcf.setAlignment(Alignment.CENTRE);// 平行居中
			wcf.setVerticalAlignment(VerticalAlignment.CENTRE);// 垂直居中

			// 循环写入表头
			for (int i = 0; i < columns.size(); i++) {
				/*
				 * 添加单元格(Cell)内容addCell() 添加Label对象Label() 数据的类型有很多种、在这里你需要什么类型就导入什么类型
				 * 如:jxl.write.DateTime 、jxl.write.Number、jxl.write.Label Label(i, 0,
				 * columns[i], wcf) 其中i为列、0为行、columns[i]为数据、wcf为样式
				 * 合起来就是说将columns[i]添加到第一行(行、列下标都是从0开始)第i列、样式为什么"色"内容居中
				 */
				ws.addCell(new Label(i, 0, columns.get(i), wcf));
			}

			// 判断表中是否有数据
			if (CollectionUtils.isNotEmpty(objData)) {
				// 循环写入表中数据
				for (int i = 0; i < objData.size(); i++) {

					// 转换成map集合{activyName:测试功能,count:2}
					Map<String, Object> map = (Map<String, Object>) objData.get(i);

					// 循环输出map中的子集:既列值
					int j = 0;
					for (Object o : map.keySet()) {
						// ps:因为要“”通用”“导出功能,所以这里循环的时候不是get("Name"),而是通过map.get(o)
						ws.addCell(new Label(j, i + 1, String.valueOf(map.get(o))));
						j++;
					}
				}
			}

			wwb.write();// 写入Exel工作表

		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("导出失败");
		} finally {
			try {
				if (null != wwb) {
					wwb.close();
				}
				if (null != os) {
					os.flush();
					os.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 读取excel
	 * 
	 * @param filePath 上传的excel的路径
	 * @return 返回每行的list集合
	 * @throws BiffException
	 */
	public static List<String[]> readExcel(String filePath) throws BiffException {

		List<String[]> list = new ArrayList<String[]>();
		InputStream stream = null;
		Workbook rwb = null;

		try {

			// 创建输入流
			stream = new FileInputStream(filePath);
			// 获取Excel文件对象
			rwb = Workbook.getWorkbook(stream);
			// 获取文件的指定工作表 默认的第一个
			Sheet sheet = rwb.getSheet(0);
			if (sheet == null || sheet.getRows() == 0) {
				return null;
			}
			// 行数(表头的目录不需要,从1开始)
			for (int i = 0; i < sheet.getRows(); i++) {
				// 创建一个数组 用来存储每一列的值
				String[] str = new String[sheet.getColumns()];
				Cell cell = null;
				// 列数
				for (int j = 0; j < sheet.getColumns(); j++) {
					// 获取第i行,第j列的值
					cell = sheet.getCell(j, i);
					str[j] = cell.getContents();
				}
				// 把刚获取的列存入list
				list.add(str);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != rwb) {
					rwb.close();
				}
				if (null != stream) {
					stream.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}

		return list;
	}

	/**
	 * 导出excel
	 *
	 * @param response
	 * @param clazz
	 * @param list
	 * @param filename
	 * @param sheetName
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public static void exportToExcel(HttpServletResponse response, Class clazz, List list, String filename) throws Exception {
		OutputStream os = null;
		WritableWorkbook wwb = null;
		try {

			// excel表头
			List<String> columns = new ArrayList<String>();
			LinkedHashMap<String, String> annoFieldMap = getAnnoField(clazz);
			for (String value : annoFieldMap.values()) {
				columns.add(value);
			}

			// 数据列表
			List<LinkedHashMap<String, Object>> objData = new ArrayList<LinkedHashMap<String, Object>>();
			if(CollectionUtils.isEmpty(list)) {
				return ;
			}
			for (int i = 0; i < list.size(); i++) {
				Object obj = list.get(i);
				Map<String, Object> objFieldMap = getObjFieldKeyAndValue(obj);
				
				LinkedHashMap<String, Object> objDataMap = new LinkedHashMap<String, Object>();
				for (Map.Entry<String, String> entry : annoFieldMap.entrySet()) {
					if (objFieldMap.get(entry.getKey()) == null || StringUtils.isBlank(objFieldMap.get(entry.getKey()).toString())) {
						objDataMap.put(entry.getKey(), "-");
					} else {
						objDataMap.put(entry.getKey(), objFieldMap.get(entry.getKey()));
					}
				}
				objData.add(objDataMap);
			}

			// 设置弹出对话框
			response.setContentType("application/vnd.ms-excel");
			// 设置工作表的标题
			response.setHeader("Content-Disposition",
					"attachment;filename=" + new String(filename.getBytes("gb2312"), "ISO8859-1") + ".xls");// 设置生成的文件名字

			// 根据传进来的file对象创建可写入的Excel工作薄
			os = response.getOutputStream();
			wwb = Workbook.createWorkbook(os);

			/*
			 * 创建一个工作表、sheetName为工作表的名称、"0"为第一个工作表
			 * 打开Excel的时候会看到左下角默认有3个sheet、"sheet1、sheet2、sheet3"这样 代码中的"0"就是sheet1、其它的一一对应。
			 * createSheet(sheetName, 0)一个是工作表的名称,另一个是工作表在工作薄中的位置
			 */
			WritableSheet ws = wwb.createSheet(filename, 0);
			ws.setColumnView(1, 30);

			// 单元格设置
			SheetSettings ss = ws.getSettings();
			ss.setVerticalFreeze(1);// 冻结表头
			ss.setDefaultColumnWidth(16);// 给sheet电子版中所有的列设置默认的列的宽度;
			ss.setShowGridLines(true);

			/*
			 * WritableFont.createFont("宋体"):设置字体为宋体 18:设置字体大小
			 * WritableFont.BOLD:设置字体加粗(BOLD:加粗 NO_BOLD:不加粗) false:设置非斜体
			 * UnderlineStyle.NO_UNDERLINE:没有下划线
			 */
			WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 11, WritableFont.BOLD, false,
					UnderlineStyle.NO_UNDERLINE);
			WritableCellFormat wcf = new WritableCellFormat(font);
			wcf.setBackground(Colour.WHITE);// 背景颜色
			wcf.setWrap(true);// 设置自动换行;
			wcf.setAlignment(Alignment.CENTRE);// 平行居中
			wcf.setVerticalAlignment(VerticalAlignment.CENTRE);// 垂直居中

			// 循环写入表头
			for (int i = 0; i < columns.size(); i++) {
				/*
				 * 添加单元格(Cell)内容addCell() 添加Label对象Label() 数据的类型有很多种、在这里你需要什么类型就导入什么类型
				 * 如:jxl.write.DateTime 、jxl.write.Number、jxl.write.Label Label(i, 0,
				 * columns[i], wcf) 其中i为列、0为行、columns[i]为数据、wcf为样式
				 * 合起来就是说将columns[i]添加到第一行(行、列下标都是从0开始)第i列、样式为什么"色"内容居中
				 */
				ws.addCell(new Label(i, 0, columns.get(i), wcf));
			}

			// 判断表中是否有数据
			if (CollectionUtils.isNotEmpty(objData)) {
				// 循环写入表中数据
				for (int i = 0; i < objData.size(); i++) {

					// 转换成map集合{activyName:测试功能,count:2}
					Map<String, Object> map = (Map<String, Object>) objData.get(i);

					// 循环输出map中的子集:既列值
					int j = 0;
					for (Object o : map.keySet()) {
						// ps:因为要“”通用”“导出功能,所以这里循环的时候不是get("Name"),而是通过map.get(o)
						ws.addCell(new Label(j, i + 1, String.valueOf(map.get(o))));
						j++;
					}
				}
			}

			wwb.write();// 写入Exel工作表

		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("导出失败");
		} finally {
			try {
				if (null != wwb) {
					wwb.close();
				}
				if (null != os) {
					os.flush();
					os.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 根据对象获取对象key value
	 *
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public static Map<String, Object> getObjFieldKeyAndValue(Object obj) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		Class userCla = (Class) obj.getClass();
		Field[] fs = userCla.getDeclaredFields();
		for (int i = 0; i < fs.length; i++) {
			Field f = fs[i];
			f.setAccessible(true);
			Object val = f.get(obj);
			if (val == null) {
				continue;
			}
			if (f.getName().equals("serialVersionUID")) {
				continue;
			}
			map.put(f.getName(), val);
		}
		return map;
	}

	/**
	 * 根据类获取实体类注解的字段名和注解属性
	 *
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static LinkedHashMap<String, String> getAnnoField(Class clazz) throws Exception {
		// 获取注解并排序
		List<Field> fieldList = new ArrayList<>();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAnnotationPresent(ExcelField.class)) {
				continue;
			}
			fieldList.add(field);
		}
		fieldList.sort(Comparator.comparingInt(m -> m.getAnnotation(ExcelField.class).sort()));
		
		// 将注解放入map中
		LinkedHashMap<String, String> valueMap = new LinkedHashMap<>();
		for (Field field : fieldList) {
			String fieldNames = field.getName();
			ExcelField excelField = field.getAnnotation(ExcelField.class);
			if (valueMap.get(excelField.name()) != null) {
				continue;
			}
			valueMap.put(fieldNames, excelField.name());
		}
		return valueMap;
	}
}

注解

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

/**
 * 标记可以用于导出excel表头
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelField {
	
	/**
	 * 名称
	 *
	 * @return
	 */
	String name() default "";
	
	/**
	 * 排序
	 *
	 * @return
	 */
	int sort();
}

实体类


	@ExcelField(name="本次完成", sort=7)
	private java.lang.String currentPlan;
	
	@ExcelField(name="下次计划", sort=8)
	private java.lang.String afterPlan;
	
	@ExcelField(name="上次计划", sort=6)
	private java.lang.String beforePlan;

使用

JxlExcelUtils.exportToExcel(response, XXX.class, datas, filename);

说明:

1.第一种是根据注解导出excel

2.第二种是传入表头和数据map集合导出数据,根据情况使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值