170313、poi:采用自定義注解的方式導入、導出excel(這種方式比較好擴展)


步驟一、自定義注解

步驟二、寫Excel泛型工具類

步驟三、在需要導出excel的類屬相上加上自定義注解,並設置

步驟四、寫service,controller

步驟一:自定義注解

import java.lang.annotation.Retention;  

import java.lang.annotation.RetentionPolicy;  

import java.lang.annotation.Target;  

@Retention(RetentionPolicy.RUNTIME)  

@Target({java.lang.annotation.ElementType.FIELD})  

public @interface ExcelField {  

    /** 

     * 導出到Excel中的名字. 

     */  

    public abstract String name();  

 

    /** 

     * 配置列的名稱,對應A,B,C,D.... 

     */  

    public abstract String column();  

 

    /** 

     * 提示信息 

     */  

    public abstract String prompt() default "";  

 

    /** 

     * 設置只能選擇不能輸入的列內容. 

     */  

    public abstract String[] combo() default {};  

 

    /** 

     * 是否導出數據

     */  

    public abstract boolean isExport() default true;  

步驟二、excel泛型工具類

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.apache.poi.hssf.usermodel.DVConstraint;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import org.apache.poi.hssf.usermodel.HSSFDataValidation;

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;

import org.apache.poi.ss.util.CellRangeAddressList;

 

/**

 * 導出excel的工具類

 * 全部采用string類型,如果需要加入其它類型需要修改工具方法  

 */

public class ExcelUtil<T> {  

    Class<T> clazz;  

    public ExcelUtil(Class<T> clazz) {  

        this.clazz = clazz;  

    }  

    /**

     * 批量導入

     * 這里的批量導入指的是一個excel文件中有多個相同類型的sheet頁

     */

    public List<T> importBatch(InputStream input) throws Exception {

     List<T> newList = new ArrayList<T>();

HSSFWorkbook workbook=new HSSFWorkbook(input);

if(null != workbook){

int sheets = workbook.getNumberOfSheets();

if(sheets>0){

for(int i=0;i<sheets;i++){

HSSFSheet sheet = workbook.getSheetAt(i);

if(null != sheet){

List<T> importProcessor = importProcessor(sheet);

newList.addAll(importProcessor);

}

}

}

}

return newList;

    }

    /**

     * 指定sheet頁導入,如果不指定默認會選第一個sheet

     */

    public List<T> importExcel(String sheetName, InputStream input) throws Exception {  

        HSSFWorkbook workbook = new HSSFWorkbook(input);  

        HSSFSheet sheet = workbook.getSheet(sheetName);  

        if (!sheetName.trim().equals("")) {  

            sheet = workbook.getSheet(sheetName);// 如果指定sheet名,則取指定sheet中的內容.  

        }  

        if (sheet == null) {  

            sheet = workbook.getSheetAt(0); // 如果傳入的sheet名不存在則默認指向第1個sheet.  

        }  

        return importProcessor(sheet);

    }  

    /**

     * 具體處理導入

     */

