第三步:向工作表填充了数据,填充表头,填充内容(定义了获取单元格内容的方法:getFieldValueByNameSequence)
private static <T> void fillSheet(WritableSheet sheet, List<T> list,
LinkedHashMap<String, String> fieldMap, int firstIndex,
int lastIndex) throws Exception {
CellView cellView = new CellView();
cellView.setAutosize(true); // 设置自动大小
sheet.setColumnView(1, cellView);// 根据内容自动设置列宽
// 设置表头格式
jxl.write.WritableFont wfont = new jxl.write.WritableFont(WritableFont.ARIAL, 12, WritableFont.BOLD);
WritableCellFormat wc1 = new WritableCellFormat(wfont);
wc1.setAlignment(Alignment.CENTRE); // 设置居中
wc1.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc1.setBackground(jxl.format.Colour.PALE_BLUE); // 设置单元格的背景颜色
// 设置内容格式
jxl.write.WritableFont wfont2 = new jxl.write.WritableFont(WritableFont.ARIAL, 11);
WritableCellFormat wc2 = new WritableCellFormat(wfont2);
wc2.setBorder(Border.ALL, BorderLineStyle.THIN);
wc2.setWrap(true);//设置自动换行
// 定义存放英文字段名和中文字段名的数组
String[] enFields = new String[fieldMap.size()];
String[] cnFields = new String[fieldMap.size()];
// 填充数组
int count = 0;
for (Entry<String, String> entry : fieldMap.entrySet()) {
enFields[count] = entry.getKey();
cnFields[count] = entry.getValue();
count++;
}
// 填充表头
for (int i = 0; i < cnFields.length; i++) {
Label label = new Label(i, 0, cnFields[i], wc1);
sheet.addCell(label);
}
// 填充内容
int rowNo = 1;
for (int index = firstIndex; index <= lastIndex; index++) {
// 获取单个对象
T item = list.get(index);
for (int i = 0; i < enFields.length; i++) {
Object objValue = getFieldValueByNameSequence(enFields[i], item);
String fieldValue = objValue == null ? "" : objValue.toString();
Label label = new Label(i, rowNo, fieldValue, wc2);
sheet.addCell(label);
}
rowNo++;
}
// 设置自动列宽
setColumnAutoSize(sheet, 5);
}
第四步:对属性名进行拆分,判断是简单属性名还是带路径的属性名,定义获取单元格内容的最终方法(getFieldValueByName)
/**
* @MethodName : getFieldValueByNameSequence
* @Description : 根据带路径或不带路径的属性名获取属性值:即接受简单属性名,如userName等,又接受带路径的属性名,如student.department.name等
* @param fieldNameSequence 带路径的属性名或简单属性名
* @param o 对象
* @return 属性值
* @throws Exception
*/
private static Object getFieldValueByNameSequence(String fieldNameSequence,Object o) throws Exception {
Object value = null;
// 将fieldNameSequence进行拆分
String[] attributes = fieldNameSequence.split("\\.");
if (attributes.length == 1) {
value = getFieldValueByName(fieldNameSequence, o);
} else {
// 根据属性名获取属性对象
Object fieldObj = getFieldValueByName(attributes[0], o);
String subFieldNameSequence = fieldNameSequence.substring(fieldNameSequence.indexOf(".") + 1);
value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj);
}
return value;
}
第五步:获取单元格内容
private static Object getFieldValueByName(String fieldName, Object o)
throws Exception {
Object value = null;
Field field = getFieldByName(fieldName, o.getClass());//(传入栏位字段名,反射出实体类)根据比对,返回实体类中是否有该Excel栏位字段
if (field != null) {
field.setAccessible(true);//反射中加速性能
value = field.get(o);//反射:根据字段,获取值
} else {
throw new ExcelException(o.getClass().getSimpleName() + "類不存在欄位名 "+ fieldName);
}
return value;
}
/**
* @MethodName : getFieldByName
* @Description : 根据字段名获取字段
* @param fieldName 字段名
* @param clazz 包含该字段的类
* @return 字段
*/
private static Field getFieldByName(String fieldName, Class<?> clazz) {
Field[] selfFields = clazz.getDeclaredFields();// 拿到本类的所有字段
for (Field field : selfFields) {
if (field.getName().equals(fieldName)) {// 如果本类中存在该字段,则返回
return field;
}
}
// 否则,查看父类中是否存在此字段,如果有则返回
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
return getFieldByName(fieldName, superClazz);
}
// 如果本类和父类都没有,则返回空
return null;
}