最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot如何使用POI讀取Excel文件

 更新時(shí)間:2021年08月20日 10:13:43   作者:代碼貓  
本文主要介紹使用POI進(jìn)行Excel文件的相關(guān)操作,涉及讀取文件,獲取sheet表格,對(duì)單元格內(nèi)容進(jìn)行讀寫操作,以及合并單元格的操作

spring boot 使用POI讀取Excel文件

Excel文件目錄

Excel模板文件存了resourse目錄下,如下圖:

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>

重要說明

如果是xls格式,使用HSSFWorkbook,HSSFSheet,HSSFRow來進(jìn)行相關(guān)操作

如果是xlsx格式,使用XSSFWorkbook,XSSFSheet,XSSFRow來進(jìn)行相關(guān)操作

讀取Excel文件

// 定義一個(gè)數(shù)據(jù)格式化對(duì)象
XSSFWorkbook wb = null;
try {
    //excel模板路徑
    File cfgFile = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "static/ExcelTemplate/ContradictionMatrix.xlsx");
    InputStream in = new FileInputStream(cfgFile);
    //讀取excel模板
    wb = new XSSFWorkbook(in);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

獲取sheet表格及讀寫單元格內(nèi)容

//獲取sheet表格,及讀取單元格內(nèi)容
XSSFSheet sheet = null;
try{
    sheet = wb.getSheetAt(0);
    //先將獲取的單元格設(shè)置為String類型,下面使用getStringCellValue獲取單元格內(nèi)容
    //如果不設(shè)置為String類型,如果單元格是數(shù)字,則報(bào)如下異常
    //java.lang.IllegalStateException: Cannot get a STRING value from a NUMERIC cell
    sheet.getRow(2).getCell(2).setCellType(CellType.STRING);
    //讀取單元格內(nèi)容
    String cellValue = sheet.getRow(2).getCell(2).getStringCellValue();
    
    //添加一行
    XSSFRow row = sheet.createRow(1); //第2行開始寫數(shù)據(jù)
    row.setHeight((short)400); //設(shè)置行高
    //向單元格寫數(shù)據(jù)
    row.createCell(1).setCellValue("名稱");
}
catch (Exception e){
    e.printStackTrace();
}

合并單元格

使用下面的語句合并單元格:

sheet.addMergedRegion(new CellRangeAddress(0,2,15,18));

看一下CellRangeAddress的構(gòu)造函數(shù):

/**
 * Creates new cell range. Indexes are zero-based.
 * 
 * @param firstRow Index of first row
 * @param lastRow Index of last row (inclusive), must be equal to or larger than {@code firstRow}
 * @param firstCol Index of first column
 * @param lastCol Index of last column (inclusive), must be equal to or larger than {@code firstCol}
 */
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
    super(firstRow, lastRow, firstCol, lastCol);
    
    if (lastRow < firstRow || lastCol < firstCol)
        throw new IllegalArgumentException("lastRow < firstRow || lastCol < firstCol");
}

SpringBoot解析Excel

現(xiàn)在很多web應(yīng)用中,導(dǎo)入excel導(dǎo)出excel很常見,這篇文章就講講導(dǎo)入excel文件。

以批量導(dǎo)入課程為例

首先加入需要的jar包

<!--解析excel-->
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>RELEASE</version>
  </dependency>

數(shù)據(jù)庫中創(chuàng)建一個(gè)表course

DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `course_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '課程id',
  `course_code` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '課程代碼',
  `course_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '課程名稱',
  `teacher_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '教師id',
  `course_time` date NOT NULL DEFAULT '1996-01-01' COMMENT '開課時(shí)間',
  `class_room` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '開課地點(diǎn)',
  `course_week` int(5) UNSIGNED NOT NULL DEFAULT 0 COMMENT '課程學(xué)時(shí)',
  `course_type` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '必修課' COMMENT '課程類型',
  `college_id` int(11) UNSIGNED NOT NULL COMMENT '所屬院系id',
  `score` int(5) UNSIGNED NOT NULL DEFAULT 0 COMMENT '學(xué)分',
  `is_on` tinyint(2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否開啟了選課,默認(rèn)0未開啟',
  PRIMARY KEY (`course_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '課程表' ROW_FORMAT = Dynamic;

新建一個(gè)ExcelUtil.java

/**
 * excel工具類
 */
