问题描述:
使用excle导出的时候,部分字段无法获取,结果检查,发现是vo类,字段的修饰符为public,应该为private,然后excle的工具类,在获取字段的时候,以前使用的是Field[] fields = Class.getFields(),之后写了一个工具类,递归调用获取vo类的所有的字段,包括继承的父类,下面为代码:
@Service
@Slf4j
public class ExcelExpotUtils {
public static final int SHEET_PAGE_NUM =10000;
public void exportDataExcel(HttpServletResponse response, String fileName, Class c, List beanMapList)throws IOException {
long startTime = System.currentTimeMillis();
fileName = fileName+".xlsx";
XSSFWorkbook wb =new XSSFWorkbook();
// 工作表对象
XSSFSheet sheet =null;
//行对象
Row row =null;
//列对象
Cell cell =null;
List titleList =new ArrayList<>();
List fieldList =new ArrayList<>();
List fields = BeanUtil.getDeclaredFields(c);
for (Field field : fields) {
titleList.add(field.getAnnotation(ApiModelProperty.class).value());
fieldList.add(field.getName());
}
//总行号
int rowNo =0;
//页行号
int pageRowNo =0;
if (beanMapList ==null || beanMapList.size() ==0) {
sheet = wb.createSheet("工作簿" + (rowNo /SHEET_PAGE_NUM));
//动态指定当前的工作表
sheet = wb.getSheetAt(rowNo /SHEET_PAGE_NUM);
//新建了工作表,重置工作表的行号为0
pageRowNo =0;
// -----------定义表头-----------
row = sheet.createRow(pageRowNo++);
// 列数 titleKeyList.size()
for (int i =0; i < titleList.size(); i++) {
Cell cellTem = row.createCell(i);
cellTem.setCellValue(titleList.get(i));
}
}else {
for (int k =0; k < beanMapList.size(); k++) {
Map srcMap = beanMapList.get(k);
//写入SHEET_PAGE_NUM条后切换到下个工作表
if (rowNo %SHEET_PAGE_NUM ==0) {
// System.out.println("Current Sheet:" + rowNo/SHEET_PAGE_NUM);
//建立新的sheet对象
sheet = wb.createSheet("工作簿" + (rowNo /SHEET_PAGE_NUM));
//动态指定当前的工作表
sheet = wb.getSheetAt(rowNo /SHEET_PAGE_NUM);
//新建了工作表,重置工作表的行号为0
pageRowNo =0;
// -----------定义表头-----------
row = sheet.createRow(pageRowNo++);
// 列数 titleKeyList.size()
for (int i =0; i < titleList.size(); i++) {
Cell cellTem = row.createCell(i);
cellTem.setCellValue(titleList.get(i));
}
rowNo++;
// ---------------------------
}
rowNo++;
//新建行对象
row = sheet.createRow(pageRowNo++);
// 行,获取cell值
for (int j =0; j < fieldList.size(); j++) {
cell = row.createCell(j);
Object object = srcMap.get(fieldList.get(j));
if (object !=null) {
if (objectinstanceof BigDecimal || objectinstanceof Double || objectinstanceof Long || objectinstanceof Integer) {
cell.setCellValue(Double.parseDouble(object.toString()));
//设置单元格类型
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
}else if(objectinstanceof List){
List list = (List) object;
StringBuffer lvalue =new StringBuffer();
list.forEach(t -> {
lvalue.append(t.toString()).append("\r\n");
});
cell.setCellValue(lvalue.toString());
}else{
cell.setCellValue(object.toString());
}
}
}
}
}
log.info("生存导出{}.xlsx耗时{}ms",fileName,System.currentTimeMillis()-startTime);
setSizeColumn(sheet, fieldList.size() ==0 ?1 : fieldList.size());
log.info("自适应{}.xlsx耗时{}ms",fileName,System.currentTimeMillis()-startTime);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.addHeader("Content-Disposition", "attachment; filename=" +new String(fileName.getBytes("utf-8"), "iso8859-1"));
response.flushBuffer();
OutputStream outputStream = response.getOutputStream();
wb.write(response.getOutputStream());
wb.close();
outputStream.flush();
outputStream.close();
;
}
// 自适应宽度(中文支持)
private void setSizeColumn(XSSFSheet sheet, int size) {
for (int columnNum =0; columnNum < size; columnNum++) {
int columnWidth = sheet.getColumnWidth(columnNum) /256;
// System.out.println(sheet.getLastRowNum());
for (int rowNum =0; rowNum <= sheet.getLastRowNum(); rowNum++) {
XSSFRow currentRow;
//当前行未被使用过
if (sheet.getRow(rowNum) ==null) {
currentRow = sheet.createRow(rowNum);
}else {
currentRow = sheet.getRow(rowNum);
}
if (currentRow.getCell(columnNum) !=null) {
XSSFCell currentCell = currentRow.getCell(columnNum);
if (currentCell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
int length = currentCell.getStringCellValue().getBytes().length;
if (columnWidth < length) {
columnWidth = length;
}
}
}
}
sheet.setColumnWidth(columnNum, columnWidth *256);
}
}
}
工具类的方法,递归获取所有的字段类型
/**
* 获取类的所有字段,包括继承的父类字段。
*
* @param clazz 类型
* @return 字段列表
*/
public static ListgetDeclaredFields(Class clazz) {
List fieldList =new ArrayList<>();
getDeclaredFields(clazz, fieldList);
return fieldList;
}
public static void getDeclaredFields(Class clazz, List fieldList) {
Field[] fields = clazz.getDeclaredFields();
Arrays.stream(fields).forEach(field ->fieldList.add(field));
Class superclass = clazz.getSuperclass();
if (superclass == Object.class) {
return;
}
getDeclaredFields(superclass, fieldList);
}