<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java高級(jí)特性-注解:注解實(shí)現(xiàn)Excel導(dǎo)出功能

          共 5175字,需瀏覽 11分鐘

           ·

          2020-12-04 19:38

          作者:JerryWu
          來源:SegmentFault 思否社區(qū)



          注解是 Java 的一個(gè)高級(jí)特性,Spring 更是以注解為基礎(chǔ),發(fā)展出一套“注解驅(qū)動(dòng)編程”。


          這聽起來高大上,但畢竟是框架的事,我們也能用好注解嗎?


          的確,我們很少有機(jī)會(huì)自己寫注解,導(dǎo)致我們搞不清楚注解是怎么回事,更別提用好注解了。


          既然這樣,我們就從具體的工作出發(fā),開發(fā)一個(gè) Excel 導(dǎo)出功能。我相信,你在搞懂這個(gè)例子后,就能明白注解是怎么個(gè)用法。




          Excel 導(dǎo)出-需求拆解


          在后臺(tái)管理系統(tǒng)中,常常需要把數(shù)據(jù)導(dǎo)出 Excel 表。


          比如,在雙十一過后,銷售部要把商品訂單錄入到 Excel 表,財(cái)務(wù)部要把支付訂單錄入到 Excel 表,然后各部門匯總分析,最后找個(gè)時(shí)間討論怎么改善公司的服務(wù)。


          你想呀,雙十一的訂單成千上萬,靠人工錄入,少說也要花三四天,而且還特別容易出錯(cuò)。所以,你必須開發(fā) Excel 導(dǎo)出功能。


          那么,具體怎么做呢?


          上次我們提到,注解想發(fā)揮作用,有三個(gè)要素:定義、使用、讀取。這次,我們就利用注解的三個(gè)特性,來實(shí)現(xiàn) Excel 導(dǎo)出功能,設(shè)計(jì)過程是這樣的。


          • 第一步,我們要?jiǎng)?chuàng)建不同的 Excel 模型。雙十一過后,銷售部要訂單數(shù)據(jù),財(cái)務(wù)部要支付數(shù)據(jù),兩個(gè)部門要的 Excel 表肯定也不一樣,這就得幫每個(gè)部門創(chuàng)建不同的 Excel 模型,他們拿到想要的數(shù)據(jù)。

          • 第二步,我們要根據(jù) Excel 模型,來導(dǎo)出 Excel 表。


          看到這,你應(yīng)該明白 Excel 導(dǎo)出的設(shè)計(jì)過程了。接下來,我們就來一步步實(shí)現(xiàn)這個(gè)功能。




          創(chuàng)建 Excel 模型


          創(chuàng)建 Excel 模型,涉及到注解三要素中的定義、使用。


          首先,定義 Excel 注解,我們直接看關(guān)鍵代碼。


          @Target({ElementType.FIELD})
          @Retention(RetentionPolicy.RUNTIME)
          public?@interface?ExcelField?{

          ????/**
          ?????*?導(dǎo)出字段標(biāo)題
          ?????*/
          ????String?title();
          ????
          ????/**
          ?????*?導(dǎo)出字段排序(升序)
          ?????*/
          ????int?sort()?default?0;
          ????
          ????/**
          ?????*?對(duì)齊方式(0:自動(dòng);1:靠左;2:居中;3:靠右)
          ?????*/
          ????int?align()?default?0;????

          }


          這里用到了兩個(gè)元注解@Retention和@Target。@Target代表這個(gè)注解只能放在成員變量上;@Retention代表這個(gè)注解要加載到 JVM 內(nèi)存,我們可以用反射來讀取注解。


          此外,注解還有 3 個(gè)成員變量,分別對(duì)應(yīng):Excel 的字段標(biāo)題、字段排序、對(duì)齊方式,方便大家微調(diào)表格。到了這,定義 Excel 注解就完成了。


          接下來,使用注解,我們還是直接看代碼。


          public?class?OrderModel?{
          ????@ExcelField(title?=?"訂單號(hào)",?align?=?2,?sort?=?20)
          ????private?String?orderNo;

          ????@ExcelField(title?=?"金額",?align?=?2,?sort?=?20)
          ????private?String?amount;
          ????
          ????//?創(chuàng)建時(shí)間
          ????private?Date?createTime;
          ????
          ????//?省略?getter/setter?方法
          }


          訂單模型有 3 個(gè)字段:訂單號(hào)、金額、創(chuàng)建時(shí)間,但這里注解只加到訂單號(hào)、金額上,表示這兩個(gè)字段會(huì)導(dǎo)出 Excel 表,而創(chuàng)建時(shí)間會(huì)忽略,你可以看看這副圖片。



          至此,我們完成了定義注解、使用注解,得到了一個(gè) Excel 模型。但要想實(shí)現(xiàn)導(dǎo)出功能,還必須根據(jù)這個(gè)模型,生成出 Excel 表。




          讀取 Excel 模型


          讀取 Excel 模型,涉及到注解三要素中的讀取。?我們需要讀取注解,生成 Excel 表,這主要分成 3 個(gè)步驟:初始化 Excel 表對(duì)象—>寫入數(shù)據(jù)到 Excel 表對(duì)象—>輸出文件。


          第一步,初始化 Excel 表對(duì)象。在這一步中,我們要根據(jù) Excel 模型,生成一個(gè) Excel 表對(duì)象,要?jiǎng)?chuàng)建這幾個(gè)東西:標(biāo)題、表頭、樣式等等。我們來看代碼。


          public?class?ExcelExporter?{

          ????//?...省略無數(shù)代碼

          ????/*****************************?初始化?Excel?表對(duì)象?****************************/
          ????/**
          ?????*?構(gòu)造函數(shù)
          ?????*?@param?title?表格標(biāo)題,傳“空值”,表示無標(biāo)題
          ?????*?@param?cls???excel模型對(duì)象
          ?????*/
          ????public?ExcelExporter(String?title,?Class?cls)?{
          ????????//?獲取注解list
          ????????Field[]?fs?=?cls.getDeclaredFields();
          ????????for?(Field?f?:?fs)?{
          ????????????ExcelField?ef?=?f.getAnnotation(ExcelField.class);
          ????????????if?(ef?!=?null)?{
          ????????????????annotationList.add(new?Object[]{ef,?f});
          ????????????}
          ????????}
          ????????annotationList.sort(comparing(o?->?((ExcelField)?o[0]).sort()));
          ????????//?通過注解獲取表頭
          ????????List?headerList?=?new?ArrayList<>();
          ????????for?(Object[]?os?:?annotationList)?{
          ????????????String?t?=?((ExcelField)?os[0]).title();
          ????????????headerList.add(t);
          ????????}
          ????????//?初始化excel表:創(chuàng)建excel表、添加表標(biāo)題、創(chuàng)建表頭等等
          ????????initialize(title,?headerList);
          ????}
          }


          在初始化的時(shí)候,我們先從 Excel 模型對(duì)象中讀取注解,獲得一個(gè)注解列表;然后,再從注解列表中,讀取 title-字段標(biāo)題;最后,再初始化 Excel 表對(duì)象,包括:創(chuàng)建 Excel 表對(duì)象、添加表標(biāo)題、創(chuàng)建表頭、添加樣式。


          第二步,寫入數(shù)據(jù)到 Excel 表對(duì)象。在這一步中,我們要把 Java 的列表數(shù)據(jù)寫到 Excel 表對(duì)象里,讓這些數(shù)據(jù)能變成 Excel 表的一行行信息。還是來看代碼。


          public?class?ExcelExporter?{

          ????/*****************************?初始化?Excel?表對(duì)象?****************************/
          ????//?...省略無數(shù)代碼

          ????/*****************************?寫入數(shù)據(jù)到?Excel?表對(duì)象?****************************/
          ????/**
          ?????*?寫入數(shù)據(jù)
          ?????*?@return?list?數(shù)據(jù)列表
          ?????*/
          ????public??ExcelExporter?setDataList(List?list)?{
          ????????for?(E?dataObj?:?list)?{
          ????????????//?添加行
          ????????????Row?row?=?this.addRow();

          ????????????//?獲取數(shù)據(jù),并寫入單元格
          ????????????int?cellNo?=?0;
          ????????????for?(Object[]?os?:?annotationList)?{
          ????????????????//?獲取成員變量的值
          ????????????????Object?value?=?null;
          ????????????????try?{
          ????????????????????value?=?Reflections.invokeGetter(dataObj,?((Field)?os[1]).getName());
          ????????????????}?catch?(Exception?ex)?{
          ????????????????????log.info(ex.toString());
          ????????????????????value?=?"";
          ????????????????}
          ????????????????if?(value?==?null)?{
          ????????????????????value?=?"";
          ????????????????}

          ????????????????//?寫入單元格
          ????????????????ExcelField?ef?=?(ExcelField)?os[0];
          ????????????????this.addCell(row,?cellNo++,?value,?ef.align());
          ????????????}
          ????????}
          ????????return?this;
          ????}
          }


          我們先傳入一個(gè)數(shù)據(jù)列表 dataList,然后用循環(huán)來遍歷 dataList,在這個(gè)循環(huán)中,我們不斷把數(shù)據(jù)寫進(jìn) Excel 表對(duì)象里,具體操作是:創(chuàng)建了一個(gè)空白行,利用注解獲取成員變量里的值,最后寫進(jìn) Excel 表的單元格里。


          第三步,輸出文件。在這一步中,就是 Excel 表對(duì)象變成一個(gè)文件,來看下最后的代碼吧。


          public?class?ExcelExporter?{

          ????/*****************************?初始化?Excel?表對(duì)象?****************************/
          ????//?...省略無數(shù)代碼

          ????/*****************************?寫入數(shù)據(jù)到?Excel?表對(duì)象?****************************/
          ????//?...省略無數(shù)代碼

          ????/*****************************?輸出相關(guān)?****************************/
          ????/**
          ?????*?輸出到文件
          ?????*?@param?fileName?輸出文件名,加上絕對(duì)路徑
          ?????*/
          ????public?ExcelExporter?writeFile(String?fileName)?throws?IOException?{
          ????????FileOutputStream?os?=?new?FileOutputStream(fileName);
          ????????this.write(os);
          ????????return?this;
          ????}
          }


          輸出文件就沒什么好說的了,就是指定文件名,然后把文件輸出到指定的地方。


          到了這,讀取 Excel 模型就完成了。


          當(dāng)然,讀取 Excel 模型涉及到注解的讀取,這是最難理解的地方,因?yàn)樽x取注解要用到 Java 另一個(gè)高級(jí)特性—反射。而且,注解一般是用來簡化業(yè)務(wù),如果你對(duì)業(yè)務(wù)沒有深刻的了解,是很難用好的。


          限于篇幅,我只講了最核心的代碼,項(xiàng)目的完整代碼放在文末的鏈接上,大家可以好好看看。




          寫在最后


          注解想發(fā)揮作用,有三個(gè)要素:定義、使用、讀取。這篇文章利用了注解的三要素,實(shí)現(xiàn)了 Excel 導(dǎo)出功能。


          這分成兩步。第一步,創(chuàng)建 Excel 模型,這涉及到注解三要素中的定義、使用;第二步,讀取 Excel 模型,這涉及到注解三要素中的讀取。


          總之,注解一般用來簡化業(yè)務(wù),你要想用好注解,不但得熟練掌握 Java 的高級(jí)用法,還得對(duì)業(yè)務(wù)有深刻的理解。


          文章演示代碼:復(fù)制鏈接跳轉(zhuǎn)

          https://gitee.com/jiarupc/excel-export




          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開更多互動(dòng)和交流。

          -?END -

          瀏覽 106
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  密桃成人无码 | 久久伊人青青草 | 无码一区免费 | 国产精品―色哟呦 | 中文字幕在线观看网 |