public class ExcelUtils {
    private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
    /**
     * 課程excel
     * @param in
     * @param fileName
     * @return
     * @throws Exception
     */
    public static List getCourseListByExcel(InputStream in, String fileName) throws Exception {
        List list = new ArrayList<>();
        // 創(chuàng)建excel工作簿
        Workbook work = getWorkbook(in, fileName);
        if (null == work) {
            throw new Exception("創(chuàng)建Excel工作薄為空!");
        }
        Sheet sheet = null;
        Row row = null;
        Cell cell = null;
        for (int i = 0; i < work.getNumberOfSheets(); i++) {
            sheet = work.getSheetAt(i);
            if(sheet == null) {
                continue;
            }
            // 濾過第一行標(biāo)題
            for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
                row = sheet.getRow(j);
                if (row == null || row.getFirstCellNum() == j) {
                    continue;
                }
                List<Object> li = new ArrayList<>();
                for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                    cell = row.getCell(y);
                    // 日期類型轉(zhuǎn)換
                    if(y == 3) {
                        //cell.setCellType(CellType.STRING);
                        double s1 = cell.getNumericCellValue();
                        Date date = HSSFDateUtil.getJavaDate(s1);
                        li.add(date);
                        continue;
                    }
                    li.add(cell);
                }
                list.add(li);
            }
        }
        work.close();
        return list;
    }
    /**
     * 判斷文件格式
     * @param in
     * @param fileName
     * @return
     */
    private static Workbook getWorkbook(InputStream in, String fileName) throws Exception {
        Workbook book = null;
        String filetype = fileName.substring(fileName.lastIndexOf("."));
        if(".xls".equals(filetype)) {
            book = new HSSFWorkbook(in);
        } else if (".xlsx".equals(filetype)) {
            book = new XSSFWorkbook(in);
        } else {
            throw new Exception("請(qǐng)上傳excel文件!");
        }
        return book;
    }
}

這里主要注意一下上面的日期轉(zhuǎn)換,在excel中的日期,通過Java讀出來之后,變成了26 四月 2019這樣的形式,而數(shù)據(jù)庫中我們的字段類型為date,所以總是插入失敗。

上面我的寫法直接是知道那個(gè)字段是Date類型,所以直接使用y==3,這樣寫可復(fù)用性很差。

