java注解中可使用对象_Java注解(二):实战 - 直接使用对象列表生成报表...

通过对Java注解(一):介绍,思想及优点学习了解,相信大家对Java注解有一定程度的了解,本篇文章将实战项目中的应用来加深对Java注解的了解。

本实例实现根据指定字段的JavaBean,生成对应列的报表。使用Java注解就是方便实现JavaBean与Excel或CSV列已一一映射。直观展现数据,不需要中间转换,Java注解可以很轻松实现。

下面先给出Java注解的定义:

import java.lang.annotation.*;

/**

* 类功能描述:列属性

*

* @author WangXueXing create at 18-10-29 下午4:40

* @version 1.0.0

*/

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Inherited

public @interface ColumnProperty {

/**

* 列序号

* @return

*/

int index();

/**

* 列表头名

* @return

*/

String name();

}

本注解定义目的是使用在JavaBean的每个字段映射到Excel中的列序号及列表头名。这样对于开发者,我只需要定义好报表展示的列及相对位置,并组装JavaBean list.直观,不需要关心转换过程。

下面代码就是定义JavaBean及使用上面定义的注解:

import com.today.service.financereport.util.ColumnProperty

import scala.annotation.meta.field

import scala.beans.BeanProperty

/**

* 类功能描述:营收明细

*

* @author WangXueXing create at 18-10-23 下午7:52

* @version 1.0.0

*/

case class IncomeDetail(/** 店号 */

@(ColumnProperty@field)(index = 0, name = "店号")

@BeanProperty

storeId: String,

/** 店名 */

@(ColumnProperty@field)(index = 1, name = "店名")

@BeanProperty

storeName: String,

/** 门店类型 */

@(ColumnProperty@field)(index = 2, name = "门店类型")

@BeanProperty

storeType: String,

/** 营业日期 */

@(ColumnProperty@field)(index = 3, name = "营业日期")

@BeanProperty

businessDate: String,

/** 交易时间 */

@(ColumnProperty@field)(index = 4, name = "交易时间")

@BeanProperty

payTime: String,

/** 订单号 */

@(ColumnProperty@field)(index = 5, name = "订单号")

@BeanProperty

orderNo: String,

/** 交易流水号 */

@(ColumnProperty@field)(index = 6, name = "交易流水号")

@BeanProperty

tradeNo: String,

/** 金额 */

@(ColumnProperty@field)(index = 7, name = "金额")

@BeanProperty

tradeAmount: BigDecimal,

/** 抹零金额 */

@(ColumnProperty@field)(index = 8, name = "抹零金额")

@BeanProperty

spotAmount: BigDecimal,

/** 支付方式 */

@(ColumnProperty@field)(index = 9, name = "支付方式")

@BeanProperty

tradeType: String,

/** POS机 */

@(ColumnProperty@field)(index = 10, name = "POS机")

@BeanProperty

posId: String,

/** 收银员 */

@(ColumnProperty@field)(index = 11, name = "收银员")

@BeanProperty

cashierName: String,

/** 订单类型 */

@(ColumnProperty@field)(index = 12, name = "订单类型")

@BeanProperty

payType: String,

/** 第三方商户订单号 */

@(ColumnProperty@field)(index = 13, name = "第三方商户订单号")

@BeanProperty

thirdPartyPaymentNo: String

)

其中@BeanProperty是Scala自带的一个注解,就是免去Java中对每个字段的getter()与setter()的定义。

以下是伪代码,从数据库中获取对应数据结构为IncomeDetail的数据列表:

def getReportData: List[IncomeDetail] = {

return jdbc.getIncomeDetailList()

}

获取到数据后,将数据通过注解转换并填入报表:

val incomeDetailList = getReportData()

val file = File.createTempFile( "营收明细报表_" + MathUtils.getRandom(4), ".csv")

ScalaFunction.tryWithResources(new PrintWriter(file, "GBK")) { out =>

val dataObj =incomeDetailList.isInstanceOf[Seq[AnyRef@unchecked]] match {

case true => incomeDetailList.asInstanceOf[List[AnyRef@unchecked]]

case _ => List.empty

}

//根据注解顺序生成CSV数据列表

AnnotationUtil.getValueWithHead(dataObj).foreach(out.println(_))

}

其中ScalaFunction.tryWithResources()仿照Java try with resources本人定义了一个Scala函数来处理流关闭,详情请参考我以前的博客:Scala实现Try with resources自动关闭IO

/**

* 类功能描述:Scala高级函数

*

* @author WangXueXing create at 18-11-22 下午5:29

* @version 1.0.0

*/

object ScalaFunction {

/**

* Scala实现Java7 try-with-resources

* @see https://www.cnblogs.com/barrywxx/p/10002422.html

*/

def tryWithResources[A <: close unit b a> B): B = {

try {

f(a)

} finally {

if(a != null){

a.close()

}

}

}

}

我们重点关注下AnnotationUtil.getValueWithHead(), 这个方法定义了通过注解将数据填入Excel或CSV报表的过程:

import java.lang.reflect.Field

import com.today.service.financereport.dto.IncomeDetail

/**

* 类功能描述:Scala注解工具类

*

* @author WangXueXing create at 18-10-30 下午3:35

* @version 1.0.0

*/

object AnnotationUtil {

/**

* 根据注解获取值列表

*/

def getValueWithHead(valList: List[_]): List[String] ={

var fields: Array[Field] = Array.empty

val dataList: List[String] = valList.zipWithIndex.map{ x=>

if(x._2 == 0){

fields = x._1.getClass.getDeclaredFields.sortBy(_.getAnnotations.apply(0).asInstanceOf[ColumnProperty].index())

}

fields.map{f=>

f.setAccessible(true)

val value = f.get(x._1)

if(value == null){

""

} else {

value.toString

}

}.mkString(",")

}

fields.map(_.getAnnotation(classOf[ColumnProperty]).name()).mkString(",")+:dataList

}

def main(args: Array[String]): Unit = {

val list = List(IncomeDetail("wew1","eerr1","wrw1",null,"1","1","1",BigDecimal(12.1),BigDecimal(12.1),"1","1","1"),

IncomeDetail("rer2","wrwrw2","wrw2","2","2","2","2",BigDecimal(12.1),BigDecimal(12.1),"2","2","2"))

val objList = getValueWithHead(list)

objList.foreach(println(_))

}

}

好了,到这里,这个实例已经完成。是不是以后就不需要关注怎样组装复杂报表数据结构,只需要将JavaBean定义好,按照这个JavaBean的数据结构组装数据就行了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值