1. 程式人生 > >POI之自定義註解生成文件-yellowcong

POI之自定義註解生成文件-yellowcong

到處資料如果是成條的,而且是批量處理的情況下,我們可以通過對資料模型使用註解,來解決這種問題。

這裡寫圖片描述

環境搭建

<!-- excel -->
    <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

<!-- word -->
<dependency>
    <groupId
>
org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.17</version> </dependency> <!-- xlsx --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version
>
3.17</version> </dependency> <!-- xlsx 依賴這個包 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency>

實現思路

在資料模型物件下,新增一個註解類,說明抽出的欄位在excel中所對應的表頭,然後通過工具類,通過反射,獲取每個欄位所對應的標題,同時設定每個欄位對應的資料

POI自定義註解類(HFFSAlias.java)

HFFSAlias.java這個註解類是基於file欄位的,用於說明欄位在xls中的中文名稱

package com.yellowcong.utils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * 通過註解來操作別名,判斷的是欄位上的別名
 * 通過這個註解類和我們的PoiUtils 可以很好的解決文件匯出的問題
 * 
 * @author yellowcong
 * @date 2016年1月7日
 */
@Target({ java.lang.annotation.ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface HFFSAlias{
    //設定別名,通過value 這個函式,就不需要寫引數了
    //@HFFSAlias("xx") 就可以了
    public String value() default "";
}

模型類物件(User.java)

這個模型物件,使用的是Hibernate的框架,通過Hibernate做ORM框架,我們只需要呼叫自定義的HFFSAlias.java這個annotation,就可以設定標題了

package com.yellowcong.model;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.annotations.Index;
import org.hibernate.validator.constraints.Email;

import com.yellowcong.utils.HFFSAlias;

/**
 * yellowcong 的新網站,以後也會一直建立下去
 *
 * @author yellowcong
 *
 * 
 * QQ
 * 新浪微博藉口
 * 微信介面  資料推送
 * github 介面
 * 
 * 
 * 使用者登入的 email 
 * 使用者登入的手機號
 * 使用者的名稱
 * 必須是唯一的
 * 
 * 
 * 網名和頭像隨機生成,如果使用者不填寫的情況下
 * 
 * 
 * 手機和email登入  
 * 三方登入   
 *    
 */
@Entity
@Table(name="ycg_user")
public class User {
    @HFFSAlias("編號")
    private int id;
    //使用者名稱稱
    @HFFSAlias("使用者名稱稱")
    private String username;
    //別名
    //別名不能存在郵箱@ 不然會導致問題,我們需要做js驗證
    @HFFSAlias("別名")
    private String nickname;
    //密碼
//  @HFFSAlias("密碼")
    private String password;
    //建立日期
    @HFFSAlias("建立日期")
    private Date createDate;
    //使用者頭像
    @HFFSAlias("使用者頭像")
    private String imgUrl;
    //使用者的郵箱地址
    @HFFSAlias("郵箱")
    private String email;
    //電話
    @HFFSAlias("電話號")
    private String phone;
    //是否郵箱啟用
    // 0 表示未啟用 
    // 1 表示啟用
    @HFFSAlias("是否啟用")
    private int isActive;

    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    //用於驗證使用者是否登入
    public User(int id) {
        super();
        this.id = id;
    }


    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Index(name="username")
    @Column(name="username",length=16)
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    //我們不需要設定我們的nickname 為唯一的
    @Index(name="nickname")
    @Column(name="nickname",length=16,unique=false)
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    @Column(length=32)
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    @Column(name="create_date")
    public Date getCreateDate() {
        return createDate;
    }
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @Column(name="img_url")
    public String getImgUrl() {
        return imgUrl;
    }
    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    @Email
    @Column(unique=true,length=64)
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    @Column(name="phone",length=11,unique=true)
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Column(name="is_active",length=1)
    public int getIsActive() {
        return isActive;
    }
    public void setIsActive(int isActive) {
        this.isActive = isActive;
    }

}

工具類

工具類中,主要可供使用的是將獲取的List<?>資料轉化為Excel文件,同時也可以 將轉化的Excel文件轉化為List<?>,這幾個方法都有一個特點,他們是有表頭,而且還有一點缺點,對於時間型別需要指定,不然有問題,同時逆向工程中,讀取的表的資料 少一行

package com.yellowcong.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

/**
 * 報表工具包,用來操作報表中的資料
 * @author yellowcong
 * @date 2016年1月6日
 * 依賴 poi-2.5.1.jar 
 * beanutil
 * 
 * 重要的方法
 * 建立xls檔案
 * 
 * 基於annotation
 * 類物件需要使用@HHFSAlias 註解 給欄位設定別名
 * createHSSFByAnnotation(List<?>) 
 * 
 * 自己配置好對映關係,然後傳 List<?>物件
 * createHSSF(LinkedHashMap<String, String>, List<?>)
 * 
 * 逆向生成 java物件
 * 類物件需要使用@HHFSAlias 註解 給欄位設定別名
 * reverseHSSFByAnnotation(File, Class<?>)
 * 
 * 對於文件直接使用,使用String[]來配置我們的 對映關係,boolena 設定是否有表頭
 * reverseHSSF(File, String[], Class<?>, boolean)
 * 
 * 對於有表頭的可以使用這個,也可以使用上一個,上一個的效率高一點
 * reverseHSSF(File, Map<String, String>, Class<?>)
 */
public class PoiUtils {
    private PoiUtils(){}


    /**
     * 將HSSFWorkbook 物件轉化為 檔案
     * @param wb  HSSFWorkbook 物件 
     * @param file 檔案
     */
    public static void copyHSSFToFile(HSSFWorkbook wb,File file){
        FileOutputStream  out = null;
        try {
            out = new FileOutputStream(file);
        } catch (Exception e) {
            // TODO: handle exception
        }finally{

            try {
                if(wb != null){
                    wb.write(out);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    if(out != null){
                        out.close();
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                }
            }
        }
    }

    /**
     * 獲取一個不帶有輸入流的HSSFWorkbook 物件
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(){
        return getHSSFWorkbook(null);
    }
    /**
     * 獲取我們的一個HSSFWorkbook
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(File file){
        HSSFWorkbook workbook= null;
        try {
                if(file != null){
                    workbook  = new HSSFWorkbook(new FileInputStream(file));
                }else{
                    workbook = new HSSFWorkbook();
                }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return workbook;
    }
    //判斷資料
    /**
     * 通過 結合註解,來生成我們的poi文件操作
     * 通過註解呼叫的時候,我們的類中必須要有註解寫出,如果沒有就建立不了
     * 需要結合@HFFSAlias 這個類
     * @param data 我們的資料集合
     * @return
     */
    public static HSSFWorkbook createHSSFByAnnotation(List<?> data) {
        LinkedHashMap<String, String> title = null;
        //獲取到我們的title資料
        if(data != null && data.size() >0){
            title = new LinkedHashMap<String, String>();
            /*Field [] fields = data.get(0).getClass().getDeclaredFields();
            for(Field field:fields){
                HFFSAlias alias = field.getAnnotation(HFFSAlias.class);
                if(alias != null){
                    title.put(field.getName(), alias.value());
                }
            }*/
            title = PoiUtils.getAnnotationAlias(data.get(0).getClass());
            //然後呼叫已經存在的方法來生成表
            return PoiUtils.createHSSF(title, data);
        }
        return null;
    }
    /**
     * 逆向生成,我們需要的資料,將xls中的資料轉化為字串資料
     * @param clazz 對映的類物件
     * @param file xls檔案物件
     * @return
     */
    public static List<?> reverseHSSFByAnnotation(File file,Class<?> clazz ){
        //獲取field中的資訊
        return PoiUtils.reverseHSSF(file, PoiUtils.getAnnotationAlias(clazz), clazz);       
    }

    /**
     * 通過clazz 來獲取到裡面的title資料
     * @param clazz
     * @return
     */
    public static LinkedHashMap<String,String> getAnnotationAlias(Class<?> clazz){
        Field []  fields = clazz.getDeclaredFields();
        LinkedHashMap<String,String> title = new LinkedHashMap<String, String>();
        for(Field field:fields){
            HFFSAlias alias = field.getAnnotation(HFFSAlias.class);
            if(alias != null){
                title.put(field.getName(), alias.value());
            }
        }
        return title;
    }
    /**
     * 沒有行標題的資料,需要通過這種方法來確定資料
     * 這個方法使用起來 比通過Map 更加的簡便
     * @param file  逆向工程的xls檔案愛你
     * @param title  這個 需要設定 對映關係,而且順序不能錯
     * @param clazz   對映的類物件
     * @param hasHead  是否包含表頭,有表頭的資料就 需要從1 開始
     * @return
     */
    public static List<?> reverseHSSF(File file,String[] title,Class<?> clazz ,boolean hasHead){
        try {
            //建立work
            HSSFWorkbook work = PoiUtils.getHSSFWorkbook(file);
            //獲取第一頁
            HSSFSheet sheet = work.getSheetAt(0);
            //row是從0開始的,獲取列和行的數目
            HSSFRow row =  sheet.getRow(0);
            List list =null;
            List<String> dateFields = null;
            int rownum = sheet.getLastRowNum();
            int cellnum = row.getLastCellNum();
//          System.out.println(rownum);
            String [] ids = title;

            if(rownum >0 && cellnum >0){
                list = new ArrayList();
                dateFields = PoiUtils.getDataTimeFiled(clazz);
                //遍歷別的資料,、第一行資料 是需要的
                int start = 0;
                if(hasHead){
                    start = 1;
                }
                for(int i=start;i<rownum;i++){
                    row = sheet.getRow(i);
                    //例項化物件
                    Object obj = clazz.newInstance();
                    //設定屬性
                    for(int j=0;j<cellnum;j++){
                        HSSFCell cell = row.getCell((short)j);
                        String result ="";
                        //當時數字型別的資料,不可以轉化
                        if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
                            result = cell.getNumericCellValue()+"";
                        }else{
                            result =cell.getStringCellValue();
                        }

                        //日期型別的資料不好注入,需要判斷,和設定資料的型別
                        if(dateFields.contains(ids[j])){
                            BeanUtils.setProperty(obj, ids[j], new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(result));
                        }else{
                            BeanUtils.setProperty(obj, ids[j], result);
                        }
                    }
                    list.add(obj);
                }
            }
            return list;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 通過配置的方法來生成逆向工程
     * 給定檔案,將物件轉化為類
     * 設定中,sheeet 就一頁
     * @param file  xls檔名稱
     * @param title 標題,表頭關係
     * @param clazz 類物件
     * @return
     */
    public static List<?> reverseHSSF(File file,Map<String,String> title,Class<?> clazz ){
        try {
            //建立work
            HSSFWorkbook work = PoiUtils.getHSSFWorkbook(file);
            //獲取第一頁
            HSSFSheet sheet = work.getSheetAt(0);
            //row是從0開始的,獲取列和行的數目
            HSSFRow row =  sheet.getRow(0);
            List list =null;
            List<String> dateFields = null;
            int rownum = sheet.getLastRowNum();
            int cellnum = row.getLastCellNum();
//          System.out.println(rownum);
            String [] ids = new String[cellnum];

            if(rownum >0 && cellnum >0){
                title = PoiUtils.reverseMap(title);
                list = new ArrayList();
                dateFields = PoiUtils.getDataTimeFiled(clazz);
                //這個可以 提取為 獲取第一行資料的資訊
                //獲取地一行,標題行  獲取標題對應資訊
                for(int j=0;j<cellnum;j++){
                    HSSFCell cell = row.getCell((short)j);
                    String result = "";
                    //當時數字型別的資料,不可以轉化
                    if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
//                  ids[j]= title.containsValue(value);
                        result = cell.getNumericCellValue()+"";
                    }else{
                        result = cell.getStringCellValue();
                    }
                    //獲取的資料進行注入操作

                    //需要反轉map集合
                    if(title != null && result != null){
                        if(!title.containsKey(result)){
                            throw new RuntimeException("內容不匹配");
                        }
                        ids[j] = title.get(result);
                    }
                }

                //遍歷別的資料
                for(int i=1;i<rownum;i++){
                    row = sheet.getRow(i);
                    //例項化物件
                    Object obj = clazz.newInstance();
                    //設定屬性
                    for(int j=0;j<cellnum;j++){
                        HSSFCell cell = row.getCell((short)j);
                        String result ="";
                        //當時數字型別的資料,不可以轉化
                        if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
                            result = cell.getNumericCellValue()+"";
                        }else{
                            result =cell.getStringCellValue();
                        }

                        //日期型別的資料不好注入,需要判斷,和設定資料的型別
                        if(dateFields.contains(ids[j])){
                            BeanUtils.setProperty(obj, ids[j], new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(result));
                        }else{
                            BeanUtils.setProperty(obj, ids[j], result);
                        }
                    }
                    list.add(obj);
                }
            }
            return list;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通過給定類,來獲取到日期型別的欄位
     * 解決日期型別 注入不進去的問題
     * @param clazz
     * @return
     */
    public static List<String> getDataTimeFiled(Class<?> clazz){
        Field [] fields = clazz.getDeclaredFields();
        List<String> fieldNames = new ArrayList<String>();
        for(Field  field :fields){
            if(field.getType().getSimpleName().equals("Date")){
                fieldNames.add(field.getName());        
            }
        }
        return  fieldNames;
    }
    /**
     * 建立我們的HSSFwork 通過配置別名屬性
     * @param tiles 文件的title         Map<屬性名稱, 別名>
     * @param date List<?> 是一個集合的資料
     * @return 
     */
    public static HSSFWorkbook createHSSF(LinkedHashMap<String, String> title,List<?> data) {
        try {
            //一個漢字的寬度是 500
            //英文260 
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet();

            //獲取字元的長度
//      sheet.setColumnGroupCollapsed(columnNumber, collapsed);
//          sheet.setColumnWidth(column, width);
            //寫title中的資料
            if(title!= null && title.size() >0){
                //建立樣式
                HSSFCellStyle style = PoiUtils.getHeadStyle(workbook);
                int index = 0;
                HSSFRow row = sheet.createRow(0);
                //獲取寬度
                Map<String, Short> columns = PoiUtils.getColumnWidth(title, data);
                //獲取資料
                for(Map.Entry<String, String> entry:title.entrySet()){
                    String val = entry.getValue();
                    HSSFCell cell = row.createCell((short)index);
                    //設定單元格的型別
                    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                    //設定編碼格式
                    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                    //設定樣式 
                    cell.setCellStyle(style);
                    cell.setCellValue(val);
                    sheet.setColumnWidth((short)index, columns.get(entry.getKey()));
                    index++;
                }

                //建立樣式
                style = PoiUtils.getBodyStyle(workbook);
                //設定資料
                if(data != null && data.size() >0){
                    //獲取我們的 data中的資料
                    //內容從第二行開始
                    int rownum =1;
                    for(Object obj:data){
                        row = sheet.createRow(rownum);
                        //列從第一行開始
                        int colnum = 0;
                        for(Map.Entry<String, String> entry:title.entrySet()){
                            String key = entry.getKey();
                            //獲取裝的物件資料
                            String val = BeanUtils.getProperty(obj, key);
                            if(val == null || "".equals(val.trim())){
                                val = "-";
                            }
                            HSSFCell cell  = row.createCell((short)colnum);
                            //設定單元格的型別
                            cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                            //設定編碼格式
                            cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                            //設定樣式 
                            cell.setCellStyle(style);
                            cell.setCellValue(val);
                            //增加列
                            colnum ++;
                        }
                        rownum ++;
                    }
                }
            }

            return workbook;
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 計算每個資料列的最適合的寬度
     * 通過資料來獲取到我們的資料的寬度
     * @param title 資料標題
     * @param data 資料幾何
     * @return 
     */
    public static Map<String, Short> getColumnWidth(Map<String, String> title,List<?> data){
        try {
            //儲存我們的每個屬性的寬度
            //Map<屬性明,寬度>
            Map<String,Short> map = new HashMap<String, Short>();

            if(title!= null && title.size() >0){
                //計算我們的第一行的寬度
                for(Map.Entry<String, String> entry:title.entrySet()){
                    int max = PoiUtils.countColumnLength(entry.getValue());

                    //計算下面的所有 同一欄位的長度
                    for(Object obj:data){
                        String val = BeanUtils.getProperty(obj, entry.getKey());
                        int temp = PoiUtils.countColumnLength(val);
                        max = max >temp?max:temp;
                    }
                    //設定欄位的值
                    map.put(entry.getKey(), (short)max);
                }
            }
            return map;
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * 根據字元的數量,來計算列的寬度
     * 不同的資料他的資料長度是不一樣的,所以我們需要計算總體的長度
     * @param str 字串
     * @return int 計算出列寬
     * 
     */
    private static int countColumnLength(String str){
        int len =0;
        if(str != null && !"".equals(str.trim())){
            //一個漢字的寬度是 500
            //英文260
            char [] chars = str.toCharArray();
            //z
            int chines = 0;
            int other =0;
            for(char val:chars){
                if(PoiUtils.isChineseChar(val)){
                    chines ++;
                }else{
                    other++;
                }
            }
            //獲取到了資料然後計算長度
            len = chines*500+other*260+1000;
        }
        return len;
    }
    /**
     * 建立樣式
     * @return 
     */
    public static HSSFCellStyle getHeadStyle(HSSFWorkbook workbook){
        HSSFCellStyle  style = workbook.createCellStyle();
        //居中顯示
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setFont(PoiUtils.getSongRed10(workbook));
        return style;
    }

    /**
     * 建立樣式
     * @return 
     */
    public static HSSFCellStyle getBodyStyle(HSSFWorkbook workbook){
        HSSFCellStyle  style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setFont(PoiUtils.getSong10(workbook));
        return style;
    }



    /**
     * 建立字型
     * @param fontFamly 字型 
     * @param size 大小 字號 14  13
     * @param color  HSSFColor.BLACK.index 這個HSSFColor中 的資料
     * @param isBold 是否加粗 操作
     * @return 
     */
    //字號 是14號 -->對應的short 280寬度 是 14好字型
    public static HSSFFont creatFont(HSSFWorkbook workbook,String fontFamly,Integer size,Short color,boolean isBold){
        HSSFFont font = workbook.createFont();
        //字號 是14號 -->對應的short 寬度 是 14好字型
        font.setFontHeight((short)((size== null  || size ==0 )?280:size*20));
        font.setBoldweight(isBold?HSSFFont.BOLDWEIGHT_BOLD:HSSFFont.BOLDWEIGHT_NORMAL);
        //將字型顏色變紅色
//      short colors = HSSFColor.RED.index;
        font.setColor(color== null?HSSFColor.BLACK.index:color);
        return font;
    }


    /**
     * 判斷我們的資料 中,是否有中文字元
     * @param str
     * @return
     */
    public static boolean isChineseChar(char str){
        boolean flag = false;
        Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]");
        if(pattern.matcher(str+"").find()){
            flag = true;
        }
        return flag;
    }

    /**
     * 得到宋體10 號 黑色
     * 預設字型的大小就是10 號 
     * @return
     */
    public static HSSFFont getSong10(HSSFWorkbook workbook){
        return creatFont(workbook,"宋體", 10, null,false);
    }

    /**
     * 得到宋體10 號  紅色加粗
     * @return
     */
    public static HSSFFont getSongRed10(HSSFWorkbook workbook){
        return creatFont(workbook,"宋體", 10, HSSFColor.RED.index,true);
    }

    /**
     * 將Map
     * @param map
     * @return
     */
    public static Map<String,String> reverseMap(Map<String,String> map){
        Map<String,String> newMap = null;
        //將便利的結果重新裝填一下
        if(map != null  && map.size() >0){
            newMap = new LinkedHashMap<String, String>();
            for(Map.Entry<String, String> entry:map.entrySet()){
                newMap.put(entry.getValue(), entry.getKey());
            }
        }
        return newMap;
    }
}

測試類

主要測試了,自己手動編寫表頭和自動配置生成表頭兩種方法,同時還測試了Excel轉List資料

package com.yellowcong.test;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.yellowcong.model.Pager;
import com.yellowcong.model.SystemContext;
import com.yellowcong.model.User;
import com.yellowcong.service.UserService;
import com.yellowcong.utils.HFFSAlias;
import com.yellowcong.utils.PoiUtils;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:ApplicationContext.xml")
public class UserServiceTest {

    private UserService userService;

    @Resource(name="userService")
    public void setUserService(UserService userService) {
        this.userService = userService;
    }


    @Test
    public void testList(){
        List<User> users= userService.listByPager().getData();
        //可以做成annotation的
        Map<String,String> map = new HashMap<String, String>();
        map.put("id", "編號");
        map.put("username", "使用者名稱");
        map.put("nickname", "別名");
        map.put("password", "密碼");
        map.put("createDate", "建立日期");
        map.put("imgUrl", "頭像路徑");
        map.put("email", "郵箱");
        map.put("phone", "電話");
        map.put("isActive", "是否啟用");

        HSSFWorkbook work = PoiUtils.createHSSF(map, users);
        PoiUtils.copyHSSFToFile(work, new File("D:/users.xls"));
    }

    @Test
    public void testList2Anotation(){
        List<User> users= userService.listByPager().getData();
        HSSFWorkbook work = PoiUtils.createHSSFByAnnotation(users);
        PoiUtils.copyHSSFToFile(work, new File("D:/users.xls"));
    }

}

測試結果

這裡寫圖片描述