接下來直接看和數(shù)據(jù)庫交互的邏輯代碼

   /**
     * 通過excel文件,批量增加課程
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/upload/course")
    public String uploadCourseExcel(HttpServletRequest request) {
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartHttpServletRequest.getFile("courseFile");
        if(file.isEmpty()) {
            return "redirect:/admin/course/list";
        }
        try {
            InputStream inputStream = file.getInputStream();
            List<List<Object>> list = ExcelUtils.getCourseListByExcel(inputStream, file.getOriginalFilename());
            inputStream.close();
            for (int i = 0; i < list.size(); i++) {
                List<Object> courseList = list.get(i);
                Course course = new Course();
                course.setCourseCode(courseList.get(0).toString());
                course.setCourseName(courseList.get(1).toString());
                // 通過教師姓名查教師id
                String teacherId = teacherService.getTeacByName(courseList.get(2).toString());
                // 教師信息錯(cuò)誤,直接跳過這條記錄
                if(teacherId == null) {
                    continue;
                }
                course.setTeacherId(teacherId);
                // 格式化時(shí)間
                Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(courseList.get(3).toString());
                course.setCourseTime(new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date)));
                course.setClassRoom(courseList.get(4).toString());
                course.setCourseWeek(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(5).toString()))));
                course.setCourseType(courseList.get(6).toString());
                // 通過院系名稱查詢?cè)合礽d
                Integer collegeId = collegeService.getCollegeByName(courseList.get(7).toString());
                // 院系有誤,直接跳過這條記錄
                if(collegeId == null || collegeId == 0) {
                    continue;
                }
                course.setCollegeId(collegeId);
                course.setScore(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(8).toString()))));
                // 默認(rèn)不開啟選課
                course.setIsOn(0);
                logger.error("course = " + course);
                // 判斷課程是否重復(fù)(同一門課程可以有多個(gè)教師教師course_code, course_name, teacher_id聯(lián)合)
                Integer courseId = null;
                courseId = courseService.getCourseByThree(course);
                // 存在重復(fù)的
                if(courseId != null) {
                    // 跳過不添加
                    continue;
                }
                // 執(zhí)行插入操作
                courseService.addCourse(course);
            }
        } catch (Exception e) {
            return "redirect:/admin/course/list";
        }
        return "redirect:/admin/course/list";
    }

可以看到,我又對(duì)時(shí)間類型進(jìn)行了處理,才能最終插入數(shù)據(jù)庫

// 格式化時(shí)間
Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(courseList.get(3).toString());
course.setCourseTime(new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date)));

同時(shí),在excel中的整數(shù)類型,取出來之后就會(huì)變成Double類型比如5變成5.0,所以我對(duì)此也進(jìn)行了處理

course.setCourseWeek(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(5).toString()))));

最后調(diào)用代碼進(jìn)行插入操作。

看看前端代碼

<button class="btn btn-default col-md-2" style="margin-top: 20px">
<a data-toggle="modal" href="#uploadExcel" rel="external nofollow"  role="button" style="color: black; text-decoration: none">
批量添加<sapn class="glyphicon glyphicon-plus"/>
</a>
</button>
<!--批量添加模態(tài)框-->
<div class="modal fade" tabindex="-1" role="dialog" id="uploadExcel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form class="form-horizontal" role="form" th:action="@{/admin/upload/course}"
enctype="multipart/form-data" method="post">
<div class="modal-body">
請(qǐng)選擇文件:<input type="file" name="courseFile">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">關(guān)閉</button>
<button type="submit" class="btn btn-success">添加</button>
</div>
</form>
</div>
</div>
</div>

這里我通過button喚醒一個(gè)模態(tài)框來添加

最后測(cè)試結(jié)果

excel記錄

數(shù)據(jù)庫記錄

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java語言通過三種方法實(shí)現(xiàn)隊(duì)列的示例代碼

    Java語言通過三種方法實(shí)現(xiàn)隊(duì)列的示例代碼

    這篇文章主要介紹了Java語言通過三種方法來實(shí)現(xiàn)隊(duì)列的實(shí)例代碼,數(shù)組模擬隊(duì)列,通過對(duì)定義的了解,發(fā)現(xiàn)隊(duì)列很像我們的數(shù)組,下面我們通過實(shí)踐給大家詳細(xì)介紹,需要的朋友可以參考下
    2022-02-02
  • 深入探究Java?@MapperScan實(shí)現(xiàn)原理

    深入探究Java?@MapperScan實(shí)現(xiàn)原理

    之前是直接在Mapper類上面添加注解@Mapper,這種方式要求每一個(gè)mapper類都需要添加此注解,麻煩。通過使用@MapperScan可以指定要掃描的Mapper類的包的路徑,這篇文章深入探究Java?@MapperScan的實(shí)現(xiàn)原理
    2023-01-01
  • SpringMVC?Restful風(fēng)格與中文亂碼問題解決方案介紹

    SpringMVC?Restful風(fēng)格與中文亂碼問題解決方案介紹

    Restful就是一個(gè)資源定位及資源操作的風(fēng)格,不是標(biāo)準(zhǔn)也不是協(xié)議,只是一種風(fēng)格,是對(duì)http協(xié)議的詮釋,下面這篇文章主要給大家介紹了關(guān)于SpringMVC對(duì)Restful風(fēng)格支持的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 詳解Java如何利用數(shù)字描述更多的信息

    詳解Java如何利用數(shù)字描述更多的信息

    在數(shù)據(jù)庫里面?,通常我們會(huì)用數(shù)字的遞進(jìn)來描述狀態(tài)等信息?,?但是如果想進(jìn)行更復(fù)雜的操作?,?就有必要對(duì)二進(jìn)制有一定理解了。本文就來趣味性的探討一下?,?如何通過更少的空間描述更多的信息
    2022-09-09
  • Spring?Boot中的max-http-header-size配置方式

    Spring?Boot中的max-http-header-size配置方式

    這篇文章主要介紹了Spring?Boot中的max-http-header-size配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Springboot使用POI實(shí)現(xiàn)導(dǎo)出Excel文件示例

    Springboot使用POI實(shí)現(xiàn)導(dǎo)出Excel文件示例

    本篇文章主要介紹了Springboot使用POI實(shí)現(xiàn)導(dǎo)出Excel文件示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2017-02-02
  • 聊一聊new對(duì)象與Spring對(duì)bean的初始化的差別

    聊一聊new對(duì)象與Spring對(duì)bean的初始化的差別

    這篇文章主要介紹了聊一聊new對(duì)象與Spring對(duì)bean的初始化的差別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java利用遞歸調(diào)用實(shí)現(xiàn)樹形菜單的樣式

    java利用遞歸調(diào)用實(shí)現(xiàn)樹形菜單的樣式

    這篇文章主要給大家介紹了關(guān)于java利用遞歸調(diào)用實(shí)現(xiàn)樹形菜單樣式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Spring @Scheduled的坑及解決

    Spring @Scheduled的坑及解決

    這篇文章主要介紹了Spring @Scheduled的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot快速實(shí)現(xiàn)接口消息加密的過程詳解

    SpringBoot快速實(shí)現(xiàn)接口消息加密的過程詳解

    在項(xiàng)目中,為了保證數(shù)據(jù)的安全,我們常常會(huì)對(duì)傳遞的數(shù)據(jù)進(jìn)行加密,常用的加密算法包括對(duì)稱加密(AES)和非對(duì)稱加密(RSA),博主選取碼云上最簡單的API加密項(xiàng)目進(jìn)行下面的講解,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

普格县| 蒙自县| 平安县| 洛阳市| 岑溪市| 济阳县| 舒城县| 翼城县| 东城区| 高要市| 林甸县| 安宁市| 鹤岗市| 田东县| 论坛| 尉犁县| 景德镇市| 延庆县| 日喀则市| 乌拉特前旗| 稷山县| 旬邑县| 桐乡市| 鄢陵县| 石首市| 四会市| 多伦县| 扎赉特旗| 临邑县| 蒙阴县| 巢湖市| 昌黎县| 荆州市| 通海县| 光山县| 庆城县| 海口市| 沈阳市| 宜黄县| 浪卡子县| 太仆寺旗|