Apache POIによるエクセルインポートエクスポートツール

39344 ワード

簡単なApache POIベースのエクセルを導入してエクスポートします。
  • 簡単なAppche POIベースのエクセルを導入してエクスポートします。
  • 紹介します。
  • 実現
  • ソースコードダウンロード
  • 紹介する
    Excelはエクスポートデータを導入してプロジェクトの中でやはり比較的に常用して、今回ちょうどこの問題に出会って、簡単で通用する導入のエクスポートツールを書きました。
    実現する
  • Maven依存
  • <dependency>
       <groupId>org.apache.poigroupId>
        <artifactId>poi-ooxmlartifactId>
        <version>3.17version>
    dependency>
  • ファイルリスト
  • .
    └── excel
        ├── ExcelField.java
        ├── Excel.java
        ├── ExcelPolicy.java
        ├── ExcelUtil.java
        └── exception
            ├── ExcelEntityException.java
            └── UnknownExcelTypeException.java
    
  • 具体的に1 Excel Policy.java
    package cn.polysys.util.excel;
    
    /**
     *      {@link Excel}       
     *
     * @author fantome
     * @date 2018/07/05
     */
    public enum ExcelPolicy {
        /**
         *       
         */
        ALL,
        /**
         *      {@link Excel}     
         */
        SPECIFY
    }
    2 Excel.javaを実現します。
    注釈は、データインポート・エクスポートされたエンティティまたはフィールドに追加されます。@Excelの注釈がエンティティに追加され、policyがALLに設定されると、エンティティのすべてのフィールドが解析され、フィールドに@Excelの注解があります。注解がない場合は、デフォルトの配置で解析されます。そして、エンティティクラスには、フィールドに厳密にマッピングされたセットとget方法が完備されていることが要求される。
    package cn.polysys.util.excel;
    
    import java.lang.annotation.*;
    
    /**
     * @author fantome
     * @date 2018/07/05
     */
    @Target({ElementType.FIELD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Excel {
    
        /**
         *   ,  name,name     name 
         *
         * @return
         */
        String value() default "";
    
        /**
         *   ,  value
         *
         * @return
         */
        String name() default "";
    
        /**
         *    
         *
         * @return
         */
        int order() default Integer.MAX_VALUE;
    
        /**
         *         
         *
         * @return
         */
        ExcelPolicy policy() default ExcelPolicy.SPECIFY;
    }
    
    3 Excel Field.java
    フィールドの操作対象には、フィールドのsetとget方法が含まれており、解析時のデータ読み込みと書き込みが容易です。
    package cn.polysys.util.excel;
    
    import java.lang.reflect.Method;
    
    /**
     * @author fantome
     * @date 2018/07/05
     */
    class ExcelField implements Comparable {
        /**
         *    class
         */
        private Class> clazz;
        /**
         *   
         */
        private String name;
        /**
         *     field 
         */
        private String fieldName;
        /**
         * field   
         */
        private Class> type;
        /**
         *        ,       field  
         */
        private int order;
        /**
         *     
         */
        private Method setter;
        /**
         *     
         */
        private Method getter;
    
        ExcelField(Class> clazz, String name, String fieldName, Class> type, int order) {
            this.clazz = clazz;
            this.name = name;
            this.fieldName = fieldName;
            this.type = type;
            this.order = order;
        }
    
        Method getSetter() throws NoSuchMethodException {
            if (setter == null) {
                char[] chars = fieldName.toCharArray();
                chars[0] = Character.toUpperCase(chars[0]);
                setter = clazz.getMethod("set" + String.valueOf(chars), type);
            }
            return setter;
        }
    
        Method getGetter() throws NoSuchMethodException {
            if (getter == null) {
                char[] chars = fieldName.toCharArray();
                chars[0] = Character.toUpperCase(chars[0]);
                getter = clazz.getMethod("get" + String.valueOf(chars));
            }
            return getter;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getFieldName() {
            return fieldName;
        }
    
        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    
        public Class> getType() {
            return type;
        }
    
        public void setType(Class> type) {
            this.type = type;
        }
    
        @Override
        public int compareTo(ExcelField o) {
            return this.order - o.order;
        }
    }
    
    4 Excel Entity Exception.java
    本体に反射操作異常がある場合は投げますが、一般的に本体定義のフォーマットが正しくない、または関連する方法がないです。
    package cn.polysys.util.excel.exception;
    
    /**
     * @author fantome
     * @date 2018/07/09
     */
    public class ExcelEntityException extends Exception {
        public ExcelEntityException() {
            super();
        }
    
        public ExcelEntityException(String message) {
            super(message);
        }
    
        public ExcelEntityException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public ExcelEntityException(Throwable cause) {
            super(cause);
        }
    }
    
    5 UKnown Excel Type Exception.java
    サポート.xlsと.xlsx拡張名エクセルファイル解析処理は、パラメータがfileの場合、拡張名に基づいて処理されます。
    package cn.polysys.util.excel.exception;
    
    /**
     * @author fantome
     * @date 2018/07/09
     */
    public class UnknownExcelTypeException extends Exception {
        public UnknownExcelTypeException() {
            super();
        }
    
        public UnknownExcelTypeException(String message) {
            super(message);
        }
    
        public UnknownExcelTypeException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public UnknownExcelTypeException(Throwable cause) {
            super(cause);
        }
    }
    
    6 Excel Util.java(コアコンテンツ)
    package cn.polysys.util.excel;
    
    import cn.polysys.util.excel.exception.ExcelEntityException;
    import cn.polysys.util.excel.exception.UnknownExcelTypeException;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    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.math.BigDecimal;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author fantome
     * @date 2018/07/04
     */
    public class ExcelUtil {
    
        /**
         *          excelField
         */
        private static final Map> EXCEL_FIELD_CACHE = new ConcurrentHashMap<>();
    
        /**
         *   sheet   
         *
         * @param clazz              POJO  
         * @param sheet              sheet  
         * @param isFirstTitleRow         
         * @param                POJO  
         * @return         
         * @throws ExcelEntityException POJO           
         */
        public static  List importExcel(Class clazz, Sheet sheet, boolean isFirstTitleRow) throws ExcelEntityException {
            List resultList = new ArrayList<>();
            List fields = getExcelFields(clazz);
            int rowIndex = 0;
            if (isFirstTitleRow) {
                rowIndex = 1;
            }
            for (; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                try {
                    T instance = clazz.newInstance();
                    for (int i = 0; i < fields.size(); i++) {
                        ExcelField field = fields.get(i);
                        Class> type = field.getType();
                        Cell cell = row.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
                        if (cell == null) {
                            continue;
                        }
                        CellType cellType = cell.getCellTypeEnum();
                        if (cellType.equals(CellType.NUMERIC)) {
                            if (type.isAssignableFrom(Date.class)) {
                                field.getSetter().invoke(instance, cell.getDateCellValue());
                            } else if (type.isAssignableFrom(Integer.class)) {
                                field.getSetter().invoke(instance, Double.valueOf(cell.getNumericCellValue()).intValue());
                            } else if (type.isAssignableFrom(BigDecimal.class)) {
                                BigDecimal decimal = BigDecimal.valueOf(cell.getNumericCellValue());
                                field.getSetter().invoke(instance, decimal);
                            } else if (type.isAssignableFrom(Double.class)) {
                                field.getSetter().invoke(instance, cell.getNumericCellValue());
                            } else {
                                field.getSetter().invoke(instance, cell.getStringCellValue());
                            }
                        } else {
                            field.getSetter().invoke(instance, cell.getStringCellValue());
                        }
                    }
                    resultList.add(instance);
                } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                    throw new ExcelEntityException(e);
                }
            }
            return resultList;
        }
    
        /**
         * @param clazz               POJO  
         * @param workbook            workbook  
         * @param isOnlyFirstSheet           sheet  
         * @param isFirstTitleRow          
         * @param                 POJO  
         * @return         
         * @throws ExcelEntityException POJO           
         */
        public static  List importExcel(Class clazz, Workbook workbook, boolean isOnlyFirstSheet, boolean isFirstTitleRow) throws ExcelEntityException {
            List resultList = new ArrayList<>();
            int numberOfSheets = isOnlyFirstSheet ? 1 : workbook.getNumberOfSheets();
            for (int sheetIndex = 0; sheetIndex < numberOfSheets; sheetIndex++) {
                Sheet sheet = workbook.getSheetAt(sheetIndex);
                List sheetResult = importExcel(clazz, sheet, isFirstTitleRow);
                resultList.addAll(sheetResult);
            }
            return resultList;
    
        }
    
        /**
         * @param clazz              POJO  
         * @param workbook           workbook  
         * @param isFirstTitleRow         
         * @param                POJO  
         * @return         
         * @throws ExcelEntityException POJO           
         */
        public static  List importExcel(Class clazz, Workbook workbook, boolean isFirstTitleRow) throws ExcelEntityException {
            return importExcel(clazz, workbook, false, isFirstTitleRow);
        }
    
        /**
         *         sheet        ,       T
         *
         * @param clazz               POJO  
         * @param file                  file
         * @param isOnlyFirstSheet           sheet  
         * @param isFirstTitleRow          
         * @param                 POJO  
         * @return List                
         * @throws IOException                   I/O         
         * @throws ExcelEntityException      POJO           
         * @throws UnknownExcelTypeException    excel     
         */
        public static  List importExcel(Class clazz, File file, boolean isOnlyFirstSheet, boolean isFirstTitleRow) throws IOException, ExcelEntityException, UnknownExcelTypeException {
            Workbook workbook = file2Workbook(file, false);
            return importExcel(clazz, workbook, isOnlyFirstSheet, isFirstTitleRow);
        }
    
        /**
         *       
         *
         * @param classes            POJO    
         * @param workbook             workbook
         * @param isFirstTitleRow         
         * @return  excel     
         * @throws ExcelEntityException POJO           
         */
        public static List> importExcelWithMultiType(List> classes, Workbook workbook, boolean isFirstTitleRow) throws ExcelEntityException {
            List> resultData = new ArrayList<>();
            //           sheet      ,      
            int size = Math.min(classes.size(), workbook.getNumberOfSheets());
            for (int index = 0; index < size; index++) {
                List> list = importExcel(classes.get(index), workbook.getSheetAt(index), isFirstTitleRow);
                resultData.add(list);
            }
            return resultData;
        }
    
        /**
         *       
         *
         * @param classes            POJO    
         * @param file                 
         * @param isFirstTitleRow         
         * @return  excel     
         * @throws IOException                   I/O         
         * @throws ExcelEntityException      POJO           
         * @throws UnknownExcelTypeException    excel     
         */
        public static List> importExcelWithMultiType(List> classes, File file, boolean isFirstTitleRow) throws IOException, ExcelEntityException, UnknownExcelTypeException {
            Workbook workbook = file2Workbook(file, false);
            return importExcelWithMultiType(classes, workbook, isFirstTitleRow);
        }
    
        /**
         *     Sheet
         *
         * @param clazz              POJO  
         * @param data                   
         * @param sheet                  sheet
         * @param isFirstTitleRow         
         * @throws ExcelEntityException POJO           
         */
        public static void exportExcel(Class> clazz, List> data, Sheet sheet, boolean isFirstTitleRow) throws ExcelEntityException {
            List fields = getExcelFields(clazz);
            int rowNum = 0;
            if (isFirstTitleRow) {
                Row titleRow = sheet.createRow(rowNum++);
                for (int i = 0; i < fields.size(); i++) {
                    Cell cell = titleRow.createCell(i, CellType.STRING);
                    cell.setCellValue(fields.get(i).getName());
                }
            }
            for (Object obj : data) {
                Row row = sheet.createRow(rowNum++);
                for (int i = 0; i < fields.size(); i++) {
                    Cell cell = row.createCell(i);
                    ExcelField field = fields.get(i);
                    try {
                        Object value = field.getGetter().invoke(obj);
                        Class> type = field.getType();
                        if (type.isAssignableFrom(Date.class)) {
                            cell.setCellValue((Date) value);
                        } else if (type.isAssignableFrom(Boolean.class)) {
                            cell.setCellValue((Boolean) value);
                        } else if (type.isAssignableFrom(Integer.class)) {
                            cell.setCellValue((Integer) value);
                        } else if (type.isAssignableFrom(BigDecimal.class)) {
                            BigDecimal decimal = (BigDecimal) value;
                            cell.setCellValue(decimal.doubleValue());
                        } else {
                            cell.setCellValue(String.valueOf(value));
                        }
                    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                        throw new ExcelEntityException(e);
                    }
                }
            }
        }
    
        /**
         * @param clazz              POJO  
         * @param data                   
         * @param workbook             workbook  
         * @param sheetName            sheet  
         * @param isFirstTitleRow         
         * @param                POJO  
         * @throws ExcelEntityException POJO           
         */
        public static  void exportExcel(Class clazz, List data, Workbook workbook, String sheetName, boolean isFirstTitleRow) throws ExcelEntityException {
            Sheet sheet = sheetName == null ? workbook.createSheet() : workbook.createSheet(sheetName);
            exportExcel(clazz, data, sheet, isFirstTitleRow);
        }
    
        /**
         * @param clazz              POJO  
         * @param data                   
         * @param sheetName         excel sheet  , null    
         * @param file                 
         * @param isFirstTitleRow         
         * @param                POJO  
         * @throws IOException                   I/O         
         * @throws ExcelEntityException      POJO           
         * @throws UnknownExcelTypeException    excel     
         */
        public static  void exportExcel(Class clazz, List data, File file, String sheetName, boolean isFirstTitleRow) throws IOException, ExcelEntityException, UnknownExcelTypeException {
            Workbook workbook = file2Workbook(file, true);
            exportExcel(clazz, data, workbook, sheetName, isFirstTitleRow);
            workbook.write(new FileOutputStream(file));
        }
    
        /**
         *          sheet
         *
         * @param clazz              POJO  
         * @param data                   
         * @param sheetNames        excel   sheet  
         * @param file                 
         * @param isFirstTitleRow         
         * @param                POJO  
         * @throws IOException                   I/O         
         * @throws ExcelEntityException      POJO           
         * @throws UnknownExcelTypeException    excel     
         */
        public static  void exportExcel(Class clazz, List> data, List sheetNames, File file, boolean isFirstTitleRow) throws IOException, ExcelEntityException, UnknownExcelTypeException {
            Workbook workbook = file2Workbook(file, true);
            for (int i = 0; i < data.size(); i++) {
                String sheetName = i < sheetNames.size() ? sheetNames.get(i) : null;
                exportExcel(clazz, data.get(i), workbook, sheetName, isFirstTitleRow);
            }
            workbook.write(new FileOutputStream(file));
        }
    
        /**
         *           WorkBook
         *
         * @param classes            POJO    
         * @param data                , classes    
         * @param sheetNames        sheet    
         * @param workbook             workbook  
         * @param isFirstTitleRow         
         * @throws ExcelEntityException POJO           
         */
        public static void exportExcelWithMultiType(List> classes, List> data, List sheetNames, Workbook workbook, boolean isFirstTitleRow) throws ExcelEntityException {
            int size = Math.min(classes.size(), data.size());
            for (int i = 0; i < size; i++) {
                String sheetName = null;
                if (i < sheetNames.size()) {
                    sheetName = sheetNames.get(i);
                }
                Sheet sheet = sheetName == null ? workbook.createSheet() : workbook.createSheet(sheetName);
                exportExcel(classes.get(i), data.get(i), sheet, isFirstTitleRow);
            }
        }
    
        /**
         * @param classes            POJO    
         * @param data                , classes    
         * @param sheetNames        sheet    
         * @param file                     
         * @param isFirstTitleRow         
         * @throws IOException                   I/O         
         * @throws UnknownExcelTypeException    excel     
         * @throws ExcelEntityException      POJO           
         */
        public static void exportExcelWithMultiType(List> classes, List> data, List sheetNames, File file, boolean isFirstTitleRow) throws IOException, UnknownExcelTypeException, ExcelEntityException {
            Workbook workbook = file2Workbook(file, true);
            exportExcelWithMultiType(classes, data, sheetNames, workbook, isFirstTitleRow);
            workbook.write(new FileOutputStream(file));
        }
    
        /**
         * @param file              file
         * @param isExportMode  export        ,          
         * @return Workbook       Workbook  
         * @throws IOException                   I/O         
         * @throws UnknownExcelTypeException    excel     
         */
        public static Workbook file2Workbook(File file, boolean isExportMode) throws UnknownExcelTypeException, IOException {
            Workbook workbook;
            String fileName = file.getName().toLowerCase();
            if (fileName.endsWith(ExcelType.XLS)) {
                workbook = isExportMode ? new HSSFWorkbook() : new HSSFWorkbook(new FileInputStream(file));
            } else if (fileName.endsWith(ExcelType.XLSX)) {
                workbook = isExportMode ? new XSSFWorkbook() : new XSSFWorkbook(new FileInputStream(file));
            } else {
                throw new UnknownExcelTypeException();
            }
            return workbook;
        }
    
        /**
         * @param clazz    POJO  
         * @return   class      
         */
        private static List getExcelFields(Class> clazz) {
            if (!EXCEL_FIELD_CACHE.containsKey(clazz)) {
                List excelFields = new ArrayList<>();
                //           
                boolean allExportPolicy = false;
                if (clazz.isAnnotationPresent(Excel.class)) {
                    ExcelPolicy policy = clazz.getAnnotation(Excel.class).policy();
                    allExportPolicy = policy.equals(ExcelPolicy.ALL);
                }
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    if (!allExportPolicy && !field.isAnnotationPresent(Excel.class)) {
                        continue;
                    }
                    String name;
                    int order = Integer.MAX_VALUE;
                    if (field.isAnnotationPresent(Excel.class)) {
                        Excel excel = field.getAnnotation(Excel.class);
                        order = excel.order();
                        name = excel.name();
                        if ("".equals(name)) {
                            name = excel.value();
                        }
                        if ("".equals(name)) {
                            name = field.getName();
                        }
                    } else {
                        name = field.getName();
                    }
                    excelFields.add(new ExcelField(clazz, name, field.getName(), field.getType(), order));
                }
                Collections.sort(excelFields);
                EXCEL_FIELD_CACHE.put(clazz, excelFields);
            }
            return EXCEL_FIELD_CACHE.get(clazz);
        }
    
        class ExcelType {
            final static String XLS = ".xls";
            final static String XLSX = ".xlsx";
        }
    }
    
  • ソースコードのダウンロード
    poly-utilソースコード