美文网首页
java POI导入导出Excel数据

java POI导入导出Excel数据

作者: 小波同学 | 来源:发表于2018-10-09 20:42 被阅读149次

    主要的难点在service层解析excel表格数据这里,因为java这里有好多种数据,一旦excel表格里面不是java对应的数据类型就会报错。还有就是在数据库批量导入的时候mybatis有大小限制的

    首先是导入前的下载模板

    public class HolidayConfigController {
    @GetMapping(value = "/downloadTemplate")
        public void downloadTemplate(HttpServletResponse response, HttpServletRequest request){
            log.info("HolidayController.downloadTemplate success Enter this method");
            try {
                //生成Excel文件
                HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
                HSSFSheet sheet = hssfWorkbook.createSheet("Sheet0");
                // 设置表格默认列宽度为15个字节
                sheet.setDefaultColumnWidth((short)15);
                HSSFRow headRow = sheet.createRow(0);
                headRow.createCell(0).setCellValue("节假日日期");
                headRow.createCell(1).setCellValue("节假日描述");
                HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum()+1);
                dataRow.createCell(0).setCellValue("2018-10-01");
                dataRow.createCell(1).setCellValue("国庆节");
                dataRow.createCell(2).setCellValue("请严格按此格式录入数据");
                response.setContentType("application/vnd.ms-excel;charset=UTF-8");
                String filename = "节假日数据导入模板.xls";
                String agent = request.getHeader("user-agent");//获得游览器
                String downloadFilename = FileUtil.encodeDownloadFilename(filename, agent); //使用工具类解决文件乱码的问题
                response.addHeader("Content-Disposition", "attachment;filename="+downloadFilename);
                ServletOutputStream outputStream = response.getOutputStream();
                hssfWorkbook.write(outputStream);
                //关闭
                hssfWorkbook.close();
            } catch (IOException e) {
                log.error("HolidayController.downloadTemplate Exception",e);
            }
        }
    

    使用FileUtil工具类处理因浏览器不同导致的乱码问题

    public class FileUtil {
        /**
         * 下载文件时,针对不同浏览器,进行附件名的编码
         *
         * @param filename
         *            下载文件名
         * @param agent
         *            客户端浏览器
         * @return 编码后的下载附件名
         * @throws IOException
         */
        public static String encodeDownloadFilename(String filename, String agent)
                throws IOException {
            if (agent.contains("Firefox")) { // 火狐浏览器
                filename = "=?UTF-8?B?"
                        + new BASE64Encoder().encode(filename.getBytes("utf-8"))
                        + "?=";
                filename = filename.replaceAll("\r\n", "");
            } else { // IE及其他浏览器
                filename = URLEncoder.encode(filename, "utf-8");
                filename = filename.replace("+"," ");
            }
            return filename;
        }
    }
    

    其次是导入Execl数据,这里分2003版和2007版两个版本,同时用一种解析方式解析

    @PostMapping(value = "/importExecl")
        public PojoResult importExecl(@RequestParam("file")MultipartFile file){
            try{
                InputStream inputStream = file.getInputStream();
                if(!inputStream.markSupported()) {
                    inputStream = new PushbackInputStream(inputStream, 8);
                }
                if(POIFSFileSystem.hasPOIFSHeader(inputStream)) {
                    log.info("HolidayController.importExecl Execl is 2003 and below");
                    Workbook workbook = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream()));
                    String importXls = HolidayConfigService .importXlsOrXlsx(workbook);
                    if("success".equals(importXls)){
                        log.info("HolidayController.importExecl Execl data import successfully");
                        return PojoResultUtil.success(Boolean.TRUE);
                    }
                    log.error("HolidayController.importExecl Execl data import failed");
                    ProductionMessageCode.BATCH_IMPORT_FAILURE.setMessage(importXls);
                    return PojoResultUtil.fail(ProductionMessageCode.BATCH_IMPORT_FAILURE);
                }else if(POIXMLDocument.hasOOXMLHeader(inputStream)){
                    log.info("HolidayController.importExecl Execl is version 2007 and above");
                    Workbook  workbook = new XSSFWorkbook(file.getInputStream());
                    String importXls = HolidayConfigService .importXlsOrXlsx(workbook);
                    if("success".equals(importXls)){
                        log.info("HolidayController.importExecl Execl data import successfully");
                        return PojoResultUtil.success(Boolean.TRUE);
                    }
                    log.error("HolidayController.importExecl Execl data import failed");
                    ProductionMessageCode.BATCH_IMPORT_FAILURE.setMessage(importXls);
                    return PojoResultUtil.fail(ProductionMessageCode.BATCH_IMPORT_FAILURE);
                }else {
                    log.error("HolidayController.importExecl Execl Format does not exist");
                    return PojoResultUtil.fail(ProductionMessageCode.EXECL_NOT_EXISTS);
                }
            }catch (Exception e){
                log.error("HolidayController.importExecl Execl data import Execption",e);
                return PojoResultUtil.fail(ProductionMessageCode.QUERY_FAIL);
            }
    }
    

    然后是service层的解析方式

    public class HolidayConfigService {
        @Transactional
        public String importXlsOrXlsx(Workbook workbook){
            UserInfo userInfo = UserInfoThreadLocal.get();
            //获取Excel第一个sheet页
            DataFormatter formatter = new DataFormatter();
            List<HolidayConfigDO> holidayConfigs = new ArrayList<>();
            //定义错误信息记录集合
            List<String> list = new ArrayList<>();
            for(int numOfSheet = 0;numOfSheet < workbook.getNumberOfSheets(); numOfSheet++){
                Sheet sheets =workbook.getSheetAt(numOfSheet);
                list.add("第Sheet" + numOfSheet +"页");
                //遍历行row
                for(int rowNum = 0; rowNum<=sheets.getLastRowNum();rowNum++){
                    Row row = sheets.getRow(rowNum);
                    if(row.getRowNum()==0){
                        //如果是第一行直接跳出本次循环
                        continue;
                    }
                    HolidayConfigDO holidayConfigDO = new HolidayConfigDO();
                    //将每一行数据的每一单元格数据取出
                    try {
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        String dateCellValue = dateFormat.format(row.getCell(0).getDateCellValue());
                        if(StringUtils.isEmpty(dateCellValue)){
                            list.add("第"+(rowNum+1)+"行,第1格节假日日期不能为空");
                        }else{
                            Date day = dateFormat.parse(dateCellValue);
                            holidayConfigDO.setDay(day);
                        }
                    } catch (Exception e) {
                        list.add("第"+(rowNum+1)+"行,第1格节假日日期格式错误");
                    }
                    String description = formatter.formatCellValue(row.getCell(1));
                    if(StringUtils.isEmpty(description)){
                        list.add("第"+(rowNum+1)+"行,第2格节假日描述不能为空");
                    }else{
                        holidayConfigDO.setDescription(description);
                    }
                    holidayConfigDO.setDeleted(false);
                    holidayConfigDO.setType((byte)1);
                    holidayConfigDO.setCreator(userInfo.getEmpId());
                    holidayConfigDO.setModifier(userInfo.getEmpId());
                    holidayConfigs.add(holidayConfigDO);
                }
                //如果没有错误就将错误记录集合数据清空
                if(!CollectionUtils.isEmpty(list) && list.size() == 1){
                    list.remove(0);
                }
            }
            if(!CollectionUtils.isEmpty(list)){
                return list.toString();
            }
            holidayConfigManager.batchInsertHolidayConfig(holidayConfigs);
            return "success";
        }
    

    在附上批量插入数据的Mapper.xml文件

    <insert id="batchInsertHolidayConfig">
            insert into dcc_holiday_config
            (gmt_create, gmt_modified, creator, modifier,day,type,is_deleted,description)
            values
            <foreach collection ="holidayConfigs" item="holidayConfig" index= "index" separator =",">
                (
                current_timestamp,
                current_timestamp,
                #{holidayConfig.creator,jdbcType=VARCHAR},
                #{holidayConfig.modifier,jdbcType=VARCHAR},
                #{holidayConfig.day,jdbcType=DATE},
                #{holidayConfig.type,jdbcType=TINYINT},
                #{holidayConfig.deleted,jdbcType=BIT},
                #{holidayConfig.description,jdbcType=VARCHAR}
                )
            </foreach >
            ON DUPLICATE KEY UPDATE
            gmt_create = values (gmt_create),
            gmt_modified = values (gmt_modified),
            creator = values (creator),
            modifier = values (modifier),
            day = values (day),
            type = values (type),
            is_deleted = values (is_deleted),
            description = values (description)
        </insert>
    

    相关文章

      网友评论

          本文标题:java POI导入导出Excel数据

          本文链接:https://www.haomeiwen.com/subject/ndgyaftx.html