POI读取Excel数据保存到数据库,并反馈给用户处理信息

  

  今天遇到这么一个需求,将课程信息以Excel的形式导入数据库,并且课程编号再数据库中不能重复,也就是我们需要先读取Excel提取信息之后保存到数据库,并将处理的信息反馈给用户。于是想到了POI读取文件提取数据,也可以利用Jxl读取Excel提取数据。

最终效果:

  对于下面的Excel,总共20条数据。18条在数据库已经存在,最后两条是在同一个excel文件中重复在数据库不存在。

            

反馈结果:(也就是最后两个X6511只保存了一条)

        

思路:

  1.先将Excel文件上传到本地,保存到本地磁盘

  2.读取本地磁盘的Excel,并且提取数据封装成集合。

  3.对提取的信息进行处理,也就是保存数据库,保存数据库之前先判断是否已经存在相同的编号,如果存在就不保存数据库,并且将存在的编号记录到一个集合中,最后根据此集合返回给用户信息。

前端文件上传是layui,后端接收文件是springMVC,处理Excel是POI

0.界面准备文件上传的button

 <button class="layui-btn layui-btn-warm" type="button" id="importCoursesBtn" style="float: right"><i class="layui-icon"></i>导入课程</button>

1.前端:layui的文件上传JS

/********S       导入课程相关操作******/
layui.use([‘layer‘,‘upload‘],function () {//使用文件上传和layer模块
    var layer =layui.layer,upload = layui.upload;
    var uploadInst = upload.render({
        elem: ‘#importCoursesBtn‘,//绑定的元素
        url: contextPath+‘/uploadCourseExcel.do‘,//提交的url
        auto:true,//是否自动上传
        accept:"file",//指定允许上传的文件类型
        multiple:false,//支持多文件上传
        exts:‘xls|xlsx‘,
        done: function(res, index, upload){ //假设code=0代表上传成功
            layer.close(layer.index); //它获取的始终是最新弹出的某个层,值是由layer内部动态递增计算的
            layer.alert(res.msg);
        }
    });

})
/********E       导入课程相关操作******/

2.后端Controller层代码:

主要就是:

  保存文件到本地

  读取本地的excel文件,提取数据

  处理提取之后的数据(也就是调用service层对提取的数据集合进行保存)

  根据Service返回的重复的编号的集合以及提取的数据集合判断添加结果并反馈给用户。

package cn.xm.jwxt.controller.trainScheme;

import cn.xm.jwxt.bean.trainScheme.TCourseBaseInfo;
import cn.xm.jwxt.service.trainScheme.CourseBaseInfoService;
import cn.xm.jwxt.utils.FileHandleUtil;
import cn.xm.jwxt.utils.ResourcesUtil;
import cn.xm.jwxt.utils.ResposeResult;
import cn.xm.jwxt.utils.UUIDUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: qlq
 * @Description 导入课程信息(以Excel模板的形式导入)
 * @Date: 11:04 2018/5/5
 */

/**
 * 导入课程(以Excel的形式导入)
 * 1.导入文件,将文件保存到本地
 * 2.读取Excel提取课程信息
 * 3.进行数据库保存
 * 4.反馈导入信息
 */
