• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于Java反射和Fel計算引擎動態(tài)導出Excel的實現(xiàn)

      2022-08-20 09:21:42張勝楠
      現(xiàn)代計算機 2022年12期
      關鍵詞:表達式調用報表

      張勝楠

      (武漢光谷職業(yè)學院,武漢 430000)

      0 引言

      Web系統(tǒng)應用中經(jīng)常會進行Excel表格的導出,傳統(tǒng)的導出方式在導出不同對象時需要配置表頭并且代碼頻繁復用,導致代碼冗余、工作量大,導出流程機械,并且對于大數(shù)據(jù)表操作效率較低。本文介紹一種基于Java反射和自定義注解,結合Fel計算表達式的方法,來實現(xiàn)Excel靈活動態(tài)的導出效果。

      1 相關概念介紹

      1.1 Java反射

      Java反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調用對象的方法的功能稱為Java語言的反射機制。

      1.2 自定義注解

      注解其實就是一種標記,可以在程序代碼中的關鍵節(jié)點(類、方法、變量、參數(shù)、包)上打上這些標記,然后程序在編譯時或運行時可以檢測到這些標記從而執(zhí)行一些特殊操作。

      1.3 Fel計算

      Fel是輕量級的高效的表達式計算引擎,F(xiàn)el源自于企業(yè)項目,設計目標是為了滿足不斷變化的功能需求和性能需求。Fel的執(zhí)行主要通過函數(shù)實現(xiàn),運算符(+、-等)都是Fel函數(shù),所有這些函數(shù)都是可以替換的,擴展函數(shù)也非常簡單,可以根據(jù)性能要求選擇執(zhí)行方式。編譯執(zhí)行就是將表達式編譯成字節(jié)碼(生成java代碼和編譯模塊都是可以擴展和替換的)。

      2 實現(xiàn)步驟

      2.1 自定義注解

      構建ExportTblAnnotation.java類,自定義類注解:構建ExportAnnotation.java類,自定義方法注解,標記特定的類和方法,用于導出文件的數(shù)據(jù)填充。

      //Excel導出注解

      @Target({E1ementType.TYPE})

      @Retention(RetentionPolicy.RUNTIME)

      @Documented

      public@interface ExportTblAnnotation{

      }

      //Excel導出注解

      @Target({E1ementType.METHOD})

      @Retention(RetentionPolicy.RUNTIME)

      @Documented

      public@interface ExportAnnotation{

      Public String code()default"";

      }

      2.2 創(chuàng)建Bean Def i nat i on對象

      用于存儲被上述自定義注解所標記的類和方法的定義。一個BeanDefinition描述了一個Bean實例,實例包含屬性值、構造方法參數(shù)值以及更多實現(xiàn)信息。該BeanDefinition只是一個最小的接口,主要目的是能動態(tài)地調用實現(xiàn)方法,這里列出幾個核心方法。

      //bean定義

      public class BeanDefinition{

      private String beanName;

      private String methodName;

      private Class<?>[]parameterClass;

      private Class<?>returnType;

      private String[]parameterNames;

      public String[]getParameterNames(){return paraneterNames;}

      public void setParameterNames(String[]parame ter-Names){this.parameterNames=parameterNames;}

      public String getBeanName(){return beanName;}

      public void setBeanName(String beanName){this.beanName=beanName;}

      public String getMethodName(){return methodName;}

      public Class<?>[]getParameterClass(){return parameterClass;}

      public void setParameterClass(Class<?>[]parameter-Class){this.parameterClass=parameterClass;}

      ....

      2.3 添加自定義注解掃描方法

      在程序啟動時,初始化階段掃描有上述自定義注解的類與方法,并將該方法的bean-Name、方法名稱methodName、參數(shù)類型parameterClass、參數(shù)名稱parameterNames、返回類型returnType等屬性存到BeanDefinition對象,與注解上code值一一映射,存入beanMap,核心代碼如下:

      @PostConstruct

      Public void init(){

      log.info(“開始初始化報表配置”);

      Map<String,Object>beanDefinitions=SpringContextUtils.getApplicationContext().getBeansWithAnnotation(ExportTblAnnotion.class);

      DefaultParameterNameDiscoverer dpnp=new DefaultParameterNameDiscoverer();

      ...

      BeanDefinition definition=new BeanDefinition();

      ...

      Constant.beanMap.put(code,definition);

      ...

      2.4 創(chuàng)建動態(tài)導出文件配置表

      (1)創(chuàng)建導出文件配置信息表(見圖1),用于存儲導出路徑、導出報表名稱,支持xls、xlsx和csv三種格式、導出報表編碼,該值和自定義注解的code值對應、導出方式,支持方法導出、SQL導出、直接導出三種方式。

      圖1 導出文件配置信息表

      ①方法導出方式僅需在導出文件所需數(shù)據(jù)的查詢方法上面添加自定義注解并配置報表編碼,舉例如下:

      //添加自定義注解

      @ExportAnnotation(code="ATLAS_TXN_DTL")

      @0verride

      public PageOutVo<BaseTxnV0> queryTxnDtl(AtlasTxnDtlInV0 inV0){

      PageOutVo<BaseTxnV0>outV0=new PageOutVo<>();

      If(StringUtils.isEmpty(inV0.getFrom())||String-Utils.isEmpty(inV0.getTarget())){

      return outV0;

      }

      StringBuilder sb=new StringBuilder();

      配置報表編碼(圖2)。

      圖2 配置報表編碼

      ②SQL導出方式僅需配置exp_sql,配置查詢數(shù)據(jù)的SQL語句即可,無需添加任何代碼。

      ③直接導出用于導出已生成的文件。

      (2)創(chuàng)建導出文件字段映射表(見圖3),用于存儲Excel表頭、標題、列寬、行高、填充值等屬性。顯示屬性SHOW_FLAG可以動態(tài)調整數(shù)據(jù)列的顯示狀態(tài),順序屬性DISPLAY_ORDER可以調整列的顯示順序。

      圖3 導出文件字段映射

      接上述例子,假設導出報表的表頭是序號、交易卡號、交易對方證件號等信息,表填充如圖4。

      圖4 導出報表填充信息

      以上兩個步驟即可完成動態(tài)導出文件的相關配置,相對于傳統(tǒng)實現(xiàn)方法的業(yè)務代碼和功能代碼耦合性高,且需求變化時會修改大量代碼,本方法僅通過配置的方式即可實現(xiàn),業(yè)務代碼和導出邏輯完全分離,移植性好。

      2.5 添加公共導出接口

      用戶通過前端頁面?zhèn)魅氪龑С鑫募膱蟊砭幋a值及查詢條件json串,即可根據(jù)上述配置信息表中的配置信息以及反射機制靈活導出多種格式文件,公共導出接口方法:

      @GetMapping("/export/data")

      @ApiOperation(“導出文件接口”)

      public ResponseEntity<Resource>exportData(String code,String condStr){

      log.info(“開始導出文件code="+code+";condStr=”+condStr);

      Map<String.Object>parm=new HashMap();

      parm.put(“code”,code);

      List<EpTblCfg> tblCfgList= jdbcTemplate.qury

      (“select*fromep_tbl_cfg where table_code=:code”,parm,new ObjRowMapper(EpTblCfg.class));

      if(CollectionUtils.isEmpty(tblCfglist)){

      throw new AmtRunExceptin(“未配置表格配置信息:”+code);

      }

      EpTblCfg tblCfg=tblCfgList.get(0);

      String expTpCd=StringUtils.isEmpty(tblCfg.getExp-Type())?Constant.EXP_TPCD.METHOD:

      tblCfg.getExpType();

      If(Constant.EXP_TPCD.METHOD.equals(exp TpCd)){

      Return reportByMethod(code,condStr);

      }else if(Constant.EXP_TPCD.FILE.equals(exp TpCd)){

      Return reportByFile(code,condStr);

      }else if(Constant.EXP_TPCD.SQL.equals(exp TpCd)){

      Return reportBySql(code,condStr);

      }else{Throw new AmtRunException(“導出類型配置錯誤”);

      }

      2.6 通過反射機制實現(xiàn)方法調用

      公共接口方法通過code值找到對應的beandefinition對象,通過反射進行查詢方法調用,獲取要導出的數(shù)據(jù)。

      ...

      BeanDefinition beanDefinition=Constant.beanMap.get(code);

      ...

      Object service=SpringContextUtils.getBean(beanDefinition.getBeanName());

      Method method=beanDefinition.getMethod();

      .....

      method.invoke(service,args,parameterClass)

      2.7 基于Fel動態(tài)導出實現(xiàn)

      將上述獲取到的待導出數(shù)據(jù)進行處理,通過2.4中所配置的文件字段信息及Fel表達式計算,動態(tài)生成表頭、標題及填充數(shù)據(jù)內容。for(EpFieldcfg cfg:columnCfg){

      Cell cell=bodyRow.createCell(bodyCellIdx++);

      cell.setCellStyle(bodyStyle);

      object result=null;

      if(StringUtils.isNotEmpty(cfg.getFieldData())){

      try{

      result=FelUtils.getExpressionResult(cfg.get-FieldData(),mct);

      }catch(Exception e){...}

      if(result==null){

      cell.setCellvalue(""′);

      }else{

      cell.setCellValue(result.toString());

      }

      3 結語

      本文實現(xiàn)了一種更加高效靈活的動態(tài)Excel文件導出方法。創(chuàng)新點有三處:①利用自定義注解及Java反射機制,使代碼更加簡潔,而且業(yè)務代碼和導出功能代碼是獨立的,減小耦合性;②導出功能還運用了Fel表達式計算引擎的特性,支持大數(shù)據(jù)高精度計算、千萬次每秒的執(zhí)行速度、而且輕量級易擴展,使Excel導出更具有靈活性、高效性和易擴展性;③導出方式有三種,支持方法導出、SQL導出、直接導出,導出報表支持xls、xlsx和csv三種格式。

      猜你喜歡
      表達式調用報表
      一個混合核Hilbert型積分不等式及其算子范數(shù)表達式
      表達式轉換及求值探析
      核電項目物項調用管理的應用研究
      淺析C語言運算符及表達式的教學誤區(qū)
      LabWindows/CVI下基于ActiveX技術的Excel調用
      測控技術(2018年5期)2018-12-09 09:04:46
      LabWindows/CVI中Excel報表技術研究
      測控技術(2018年8期)2018-11-25 07:42:28
      從三大報表讀懂養(yǎng)豬人的成績單
      基于系統(tǒng)調用的惡意軟件檢測技術研究
      利用RFC技術實現(xiàn)SAP系統(tǒng)接口通信
      議C語言中循環(huán)語句
      商(2012年11期)2012-07-09 19:07:55
      南漳县| 边坝县| 墨脱县| 泸定县| 清水县| 洪江市| 历史| 平江县| 鲜城| 津南区| 巴彦县| 贡嘎县| 水富县| 海伦市| 阿拉善盟| 高州市| 拜泉县| 渭南市| 辽中县| 卓资县| 凯里市| 灵宝市| 武宁县| 星子县| 绥芬河市| 绥棱县| 德庆县| 加查县| 文山县| 洞头县| 金山区| 聂荣县| 油尖旺区| 张家港市| 霍林郭勒市| 宝应县| 宁远县| 蓬安县| 潍坊市| 平江县| 乐清市|