0
点赞
收藏
分享

微信扫一扫

若依管理系统源码分析-导出Excel时怎样通过注解中readConverterExp实现格式化导出列的显示格式(0和1格式化为是否)


场景

在数据库中存储某些个是否的字段时,有时会使用tinint进行存储

若依管理系统源码分析-导出Excel时怎样通过注解中readConverterExp实现格式化导出列的显示格式(0和1格式化为是否)_若依

 

这样会在实体类中生成布尔类型的变量

private Boolean sfkt;

有时也会用int进行存储是否

若依管理系统源码分析-导出Excel时怎样通过注解中readConverterExp实现格式化导出列的显示格式(0和1格式化为是否)_List_02

 

那么在实体类中就可能用Integer和String进行是否字段的存取

private String sfcl;

那么在使用若依自带的导出时,如果不加修改,则会直接将对应的字段的列导出为0或者1,true或者false。

如果想要根据此列的0和1进而显示是和否怎样显示。

注:

实现

如果是0和1格式化为是和否

找到对应的实体类中的属性,在注解上添加

@Excel(name = "是否处理完成",readConverterExp = "0=否,1=是")
private String sfcl;

添加读取转换表达式属性readConverterExp就可以实现,具体见下面源码分析。

如果是true和false格式化为是和否

@Excel(name = "是否跨天",readConverterExp = "false=否,true=是")
private Boolean sfkt;

表达式的格式要固定如上,值可以自己根据要求去添加。

下面分析为什么这样添加就可以。

源码分析

在SpringbBoot后台接口中

@GetMapping("/export")
public AjaxResult export(KqBcgl kqBcgl)
{
List<KqBcgl> list = kqBcglService.getBcListByNameToExport(kqBcgl);
ExcelUtil<KqBcgl> util = new ExcelUtil<KqBcgl>(KqBcgl.class);
return util.exportExcel(list, "bcgl");
}

其中list是查询数据库的数据。

然后调用工具类生成工具类对象,主要是调用exportExcel方法来生成Excel

在方法中

public AjaxResult exportExcel(List<T> list, String sheetName)
{
this.init(list, sheetName, Type.EXPORT);
return exportExcel();
}

调用了init方法,生成一些工作簿以及列等相关信息的对象。

在方法createExcelField中

private void createExcelField()
{
this.fields = new ArrayList<Object[]>();
List<Field> tempFields = new ArrayList<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (Field field : tempFields)
{
// 单注解
if (field.isAnnotationPresent(Excel.class))
{
putToField(field, field.getAnnotation(Excel.class));
}

// 多注解
if (field.isAnnotationPresent(Excels.class))
{
Excels attrs = field.getAnnotation(Excels.class);
Excel[] excels = attrs.value();
for (Excel excel : excels)
{
putToField(field, excel);
}
}
}
}

和方法createWorkbook中

public void createWorkbook()
{
this.wb = new SXSSFWorkbook(500);
}

主要是读取注解和调用了POI的一些方法用来初始化Excel的相关对象。

构建excel数据的方法主要是exportExcel()

public AjaxResult exportExcel()
{
OutputStream out = null;
try
{
// 取出一共有多少个sheet.
double sheetNo = Math.ceil(list.size() / sheetSize);
for (int index = 0; index <= sheetNo; index++)
{
createSheet(sheetNo, index);

// 产生一行
Row row = sheet.createRow(0);
int column = 0;
// 写入各个字段的列头名称
for (Object[] os : fields)
{
Excel excel = (Excel) os[1];
this.createCell(excel, row, column++);
}
if (Type.EXPORT.equals(type))
{
fillExcelData(index, row);
}
}
String filename = encodingFilename(sheetName);
out = new FileOutputStream(getAbsoluteFile(filename));
wb.write(out);
return AjaxResult.success(filename);
}
catch (Exception e)
{
log.error("导出Excel异常{}", e.getMessage());
throw new CustomException("导出Excel失败,请联系网站管理员!");
}
finally
{
if (wb != null)
{
try
{
wb.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
if (out != null)
{
try
{
out.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
}

这其中使用填充excel的方法fillExcelData

public void fillExcelData(int index, Row row)
{
int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size());
for (int i = startNo; i < endNo; i++)
{
row = sheet.createRow(i + 1 - startNo);
// 得到导出对象.
T vo = (T) list.get(i);
int column = 0;
for (Object[] os : fields)
{
Field field = (Field) os[0];
Excel excel = (Excel) os[1];
// 设置实体类私有属性可访问
field.setAccessible(true);
this.addCell(excel, row, vo, field, column++);
}
}
}

上面的fields是读取的注解列表,

/**
* 注解列表
*/
private List<Object[]> fields;

遍历每个注解对象后调用addCell方法

public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
{
Cell cell = null;
try
{
// 设置行高
row.setHeight((short) (attr.height() * 20));
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if (attr.isExport())
{
// 创建cell
cell = row.createCell(column);
cell.setCellStyle(styles.get("data"));

// 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr);
String dateFormat = attr.dateFormat();
String readConverterExp = attr.readConverterExp();
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
{
cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
}
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
{
cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
}
else
{
// 设置列类型
setCellVo(value, attr, cell);
}
}
}
catch (Exception e)
{
log.error("导出Excel失败{}", e);
}
return cell;
}

在这里是执行填充单元格的方法,其中

 

String readConverterExp = attr.readConverterExp();

就是获取上面设置的注解readConverterExp属性

else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
{
cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
}

判断如果不为空的话将单元格的值和传递的表达式传递给方法convertByExp

  

/**
* 解析导出值 0=男,1=女,2=未知
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @return 解析后值
* @throws Exception
*/
public static String convertByExp(String propertyValue, String converterExp) throws Exception
{
try
{
String[] convertSource = converterExp.split(",");
for (String item : convertSource)
{
String[] itemArray = item.split("=");
if (itemArray[0].equals(propertyValue))
{
return itemArray[1];
}
}
}
catch (Exception e)
{
throw e;
}
return propertyValue;
}

首先将表达式按照逗号分隔,获取分隔后的数组,然后遍历数组。

再根据=分隔,如果等号左边即分割后数组的第一个值与单元格的值相等,就返回等号右边的值即分隔后的第二个值。

这样就实现了按照指定表达式将单元格的值进行格式化显示。

 

 

 

举报

相关推荐

0 条评论