@Controller
public class ImportCourseExcel {
    private Logger logger = Logger.getLogger(ImportCourseExcel.class);//日志记录器
    @Autowired
    private CourseBaseInfoService courseBaseInfoService;//课程service
    /**
     * 导入课程信息(以课程信息导入)
     * @param file
     * @return
     */
    @RequestMapping("/uploadCourseExcel")
    public @ResponseBody
    ResposeResult uploadCourseExcel(MultipartFile file){
        ResposeResult resposeResult = new ResposeResult();
        String fileOriName = null;
        String fileNowName = null;
        if(file == null){
            resposeResult.setMsg("请上传正确的Excel文件");
            return resposeResult;
        }
        //1.保存文件到本地
        fileOriName = file.getOriginalFilename();//获取原名称
        fileNowName = UUIDUtil.getUUID2()+"."+ FilenameUtils.getExtension(fileOriName);//生成唯一的名字

        try {
            fileNowName  = FileHandleUtil.uploadSpringMVCFile(file, "courseExcelFileImport", fileNowName);//保存文件
        } catch (Exception e) {
            resposeResult.setMsg("请上传正确的Excel文件");
            logger.error("导入课程信息失败失败",e);
        }
        //2.读取文件
        String fileQualifyName = ResourcesUtil.getValue("path","courseExcelFileImport")+fileNowName;//生成文件全路径
        List<TCourseBaseInfo> tCourseBaseInfos = this.readExcelData(fileQualifyName);//读取的Excel数据
        if(tCourseBaseInfos == null || tCourseBaseInfos.size()==0){
            resposeResult.setMsg("您上传的文件没有课程信息,请重新编辑");
            return resposeResult;
        }
        //3.保存数据库
        List<String> repeatCourseNums = null;
        try {
                repeatCourseNums = courseBaseInfoService.addCourseBaseInfoBatch(tCourseBaseInfos);
        } catch (SQLException e) {
            resposeResult.setMsg("保存数据库的时候出错");
            logger.error("保存数据库出错");
        }
        //4.根据返回结果判断重复的数据与条数。
        int allTotal = tCourseBaseInfos.size();
        // 4.1如果重复的集合为空则证明全部上传成功
        if(repeatCourseNums == null || repeatCourseNums.size()==0){
            resposeResult.setMsg(allTotal+"条课程信息全部上传成功");
        }else {//4.2如果有重复提示哪些重复了
            int repeatSize = repeatCourseNums.size();
            resposeResult.setMsg("总共"+allTotal+"条数据,成功上传"+(allTotal - repeatSize)+"条,重复了"+repeatSize+"条。"+"重复的课程编号为"+repeatCourseNums.toString());
        }
        return resposeResult;
    }

    /**
     * 读取Excel提取数据(返回提取的数据集合)
     * @param fileQualifyName
     * @return
     */
    private List<TCourseBaseInfo> readExcelData(String fileQualifyName) {
        List<TCourseBaseInfo> datas = null;
        File file = new File(fileQualifyName);
        try {
//            获取一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook(FileUtils.openInputStream(file));
//            获取一个工作表两种方式
//            HSSFSheet sheet = workbook.getSheet("sheet0");
//            获取工作表的第二种方式
            HSSFSheet sheet = workbook.getSheetAt(0);
            int firstRow = 1;
//            获取sheet的最后一行
            int lastRow = sheet.getLastRowNum();
            if(lastRow <2){//如果只有1行或者0行就直接退出
                return null;
            }
            datas =  new ArrayList<TCourseBaseInfo>();//用于返回的数据集合
            //循环内不要创建对象引用(集合中存的是对象的引用)
            TCourseBaseInfo courseBaseInfo = null;
            for(int i=firstRow;i<=lastRow;i++){
                courseBaseInfo = new TCourseBaseInfo();
                HSSFRow row = sheet.getRow(i);
                int lastCol = row.getLastCellNum();
                if(lastCol != 14){
                    //如果不是14列就不读这一行了。
                    continue;
                }
                for(int j=0;j<lastCol;j++){
                    HSSFCell cell= row.getCell(j);//获取一个cell
                    if (j == 0) {
                        courseBaseInfo.setCoursenum(cell.getStringCellValue());//课程编号
                        continue;
                    }
                    if (j == 1) {
                        courseBaseInfo.setCourseplatform(cell.getStringCellValue());//课程平台
                        continue;
                    }
                    if (j == 2) {
                        courseBaseInfo.setCoursenature(cell.getStringCellValue());//课程性质
                        continue;
                    }
                    if (j == 3) {
                        courseBaseInfo.setCoursenamecn(cell.getStringCellValue());//中文名称
                        continue;
                    }
                    if (j == 4) {
                        courseBaseInfo.setCoursenameen(cell.getStringCellValue());//英文名称
                        continue;
                    }
                    if (j == 5) {
                        courseBaseInfo.setCredit(cell.getStringCellValue());//学分
                        continue;
                    }
                    if (j == 6) {
                        courseBaseInfo.setCoursehour(cell.getStringCellValue());//学时
                        continue;
                    }
                    if (j == 7) {
                        courseBaseInfo.setTeachhour(cell.getStringCellValue());//讲课时长
                        continue;
                    }
                    if (j == 8) {
                        courseBaseInfo.setExperimenthour(cell.getStringCellValue());//实验时长
                        continue;
                    }
                    if (j == 9) {
                        courseBaseInfo.setComputerhour(cell.getStringCellValue());//上机时长
                        continue;
                    }
                    if (j == 10) {
                        courseBaseInfo.setPracticehour(cell.getStringCellValue());//实践时长
                        continue;
                    }
                    if (j == 11) {
                        courseBaseInfo.setWeeklyhour(cell.getStringCellValue());//周学时分配
                        continue;
                    }
                    if (j == 12) {
                        courseBaseInfo.setScoringway(cell.getStringCellValue());//计分方式
                        continue;
                    }
                    if (j == 13) {
                        courseBaseInfo.setCoursehourmethod(cell.getStringCellValue());//学时单位
                        continue;
                    }
                }
                //读完一行将数据塞进去
                datas.add(courseBaseInfo);
            }
        } catch (IOException e) {
            logger.error("读取上传的Excel出错");
        }
        return datas;
    }
}

