package com.example.wangyanan.annotation;
import java.lang.annotation.*;
/**
*
* @ClassName: ProtocolAnnotation
* @Description: 自定义注解的使用
* @date 2018年1月9日 下午5:44:08
*
*/
public class ProtocolAnnotation {
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface protocolReqClass {
String name() default "";
String serviceName() default "";
String methodName() default "";
String description() default "";
String author() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface protocolResClass {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ProtocolFiled {
String name() default "";
String isNotNull() default "否";
String description() default "";
String column();
}
}
package com.example.wangyanan;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.wangyanan.entity.UserEntity;
import com.example.wangyanan.util.PoiUtil;
/**
*
* @ClassName: UserInterfaceTest
* @Description: 自定义注解的使用
* @date 2018年1月9日 下午5:43:00
*
*/
@RunWith(SpringRunner.class)
public class UserInterfaceTest {
private Logger logger = Logger.getLogger(UserInterfaceTest.class);
@Test
public void exportExcel(){
// 初始化数据
List<UserEntity> list = new ArrayList<UserEntity>();
UserEntity vo = new UserEntity();
list.add(vo);
FileOutputStream out = null;
try {
out = new FileOutputStream("d:\\success3.xls");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
PoiUtil<UserEntity> util = new PoiUtil<UserEntity>(UserEntity.class);// 创建工具类.
util.exportExcel(list, "学生信息1", out);// 导出
logger.info("----执行完毕----------");
}
}
package com.example.wangyanan.util;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.ss.util.CellRangeAddress;
import com.example.wangyanan.annotation.ProtocolAnnotation.ProtocolFiled;
import com.example.wangyanan.annotation.ProtocolAnnotation.protocolReqClass;
/**
*
* @ClassName: PoiUtil
* @Description: 接口文档导出公共类
* @date 2018年1月9日 下午5:31:03
*
* @param <T>
*/
public class PoiUtil<T> {
Class<T> clazz;
public PoiUtil(Class<T> clazz) {
this.clazz = clazz;
}
/**
*
* @Title: exportExcel
* @Description: 按照接口文档形式进行导出
* @param @param lists
* @param @param sheetNames
* @param @param output
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public boolean exportExcel(List<T> lists[], String sheetNames[], OutputStream output) {
if (lists.length != sheetNames.length) {
System.out.println("数组长度不一致");
return false;
}
HSSFWorkbook workbook = new HSSFWorkbook();// 产生工作薄对象
for (int ii = 0; ii < lists.length; ii++) {
String sheetName = sheetNames[ii];
List<Field> fields = getMappedFiledByList(clazz, null);
HSSFSheet sheet = workbook.createSheet();// 产生工作表对象
workbook.setSheetName(ii, sheetName);
HSSFRow row;
HSSFCell cell;// 产生单元格
row = sheet.createRow(0);// 产生一行
CellRangeAddress region = new CellRangeAddress(0, 0, 0, 3);
sheet.addMergedRegion(region);
cell = row.createCell(0);// 创建列
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中
cell.setCellStyle(style);
if (clazz.isAnnotationPresent(protocolReqClass.class)) {
// Annotation[] annotations=clazz.getAnnotation(annotationClass);
protocolReqClass annotation = clazz.getAnnotation(protocolReqClass.class);
cell.setCellValue(annotation.name());// 写入列名
}
for (int i = 1; i <= fields.size(); i++) {
Field field = fields.get(i - 1);
Map<String, List<Field>> list = getMappedFiled(clazz);
row = sheet.createRow(i);// 产生一行
ProtocolFiled attr = field.getAnnotation(ProtocolFiled.class);
if (!attr.name().endsWith("List")) {
cell = row.createCell(0);// 创建列
cell.setCellValue(attr.name());// 写入列名
cell = row.createCell(1);// 创建列
cell.setCellValue(attr.isNotNull());// 写入列名
cell = row.createCell(2);// 创建列
cell.setCellValue(attr.description());// 写入列名
cell = row.createCell(3);// 创建列
cell.setCellValue(attr.column());// 写入列名
} else {
List<Field> fields2 = list.get("list");
for (Field field2 : fields2) {
//获取到对象的基本类型
Type fc = field2.getGenericType();
ParameterizedType pt = (ParameterizedType) fc;
//得到泛型里的class类型对象。
Class genericClazz = (Class) pt.getActualTypeArguments()[0];
List<Field> fields1 = getMappedFiledByList(genericClazz, null);
Class<?> cls = null;
protocolReqClass annotation = null;
try {
//获取到实例化的对象
cls = Class.forName(genericClazz.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (cls.isAnnotationPresent(protocolReqClass.class)) {
//获取到对象自定义的类注解
annotation = cls.getAnnotation(protocolReqClass.class);
}
CellRangeAddress region1 = new CellRangeAddress(i, i, 0, 3);
System.out.println("+++++++++++++++++--------------" + i);
sheet.addMergedRegion(region1);
row = sheet.createRow(i);// 产生一行
cell = row.createCell(0);// 创建列
HSSFCellStyle style1 = workbook.createCellStyle();
style1.setAlignment(HSSFCellStyle.ALIGN_LEFT); // 居左
cell.setCellStyle(style1);
cell.setCellValue(annotation.name());// 写入列名
for (int j = 1; j <= fields1.size(); j++) {
Field field1 = fields1.get(j - 1);
row = sheet.createRow(++i);
//获取到字段自定义注解
ProtocolFiled attr1 = field1.getAnnotation(ProtocolFiled.class);
cell = row.createCell(0);
cell.setCellValue(attr1.name());
cell = row.createCell(1);
cell.setCellValue(attr1.isNotNull());
cell = row.createCell(2);
cell.setCellValue(attr1.description());
cell = row.createCell(3);
cell.setCellValue(attr1.column());
System.out.println("---------------------" + i);
if (j == fields1.size()) {
//合并列
CellRangeAddress region2 = new CellRangeAddress(++i, i, 0, 3);
row = sheet.createRow(i);// 产生一行
System.out.println("+++++++++++++++++" + i);
sheet.addMergedRegion(region2);
cell = row.createCell(0);
HSSFCellStyle style2 = workbook.createCellStyle();
style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
cell.setCellStyle(style2);
cell.setCellValue(annotation.name());
}
}
++i;//注意i++和++i的区别
}
}
}
}
try {
output.flush();
workbook.write(output);
output.close();
return true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("Output is closed ");
return false;
}
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName
* 工作表的名称
* @param sheetSize
* 每个sheet中数据的行数,此数值必须小于65536
* @param output
* java输出流
*/
@SuppressWarnings("unchecked")
public boolean exportExcel(List<T> list, String sheetName, OutputStream output) {
// 此处 对类型进行转换
List<T> ilist = new ArrayList<>();
for (T t : list) {
ilist.add(t);
}
List<T>[] lists = new ArrayList[1];
lists[0] = ilist;
String[] sheetNames = new String[1];
sheetNames[0] = sheetName;
return exportExcel(lists, sheetNames, output);
}
/**
*
* @Title: getMappedFiled
* @Description: 将对象中的字段按照是否为集合进行区分封装
* @param @param clazz
* @param @return 设定文件
* @return Map<String,List<Field>> 返回类型
* @throws
*/
@SuppressWarnings("rawtypes")
private Map<String, List<Field>> getMappedFiled(Class clazz) {
Map<String, List<Field>> map = new HashMap<String, List<Field>>();
List<Field> fieldList = new ArrayList<Field>();
List<Field> fieldOther = new ArrayList<Field>();
Field[] allFields = clazz.getDeclaredFields();// 得到所有定义字段
// 得到所有field并存放到一个list中.
for (Field field : allFields) {
if (field.isAnnotationPresent(ProtocolFiled.class)) {
Class fieldClazz = field.getType(); // 得到field的class及类型全路径
// 判断是否为基本类型
if (fieldClazz.isPrimitive())
continue;
// getName()返回field的类型全路径;
if (!fieldClazz.isAssignableFrom(List.class)) {
fieldOther.add(field);
} else {
fieldList.add(field);
}
}
}
map.put("list", fieldList);
map.put("other", fieldOther);
if (clazz.getSuperclass() != null && !clazz.getSuperclass().equals(Object.class)) {
getMappedFiled(clazz.getSuperclass());
}
return map;
}
/**
*
* @Title: getMappedFiledByList
* @Description: 获取到对象中的所有有注解的字段
* @param @param clazz
* @param @param fields
* @param @return 设定文件
* @return List<Field> 返回类型
* @throws
*/
@SuppressWarnings("rawtypes")
private List<Field> getMappedFiledByList(Class clazz, List<Field> fields) {
if (fields == null) {
fields = new ArrayList<Field>();
}
Field[] allFields = clazz.getDeclaredFields();// 得到所有定义字段
// 得到所有field并存放到一个list中.
for (Field field : allFields) {
if (field.isAnnotationPresent(ProtocolFiled.class)) {
fields.add(field);
}
}
if (clazz.getSuperclass() != null
&& !clazz.getSuperclass().equals(Object.class)) {
getMappedFiledByList(clazz.getSuperclass(), fields);
}
return fields;
}
}