    private List<T> importProcessor(HSSFSheet sheet) throws Exception {  

     int maxCol = 0;  

     List<T> list = new ArrayList<T>();  

int rows = sheet.getPhysicalNumberOfRows();  

if (rows > 0) {// 有數據時才處理  

// Field[] allFields = clazz.getDeclaredFields();// 得到類的所有field.  

List<Field> allFields = getMappedFiled(clazz, null);  

 

Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();// 定義一個map用於存放列的序號和field.  

for (Field field : allFields) {  

// 將有注解的field存放到map中.  

if (field.isAnnotationPresent(ExcelField.class)) {  

ExcelField attr = field  

.getAnnotation(ExcelField.class);  

int col = getExcelCol(attr.column());// 獲得列號  

maxCol = Math.max(col, maxCol);  

// System.out.println(col + "====" + field.getName());  

field.setAccessible(true);// 設置類的私有字段屬性可訪問.  

fieldsMap.put(col, field);  

}  

}  

for (int i = 1; i < rows; i++) {// 從第2行開始取數據,默認第一行是表頭.  

HSSFRow row = sheet.getRow(i);  

// int cellNum = row.getPhysicalNumberOfCells();  

// int cellNum = row.getLastCellNum();  

int cellNum = maxCol;  

T entity = null;  

for (int j = 0; j <= cellNum; j++) { 

HSSFCell cell = row.getCell(j);  

if (cell == null) {  

continue;  

}  

int cellType = cell.getCellType();  

String c = "";  

if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {  

c = String.valueOf(cell.getNumericCellValue());  

} else if (cellType == HSSFCell.CELL_TYPE_BOOLEAN) {  

c = String.valueOf(cell.getBooleanCellValue());  

} else {  

c = cell.getStringCellValue();  

}  

if (c == null || c.equals("")) {  

continue;  

}  

entity = (entity == null ? clazz.newInstance() : entity);// 如果不存在實例則新建.  

// System.out.println(cells[j].getContents());  

Field field = fieldsMap.get(j);// 從map中得到對應列的field.  

if (field==null) {  

continue;  

}  

// 取得類型,並根據對象類型設置值.  

Class<?> fieldType = field.getType();  

if (String.class == fieldType) {  

field.set(entity, String.valueOf(c));  

} else if ((Integer.TYPE == fieldType)  

|| (Integer.class == fieldType)) {  

field.set(entity, Integer.parseInt(c));  

} else if ((Long.TYPE == fieldType)  

|| (Long.class == fieldType)) {  

field.set(entity, Long.valueOf(c));  

} else if ((Float.TYPE == fieldType)  

|| (Float.class == fieldType)) {  

field.set(entity, Float.valueOf(c));  

} else if ((Short.TYPE == fieldType)  

|| (Short.class == fieldType)) {  

field.set(entity, Short.valueOf(c));  

} else if ((Double.TYPE == fieldType)  

|| (Double.class == fieldType)) {  

field.set(entity, Double.valueOf(c));  

} else if (Character.TYPE == fieldType) {  

if ((c != null) && (c.length() > 0)) {  

field.set(entity, Character  

.valueOf(c.charAt(0)));  

}  

}  

 

}  

if (entity != null) {  

list.add(entity);  

}  

}  

}  

     return list;  

    }  

 

    /** 

     * 對list數據源將其里面的數據導出到excel表單 

     */  

    public boolean exportExcel(List<T> lists[], String sheetNames[], OutputStream output) {  

        if (lists.length != sheetNames.length) {  

            return false;  

        }  

        HSSFWorkbook workbook = new HSSFWorkbook();// 產生工作薄對象  

        for (int ii = 0; ii < lists.length; ii++) {  

            List<T> list = lists[ii];  

            String sheetName = sheetNames[ii];  

            List<Field> fields = getMappedFiled(clazz, null);  

            HSSFSheet sheet = workbook.createSheet();// 產生工作表對象  

            workbook.setSheetName(ii, sheetName);  

            HSSFRow row;  

            HSSFCell cell;// 產生單元格  

            HSSFCellStyle style = workbook.createCellStyle();  

            style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);  

            style.setFillBackgroundColor(HSSFColor.GREY_40_PERCENT.index);  

            row = sheet.createRow(0);// 產生一行  

            for (int i = 0; i < fields.size(); i++) {  

                Field field = fields.get(i);  

                ExcelField attr = field.getAnnotation(ExcelField.class);  

                int col = getExcelCol(attr.column());// 獲得列號  

                cell = row.createCell(col);// 創建列  

                cell.setCellType(HSSFCell.CELL_TYPE_STRING);// 設置列中寫入內容為String類型  

                cell.setCellValue(attr.name());// 寫入列名  

                if (!attr.prompt().trim().equals("")) {  

                    setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, col, col);// 這里默認設了2-101列提示.  

                }  

                if (attr.combo().length > 0) {  

                    setHSSFValidation(sheet, attr.combo(), 1, 100, col, col);// 這里默認設了2-101列只能選擇不能輸入.  

                }  

                cell.setCellStyle(style);  

            }  

            int startNo = 0;  

            int endNo = list.size();  

            for (int i = startNo; i < endNo; i++) {  

                row = sheet.createRow(i + 1 - startNo);  

                T vo = (T) list.get(i);

                for (int j = 0; j < fields.size(); j++) {  

                    Field field = fields.get(j);

                    field.setAccessible(true);

                    ExcelField attr = field.getAnnotation(ExcelField.class);  

                    try {  

                        if (attr.isExport()) {  

                            cell = row.createCell(getExcelCol(attr.column()));

                            cell.setCellType(HSSFCell.CELL_TYPE_STRING);  

                            cell.setCellValue(field.get(vo) == null ? ""  

                                    : String.valueOf(field.get(vo))); 

                        }  

                    } catch (IllegalArgumentException e) {  

                        e.printStackTrace();  

                    } catch (IllegalAccessException e) {  

                        e.printStackTrace();  

                    }  

                }  

            }  

        }  