Service对提取到的list集合进行批量保存的代码:

  主要就是遍历集合,获取课程编号判断数据库中是否已经存在相同编号的数据,如果已经存在则此条数据不保存数据库并将编号加到重复的list集合。

    @Override
    public int getCountByCourseNum(String courseNum) throws SQLException {
        return tCourseBaseInfoCustomMapper.getCountByCourseNum(courseNum);
    }

    @CacheEvict(value = "coursesFy",allEntries =true )//清掉分页的redis缓存
    @Override
    public boolean addCourseBaseInfo(TCourseBaseInfo courseBaseInfo) throws SQLException {
        //如果传下来的课程信息的id为空,就用UUID生成一个ID
        if(ValidateCheck.isNull(courseBaseInfo.getCourseid())){
            courseBaseInfo.setCourseid(UUIDUtil.getUUID2());
        }
        // remark1用于标记是否正在使用,1代表正在使用,0代表已经删除。
        if(ValidateCheck.isNull(courseBaseInfo.getRemark1())){
            courseBaseInfo.setRemark1(DefaultValue.IS_USE);
        }
        return tCourseBaseInfoMapper.insert(courseBaseInfo)>0?true:false;
    }

    @Override
    public List<String> addCourseBaseInfoBatch(List<TCourseBaseInfo> courseBaseInfos) throws SQLException {
        //1.遍历集合进行添加。
        //1.1如果已经存在相同的课程编号,将该课程的编号加到返回的集合中,用于提示哪些编号重复了
        List<String> repeatCourseNums = new ArrayList<String>();
        for(TCourseBaseInfo tCourseBaseInfo :courseBaseInfos){
            //如果课程编号为空结束本次循环开始下一次
            if(ValidateCheck.isNull(tCourseBaseInfo.getCoursenum())){
                continue;
            }
            //根据数据库是否已经存在相同的课程编号决定是否可以保存课程信息
            int result = this.getCountByCourseNum(tCourseBaseInfo.getCoursenum());
            if(result >= 1){//如果存在就不添加并保存到重复的元素集合
                repeatCourseNums.add(tCourseBaseInfo.getCoursenum());
            }else {//不存在就可以添加
                this.addCourseBaseInfo(tCourseBaseInfo);
            }
        }
        return repeatCourseNums;
    }

解释:

1.文件保存的工具方法:

    /*******  S针对SptingMVC的上传文件的处理  *************/
    /**
     * 专门针对SpringMVC的文件上传操作
     * @param multipartFile 文件参数
     * @param propertiesKey  需要读取的path里面的key
     * @param fileName  文件名字,比如:    ce5bd946fd43410c8a26a6fa1e9bf23c.pdf
     * @return 返回值是最后的文件名字,如果是word需要转成pdf,1.doc返回值就是1.pdf
     */
    public static String uploadSpringMVCFile(MultipartFile multipartFile,String  propertiesKey,String fileName) throws Exception {
        String fileDir = FileHandleUtil.getValue("path", propertiesKey);// 获取文件的基本目录
        //1.将文件保存到指定路径
        multipartFile.transferTo(new File(fileDir+fileName));//保存文件
        //2.根据文件后缀判断文件是word还是pdf,如果是word需要转成pdf,其他的话不做处理
        String fileNameSuffix = FilenameUtils.getExtension(fileName);//调用io包的工具类获取后缀
        if("doc".equals(fileNameSuffix)||"docx".equals(fileNameSuffix)){//如果后缀是doc或者docx的话转为pdf另存一份
            String fileNamePrefix = FilenameUtils.getBaseName(fileName);//获取文件前缀名字
            Word2PdfUtil.word2pdf(fileDir+fileName,fileDir+fileNamePrefix+".pdf");//进行word转换pdf操作
            fileName = fileNamePrefix+".pdf";//并将文件的名字换成新的pdf名字
        }
        return fileName;
    }
    /*******  E针对SptingMVC的上传文件的处理  *************/

原文地址:https://www.cnblogs.com/qlqwjy/p/8994463.html

时间: 2024-10-16 13:20:16

POI读取Excel数据保存到数据库,并反馈给用户处理信息的相关文章

通过读取excel数据和mysql数据库数据做对比(二)-代码编写测试

通过上一步,环境已搭建好了. 下面开始实战, 首先,编写链接mysql的函数conn_sql.py import pymysql def sql_conn(u,pwd,h,db): conn=pymysql.connect(user=u,passwd=pwd,host=h,db=db) #print("连接数据库"+db+"成功了!!") return conn 在编写,查询数据库的语句:sql.py import pymysql import conn_sql d

Java读取excel数据保存入库

Java开发读取excel表格数据入库保存: List<Map<String, Object>> list = null; String filePath = filePaths + "/" + userID + "/" + accountID + "/" + busDate + "/"; String fileName = FileUpload.fileUp(file, filePath, "

POI读取Excel数据

所需jar包: xmlbeans-2.3.0.jar poi-ooxml-schemas-3.8-20120326.jar poi-ooxml-3.8-20120326.jar poi-3.8-20120326.jar dom4j-1.6.1.jar // 本例为本地路径的文件,如果是从服务器或者插件上转之后的file对象,需要通过一定手段进行转换, 提供一种参考: File tempFile = File.createTempFile("random", suffix); FileU

通过读取excel数据和mysql数据库数据做对比(一)-win环境准备

要想操作excel和mysql首先需要安装python,然后是安装excel和mysql插件: 第一步安装python: 直接百度搜索,下载安装就可以了. 第二步安装excel插件: 首先到这个http://pypi.python.org/pypi/xlrd网址下载插件: 由于这个网站打开缓慢(国内打开国外网站的通病),可以到我这个网盘下载:下载 下载后,解压到一个固定目录,比如:我解压到d:\excel下 然后按ctrl+c打开运行cmd 进入到解压目录下(默认是c盘,进入d盘可以直接输入d:

java的poi技术读取Excel数据到MySQL

这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 :java的jxl技术导入Excel  项目结构: Excel中的测试数据: 数据库结构: 对应的SQL: 1 CREATE TABLE `student_info` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `no` varchar(20) DEFAU

NPOI操作excel——利用反射机制,NPOI读取excel数据准确映射到数据库字段

> 其实需求很明确,就是一大堆不一样的excel,每张excel对应数据库的一张表,我们需要提供用户上传excel,我们解析数据入库的功能实现. 那么,这就涉及到一个问题:我们可以读出excel的表头,但是怎么知道每个表头具体对应数据库里面的字段呢? 博主经过一段时间的思考与构思,想到一法:现在的情况是我们有excel表A,对应数据库表B,但是A与B具体属性字段的映射关系我们不知.那我们是不是可以有一个A到B的映射文件C呢? 我想,说到这,大家就很明了了... 第一步:为每张excel创建一个与

java的poi技术读取Excel数据

这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: java的poi技术读取Excel数据到MySQL 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术 :java的jxl技术导入Excel  下面是本文的项目结构: 项目中所需要的jar文件: 所用的Excel数据(2003-2007,2010都是一

读取excel数据到数据库里

用的是jxlJar /** * 读取excel数据到数据库里 */ private void readExcelToDB() { new Thread(new Runnable() { @Override public void run() { try { String filePath = "/sdcard/"; String fileName = "307322.xlsx"; File file = new File(filePath, fileName); F

将Excel数据导入mysql数据库的几种方法

将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面和大家分享一下: 一.用java来将Excel表格中的数据转到mysql中 这是我们用的第一种方法,就是在java找你感谢个类,然后这个类会将Excel表格中的数据存储到内存里,然后再从内存中读出来插入到数据库中,但是要 注意了,这里是存储到String[ ]数组里面,所以取出来的数据也是Strin