ExcelUtil-註解-SXSSFWorkbook

/**
 * 註解用於Excel
 * Created by tangCL on 2016/9/8.
 */
@Retention(RetentionPolicy.RUNTIME)/*運行時有效*/
@Target(ElementType.FIELD)/*範圍*/
public @interface ExcelAttribute {

    /**
     * Excel中的列名
     *
     * @return
     */
    public abstract String name();

    /**
     * 列名對應的A,B,C,D...,不指定按照默認順序排序
     *
     * @return
     */
    public abstract String column() default "";

    /**
     * 提示信息
     *
     * @return
     */
    public abstract String prompt() default "";

    /**
     * 設置只能選擇不能輸入的列內容
     *
     * @return
     */
    public abstract String[] combo() default {};

    /**
     * 是否導出數據
     *
     * @return
     */
    public abstract boolean isExport() default true;

}

----------------------------------------------------------------------------------------------------------------
/**
 * Created by tangCL on 2016/9/8.
 */
public class ExcelTestVO {
    @ExcelAttribute(name="ID",isExport=true)
    private Integer id;
    @ExcelAttribute(name="姓名",isExport=true)
    private String name;
    @ExcelAttribute(name="電話",isExport=true)
    private String phone;
    @ExcelAttribute(name="年齡",isExport=true)
    private Integer age;
    @ExcelAttribute(name="備註")
    private String remark;

//get,set
}

----------------------------------------------------------------------------------------------------------------
/**
 * 採用的是POI3.8以上的SXSSFWorkbook  excel版本在2007以上
 * Created by tangCL on 2016/9/8.
 */
public class ExcelUtil<T> implements Serializable {

    private static final Logger logger = LoggerFactory.getLogger(ExcelUtil.class);

    public final static int sheetSize = 2;
    public final static int diskSize = 100000;

    /**
     * 獲取相應的類
     */
    private Class<T> clazz;
    public ExcelUtil(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     *
     * @param resultList 將寫入EXCEL的數據
     * @param sheetName 工作表名字
     * @param outputStream 輸出流
     * @return
     */
    public boolean writeExcelFromList(List<T> resultList, String sheetName, OutputStream outputStream){
        //返回標示
        Boolean sign = Boolean.TRUE;
        try{
            // 得到所有定義字段
            Field[] allFields = clazz.getDeclaredFields();
            List<Field> fields = new ArrayList<Field>();
            // 得到所有field並存放到一個list中
            for (Field field : allFields) {
                if (field.isAnnotationPresent(ExcelAttribute.class)) {
                    fields.add(field);
                }
            }
            // 產生工作薄對象
            Workbook workbook = new SXSSFWorkbook(diskSize);

            //數據源數量
            int listSize = 0;
            if (resultList != null && resultList.size() >= 0) {
                listSize = resultList.size();
            }
            //工作簿頁數
            double sheetNo = Math.ceil(listSize / sheetSize);

            for(int i = 0 ; i <= sheetNo ; i++){
                //創建工作簿
                Sheet sheet = workbook.createSheet();
                //設置工作表的名稱
                workbook.setSheetName(i,sheetName+""+i);
                //創建
                Row row;
                Cell cell;
                //創建第一行
                row = sheet.createRow(0);
                for(int cellNum = 0 ; cellNum < fields.size() ; cellNum++){
                    //
                    Field field = fields.get(cellNum);
                    //獲取註解信息
                    ExcelAttribute attr = field.getAnnotation(ExcelAttribute.class);
                    int col = cellNum;
                    // 根據指定的順序獲得列號
                    if (StringUtils.isNotBlank(attr.column())) {
                        col = getExcelCol(attr.column());
                    }
                    // 創建列
                    cell = row.createCell(col);

                    sheet.setColumnWidth(i, (int) ((attr.name().getBytes().length <= 4 ? 6 : attr.name().getBytes().length) * 1.5 * 256));

                    // 設置列中寫入內容爲String類型
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    // 寫入列名
                    cell.setCellValue(attr.name());
                    /*
                    // 如果設置了提示信息則鼠標放上去提示.
                    if (StringUtils.isNotBlank(attr.prompt())) {
                        setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, col, col);
                    }
                    // 如果設置了combo屬性則本列只能選擇不能輸入
                    if (attr.combo().length > 0) {
                        setHSSFValidation(sheet, attr.combo(), 1, 100, col, col);
                    }
                    */
                }

                //創建內容列
                int startNo = i * sheetSize;
                int endNo = Math.min(startNo + sheetSize, listSize);
                for(int j = startNo; j < endNo; j++){
                    row = sheet.createRow(j + 1 - startNo);
                    // 得到導出對象.
                    T vo = (T) resultList.get(j);
                    for(int k = 0 ; k < fields.size() ; k++){
                        // 獲得field
                        Field field = fields.get(k);
                        // 設置實體類私有屬性可訪問
                        field.setAccessible(true);
                        ExcelAttribute attr = field.getAnnotation(ExcelAttribute.class);
                        int col = k;
                        // 根據指定的順序獲得列號
                        if (StringUtils.isNotBlank(attr.column())) {
                            col = getExcelCol(attr.column());
                        }

                        cell = row.createCell(col);
                        // 如果數據存在就填入,不存在填入空格
                        Class<?> classType = (Class<?>) field.getType();
                        String value = null;
                        if (field.get(vo) != null && classType.isAssignableFrom(Date.class)) {
                            SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                            value = DateUtils.formatDate(sdf.parse(String.valueOf(field.get(vo))));
                        }
                        cell.setCellValue(field.get(vo) == null ? "" : value == null ? String.valueOf(field.get(vo)) : value);

                    }
                }

            }
            outputStream.flush();
            workbook.write(outputStream);
            outputStream.close();
        }catch (Exception e){
            logger.warn("Excel writeExcelFromList Exception" + e);
        }finally {
            return sign;
        }
    }


    /**
     * 將EXCEL中A,B,C,D,E列映射成0,1,2,3
     *
     * @param col
     */
    public static int getExcelCol(String col) {
        col = col.toUpperCase();
        // 從-1開始計算,字母重1開始運算。這種總數下來算數正好相同。
        int count = -1;
        char[] cs = col.toCharArray();
        for (int i = 0; i < cs.length; i++) {
            count += (cs[i] - 64) * Math.pow(26, cs.length - 1 - i);
        }
        return count;
    }

}


----------------------------------------------------------------------------------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章