        try {  

            output.flush();  

            workbook.write(output);  

            output.close();  

            return true;  

        } catch (IOException e) {  

            e.printStackTrace();  

            return false;  

        }  

 

    }  

 

    /** 

     * 對list數據源將其里面的數據導出到excel表單

     */  

    @SuppressWarnings("unchecked")

    public boolean exportExcel(List<T> list, String sheetName,  

            OutputStream output) {

        //此處 對類型進行轉換

        List<T> ilist = new ArrayList<>();

        for (T t : list) {

            ilist.add(t);

        }

        List<T>[] lists = new ArrayList[1];  

        lists[0] = ilist;  

 

        String[] sheetNames = new String[1];  

        sheetNames[0] = sheetName;  

 

        return exportExcel(lists, sheetNames, output);  

    }  

 

    /** 

     * 將EXCEL中A,B,C,D,E列映射成0,1,2,3,4 

     * @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;  

    }  

 

    /** 

     * 設置單元格上提示 

     */  

    public static HSSFSheet setHSSFPrompt(HSSFSheet sheet, String promptTitle,  

            String promptContent, int firstRow, int endRow, int firstCol,  

            int endCol) {  

        DVConstraint constraint = DVConstraint  

                .createCustomFormulaConstraint("DD1");  

        CellRangeAddressList regions = new CellRangeAddressList(firstRow,  

                endRow, firstCol, endCol);  

        HSSFDataValidation data_validation_view = new HSSFDataValidation(  

                regions, constraint);  

        data_validation_view.createPromptBox(promptTitle, promptContent);  

        sheet.addValidationData(data_validation_view);  

        return sheet;  

    }  

 

    /** 

     * 設置某些列的值只能輸入預制的數據,顯示下拉框. 

     */  

    public static HSSFSheet setHSSFValidation(HSSFSheet sheet,  

            String[] textlist, int firstRow, int endRow, int firstCol,  

            int endCol) {  

        DVConstraint constraint = DVConstraint  

                .createExplicitListConstraint(textlist);  

        CellRangeAddressList regions = new CellRangeAddressList(firstRow,  

                endRow, firstCol, endCol);  

        HSSFDataValidation data_validation_list = new HSSFDataValidation(  

                regions, constraint);  

        sheet.addValidationData(data_validation_list);  

        return sheet;  

    }  

 

    /** 

     * 得到實體類所有通過注解映射了數據表的字段 

     *  遞歸調用

     */  

    private List<Field> getMappedFiled(Class clazz, List<Field> fields) {  

        if (fields == null) {  

            fields = new ArrayList<Field>();  

        }  

 

        Field[] allFields = clazz.getDeclaredFields();// 得到所有定義字段  

        for (Field field : allFields) {  

            if (field.isAnnotationPresent(ExcelField.class)) {  

                fields.add(field);  

            }  

        }  

        if (clazz.getSuperclass() != null  

                && !clazz.getSuperclass().equals(Object.class)) {  

            getMappedFiled(clazz.getSuperclass(), fields);  

        }  

        return fields;  

    }  

步驟三、需要導出的java類屬性上加上自定義注解

/**

 * 退款excel導出

 */

public class ExcelPackageRefund {

 

@ExcelField(name="訂單",column="A")

private String orderSn;//訂單

@ExcelField(name="包裹",column="B")

private String packageSn;//包裹

    //setter/getter

}

四、service和cotroller(字數限制,只保留了核心)

response.setHeader("Content-Disposition", "attachment;filename="+new String(filename.getBytes("utf-8"),"iso8859-1"));

response.setContentType("application/ynd.ms-excel;charset=UTF-8");

 

List<ExcelPackageRefund> packageReturn = excelExportService.exportPackageRefund(bean);

ExcelUtil<ExcelPackageRefund> prbs = new ExcelUtil<ExcelPackageRefund>(ExcelPackageRefund.class);

boolean result = prbs.exportExcel(packageReturn, sheetName,response.getOutputStream());


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM