POI導(dǎo)入Excel(后續(xù)添加導(dǎo)出Excel)

1殖演、引入依賴

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.monitorjbl</groupId>
            <artifactId>xlsx-streamer</artifactId>
            <version>2.1.0</version>
        </dependency>

2熄浓、編寫ExcelDataDO類

@Data
public class ExcelDataDO<T> {
    public Class<T> clazz;

    public ExcelData(Class<T> clazz) {
        this.clazz = clazz;
    }

    public String sheetName;
    public List<T> data;
}

3情臭、編寫自動(dòng)封裝@ExcelField注解類

@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD})
public @interface ExcelField {

    /**
     * 導(dǎo)出到Excel中的名字.
     */
    public abstract String name();


    /**
     * 配置列的名稱,對(duì)應(yīng)A,B,C,D....
     */
    public abstract String column();


    /**
     * 必填項(xiàng)
     */
    public abstract boolean required() default false;

    /**
     * 校驗(yàn)規(guī)則(正則)
     */
    public abstract String regex() default "";

    /**
     * 是否導(dǎo)出數(shù)據(jù)
     */
    public abstract boolean isExport() default true;
}

4、編寫自動(dòng)封裝ExcelBridge實(shí)體類

@Data
public class ExcelBridgeDO{

    /**
     * 項(xiàng)目序號(hào)
     */
    @ExcelField(name = "序號(hào)", column = "A", required = true)
    private String projectNumber;

    /**
     * 地市名稱
     */
    @ExcelField(name = "地市名稱", column = "B", required = true)
    private String cityName;

    /**
     * 路線名稱
     */
    @ExcelField(name = "路線名稱", column = "C", required = true)
    private String roadName;

    /**
     * 項(xiàng)目類型
     */
    @ExcelField(name = "工程項(xiàng)目", column = "D", required = true)
    private String projectType;

    /**
     * 工程所在地區(qū)間樁號(hào)
     */
    @ExcelField(name = "工程所在地區(qū)間樁號(hào)", column = "E", required = true)
    private String sectionNo;

    /**
     * 建設(shè)性質(zhì)
     */
    @ExcelField(name = "建設(shè)性質(zhì)", column = "F", required = true)
    private String buildNature;

    /**
     * 技術(shù)標(biāo)準(zhǔn)結(jié)構(gòu)
     */
    @ExcelField(name = "技術(shù)標(biāo)準(zhǔn)結(jié)構(gòu)", column = "G", required = true)
    private String buildStructure;

    /**
     * 單位
     */
    @ExcelField(name = "單位", column = "H", required = true)
    private String projectUnit;

    /**
     * 數(shù)量
     */
    @ExcelField(name = "數(shù)量", column = "I", required = true)
    private String projectNum;

    /**
     * 座
     */
    @ExcelField(name = "座", column = "J", required = true)
    private String zuo;

    /**
     * 總投資金額
     */
    @ExcelField(name = "總投資金額", column = "K", required = true)
    private BigDecimal projectTotalMoney;


    /**
     * 部投資金額
     */
    @ExcelField(name = "部投資金額", column = "L", required = true)
    private BigDecimal countyOutMoney;

    /**
     * 省投資金額
     */
    @ExcelField(name = "省投資金額", column = "M", required = true)
    private BigDecimal provinceOutMoney;

    /**
     * 備注
     */
    @ExcelField(name = "備注", column = "R", required = true)
    private String remark;
}

5赌蔑、編寫ExcelUtil類

/**
 * Excel 工具類.
 */
@SuppressWarnings("all")
public class ExcelUtil<T> {
        public Class<T> clazz;
    boolean v2007 = true;

    public ExcelUtil(Class<T> clazz) {
        this.clazz = clazz;
    }

    public Workbook getWorkbook(InputStream in, boolean v2007) throws Exception {
        Workbook workbook = null;
        this.v2007 = v2007;
        if (v2007) {
            workbook = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).open(in);
        } else {
            workbook = new HSSFWorkbook(in);
        }
        return workbook;
    }

    public boolean validity(Workbook workbook) throws Exception {
        Sheet sheet = workbook.getSheetAt(0);
        List<Field> allFields = getMappedFiled(clazz, null);
        if (sheet.getLastRowNum() <= 0) {
            return false;
        }
        Row topRow = null;
        boolean flag = false;
        for (Row row : sheet) {
            if (flag) {
                break;
            }
            topRow = row;
            flag = true;
        }
        int colNum = 0;
        for (Field field : allFields) {
            if (field.isAnnotationPresent(ExcelField.class)) {
                ExcelField attr = field.getAnnotation(ExcelField.class);
                if (topRow.getCell(colNum) == null) {

                    return false;
                } else {
                    String headName = topRow.getCell(colNum).getStringCellValue();
                    if (!headName.equals(attr.name())) {
                        return false;
                    }
                }
                colNum++;

            }
        }
        return true;
    }


    public List<ExcelDataDO<T>> getList(Workbook workbook, int headRow) throws Exception {
        List<ExcelDataDO<T>> result = new ArrayList<ExcelDataDO<T>>();
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            ExcelDataDO<T> exceData = new ExcelDataDO<T>(clazz);
            List<T> list = getList(sheet, headRow);
            exceData.setSheetName(sheet.getSheetName());
            exceData.setData(list);
            result.add(exceData);
        }
        return result;
    }

    public List<ExcelDataDO<T>> getList(Workbook workbook, int sheetIndex, int headRow) throws Exception {
        List<ExcelDataDO<T>> result = new ArrayList<ExcelDataDO<T>>();
        Sheet sheet = workbook.getSheetAt(sheetIndex);
        ExcelDataDO<T> exceData = new ExcelDataDO<T>(clazz);
        List<T> list = getList(sheet, headRow);
        exceData.setSheetName(sheet.getSheetName());
        exceData.setData(list);
        result.add(exceData);
        return result;
    }

    public List<T> getList(Sheet sheet, int headRow) throws Exception {
        List<T> list = new ArrayList<>();
        int maxCol = 0;
        List<Field> allFields = getMappedFiled(clazz, null);
        Map<Integer, Field> fieldsMap = new HashMap<>();
        for (Field field : allFields) {
            if (field.isAnnotationPresent(ExcelField.class)) {
                ExcelField attr = field.getAnnotation(ExcelField.class);
                int col = getExcelCol(attr.column());
                maxCol = Math.max(col, maxCol);
                field.setAccessible(true);
                fieldsMap.put(col, field);
            }
        }
        int index = 0;
        boolean flag = false;
        for (Row row : sheet) {
            int cellNum = maxCol;
            index = index + 1;
            if (index <= headRow) {
                continue;
            }
            if (row.getCell(0).getStringCellValue().equals("1") || flag) {
                flag = true;
            } else {
                continue;
            }

            T entity = null;
            for (int j = 0; j <= cellNum; j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    continue;
                }
                if (!v2007) {
                    cell.setCellType(CellType.STRING);
                }
                String c = cell.getStringCellValue();
                if (c == null || c.equals("")) {
                    continue;
                }
                entity = (entity == null ? clazz.newInstance() : entity);

                Field field = fieldsMap.get(j);
                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 ((BigDecimal.class == fieldType)
                        || (BigDecimal.class == fieldType)) {
                    c = c.replaceAll("\\\\(.*?\\\\)", "");
                    field.set(entity, new BigDecimal(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);
            }
            if (!flag) {
                throw new Exception("未找到有效數(shù)據(jù).");
            }
        }
        return list;
    }

    public int getExcelCol(String col) {
        col = col.toUpperCase();
        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;
    }


    private List<Field> getMappedFiled(Class clazz, List<Field> fields) {
        if (fields == null) {
            fields = new ArrayList<>();
        }

        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;
    }

    private boolean notEmpty(Object object) {
        if (object == null || String.valueOf(object).trim().equals("")) {
            return false;
        }
        return true;
    }

    private boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
}

6俯在、測試代碼

本地測試
    public static void main(String agrs[]) throws Exception {
        ExcelUtil excelUtil = new ExcelUtil(ExcelBridgeDO.class);
        File file = new File("D:\\traffic-project-new\\開發(fā)文檔\\2020-危橋改造計(jì)劃-錄入表總.xlsx");
        FileInputStream inv = new FileInputStream(file);
        Workbook workbook = excelUtil.getWorkbook(inv, "XLSX".equals("XLSX"));
        List<ExcelDataDO<ExcelBridgeDO>> list = excelUtil.getList(workbook, 1, 8);
    }
接口測試
    @RequestMapping(value = "/upload")
    public R upload(@RequestParam("file") MultipartFile file) {
        ExcelUtil excelUtil = new ExcelUtil(ExcelBridgeDO.class);
        InputStream inputStream = file.getInputStream();
        Workbook workbook = excelUtil.getWorkbook(inputStream, suffix.toUpperCase().equals("XLSX"));
        List<ExcelDataDO<ExcelBridgeDO>> excelDataList = excelUtil.getList(workbook, 1, 8);
        return R.ok();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市娃惯,隨后出現(xiàn)的幾起案子朝巫,更是在濱河造成了極大的恐慌,老刑警劉巖石景,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拙吉,居然都是意外死亡潮孽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門筷黔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來往史,“玉大人,你說我怎么就攤上這事佛舱∽道” “怎么了挨决?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長订歪。 經(jīng)常有香客問我脖祈,道長,這世上最難降的妖魔是什么刷晋? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任盖高,我火速辦了婚禮,結(jié)果婚禮上眼虱,老公的妹妹穿的比我還像新娘喻奥。我一直安慰自己,他們只是感情好捏悬,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布撞蚕。 她就那樣靜靜地躺著钦勘,像睡著了一般伏恐。 火紅的嫁衣襯著肌膚如雪域滥。 梳的紋絲不亂的頭發(fā)上蟆肆,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天剃浇,我揣著相機(jī)與錄音掏婶,去河邊找鬼崔列。 笑死让禀,一個(gè)胖子當(dāng)著我的面吹牛摧莽,可吹牛的內(nèi)容都是我干的庙洼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼镊辕,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼油够!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起征懈,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤石咬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卖哎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鬼悠,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年亏娜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了焕窝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡维贺,死狀恐怖它掂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溯泣,我是刑警寧澤虐秋,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布榕茧,位于F島的核電站,受9級(jí)特大地震影響客给,放射性物質(zhì)發(fā)生泄漏用押。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一起愈、第九天 我趴在偏房一處隱蔽的房頂上張望只恨。 院中可真熱鬧,春花似錦抬虽、人聲如沸官觅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽休涤。三九已至,卻和暖如春笛辟,著一層夾襖步出監(jiān)牢的瞬間功氨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工手幢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捷凄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓围来,卻偏偏與公主長得像跺涤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子监透,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容