【Java】【46】导入Excel到数据库

前言:

业务场景:用户提供Excel表,在页面上点击“导入按钮”,系统读取Excel中的数据,存到对应的数据库

注:

1,目前仅提供导入简单的Excel表,没有合并单元格,只能读取单页sheet

2,方法里用到了具体业务场景的实体类,所以适用性不是很强,其他场景要用的话,还需要修改代码。但是也具有一定的参考性,所以先记录下来。我的后续思路是:在 工具类(ReadExcelUtil) 里根据导入的Excel表头确定要处理的字段名,然后拼成json格式的数据,传到Service层,再做处理。之后再做更新 //TODO

3,用的jar包:POI

正文:

html:

<div>
    <span><input type="file" id="upfile" name="upfile" placeholder=""/></span>
    <button onclick="importExp();">导入</button>
    <span>格式:.xls</span>
</div>

JS:

function importExp() {
    var name = $("#upfile").val();
    var file =  $("#upfile")[0].files[0];
    // ajax...
}

Java:

Controller层

@ApiOperation(value = "导入Excel")
@RequestMapping(value="excel/import", method = RequestMethod.POST)
public void importExcel(MultipartFile file) {
    return this.theService.importExcel(file);
}

Service层

public void importExcel(MultipartFile file) {
    if(file.isEmpty()){
        //请先选择Excel文件。是否把报错等信息返回到前端,视情况而定。
        return;
    }

    Result readResult = ReadExcelUtil.readExcel(file);  //Result是封装了返回值的类,相当于实体类

    if(readResult.getCode() != 0){
        //错误:readResult.msg
        return;
    }
    List<Award> list = (List<Award>) readResult.getData(); //Award是数据库表对应的实体类 

    //获取了list之后,insert到数据库...
}

工具类:

ReadExcelUtil

package com.bf.base.utils;

import com.bf.base.entity.DripAward;
import com.bf.base.params.Result;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class ReadExcelUtil {

    /**
     * 读取 单页sheet,返回一个集合
     * @return
     */
    public static Result<?> readDripAwardExcel(MultipartFile file) {
        Result result = new Result<>();
        InputStream is = null;
        Workbook wb = null;
        String fileName = file.getOriginalFilename();
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());

        try {
            is = file.getInputStream();

            if (fileType.equals("xls")) {
                wb = new HSSFWorkbook(is);
            } else if (fileType.equals("xlsx")) {
                wb = new XSSFWorkbook(is);
            } else {
                return new Result<>(Result.FAIL, "读取的不是excel文件", null, null);
            }

            int sheetSize = wb.getNumberOfSheets();//有多少sheet页
            if(sheetSize >= 2){
                return new Result<>(Result.FAIL, "请核对Excel的页数", null, null);
            }

            Sheet sheet = wb.getSheetAt(0);
            result = sheetData2List(sheet); //关键,sheet表数据 转 集合

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    //获取数据
    private static Result sheetData2List(Sheet sheet) {
        Result result = new Result<>();
        List<Award> awards = new ArrayList<>();
        int CELL_SIZE = 3; //excel固定三列(编码、金额)
        int rowSize = sheet.getLastRowNum() + 1;

        for (int j = 0; j < rowSize; j++) { //读取每一行
            Row row = sheet.getRow(j);
            if (row == null) {
                continue;
            }

            if(row.getLastCellNum() != CELL_SIZE){
                result.setCode(2);
                result.setMsg("第"+ j +"行数据异常,请核对后再上传!");
                return result;
            }

            if (j == 0) {
                continue;
            } else {
                DripAward rowObj = new DripAward();
                for (int k = 0; k < CELL_SIZE; k++) { //获取列的数据
                    Cell cell = row.getCell(k);
                    String value = getCellFormatValue(cell);
                    switch (k) {
                        case 0:
                            rowObj.setCode(AESUtil.encrypt(value));
                            break;
                        case 1:
                            rowObj.setAmount(Double.parseDouble(value));
                            break;
                        case 2:
                            rowObj.setClassify(Integer.parseInt(value));
                            break;
                        default:
                            break;
                    }
                }
                awards.add(rowObj);
            }
        }

        result.setCode(0);
        result.setData(awards);
        return result;
    }

    //获取列的数据
    private static String getCellFormatValue(Cell cell) {
        String cellvalue = "";
        if (cell != null) {
            CellType cellType = cell.getCellTypeEnum();
            switch (cellType) {
                case NUMERIC: {
                    if(String.valueOf(cell.getNumericCellValue()).indexOf("E") == -1){
                        cellvalue =  String.valueOf(cell.getNumericCellValue());
                    }else {
                        cellvalue =  new DecimalFormat("#").format(cell.getNumericCellValue());
                    }
                    break;
                }
                case STRING:
                    cellvalue = cell.getRichStringCellValue().getString();
                    break;
                default:
                    cellvalue = "-";
            }
        }

        return cellvalue;
    }
}

其他:

Result (封装了返回值的类,相当于实体类)

package com.bf.base.params;

import org.apache.commons.lang.StringUtils;

/**
 * 传给前端数据的统一格式
 * code = 0时,表示调用成功
 * 其余code均表示调用接口异常,异常时,标明异常码,并给出msg和detail注释,同步文档
 */
public class Result<T> {

    private int code;//状态返回码

    private String msg;//返回码描述

    private String detail;//错误详细描述或返回码对应处理方案

    private T data;//返回的主体数据

    public static final int FAIL = -1;

    public static final int SUCCESS = 0;

    @Override
    public String toString() {
        return "Result [code=" + code + ", msg=" + msg + ", detail=" + detail + ", data=" + data + "]";
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}

Award(数据库表对应的实体类)

public class Award {
    private String code;

    private Double amount;

    private int classify;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Double getAmount() {
        return amount;
    }

    public void setAmount(Double amount) {
        this.amount = amount;
    }

    public int getClassify() {
        return classify;
    }

    public void setClassify(int classify) {
        this.classify = classify;
    }
}

原文地址:https://www.cnblogs.com/huashengweilong/p/11363014.html

时间: 2024-08-29 16:22:22

【Java】【46】导入Excel到数据库的相关文章

.Net core 使用NPOI 直接导入Excel到数据库(即不先将Excel保存到服务器再读取文件到数据库)

原文:.Net core 使用NPOI 直接导入Excel到数据库(即不先将Excel保存到服务器再读取文件到数据库) 1 /// <summary> 2 /// 导入信息 3 /// </summary> 4 /// <param name="file"></param> 5 /// <returns></returns> 6 /// /Public/PublicPool/ImportCustomer 7 pub

一步步实现ABAP后台导入EXCEL到数据库【1】

在SAP的应用当中,导入.导出EXCEL文件的情况是一个常见的需求,有时候用户可能有大量的数据需要定期导入到SAP的数据库中.这种情况下,使用导入程序在前台导入可能要花费不少的时间,如果能安排导入程序为后台作业,既可以节约用户的时间,也可以有效利用闲时的服务器资源.下面来介绍一下相关的知识和具体实践办法. 本文链接:http://www.cnblogs.com/hhelibeb/p/5912330.html 原创内容,转载请注明 1,定义结构 首先,准备一个EXCEL文件.假设一个相对简单的情景

java poi 导入excel

最近项目需要导入excel,网上有很多例子,自己整合记录下,兼容2003和2007,暂时没有添加图片处理功能. 所需jar包  http://pan.baidu.com/s/1sjPuWDR package example.poi; import java.io.*; import java.text.DecimalFormat; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; impor

导入Excel至数据库——程序实现

说明 承接上一篇博客,本篇博文将提供一种实现Excel数据导入数据库表的具体C#实现,其实,如果只针对单纯的一个业务开发,不用想太多内容的,只要将Excel数据转换为DataTable后具体操作,也就完成了,但如果要想写出能够应对多个需求业务的程序的时候就不得不想一些能够复用的方法了.废话少说,还是具体看一下具体的实现过程: 再次列一下我们的功能需求点: 换列名--中文-属性名称(字段名称) 必要性--必要列.行数据 去重复--Excel数据的重复.Excel与DataTable数据的重复 默认

java easyreport 导入excel、 txt 数据简单实现(一)

一直在看博客,却不知道怎么写,但是总是想写点什么,犹豫了两三天,决定还是写点东西吧,来和大家分享下. 今年上半年时候接到了一个需求,具体什么需求就不说了,要求导入excel数据,并提示每一行错误信息.接到手后,查看之前的导入excel报表的代码,发现只有初始化workBook和根据cell获取cell 字符串值得通用方法.觉得可利用的东西太少了,于是决定就构建一个通用的实现导入excel报表的工具包. 实现思路大致是这样的: 提供模板,模板包含读起始行.属性模板集合.读批次.校验出错中端. 添加

java多线程导入excel(poi)

导入excel util 1 /** 2 * @Description: excel导入工具类 3 4 * @Author: hg 5 6 * @CreateDate: 2019/6/4 11:58 7 8 */ 9 @SuppressWarnings("all") 10 public class POIUtil<T> { 11 12 private Logger logger = LoggerFactory.getLogger(this.getClass()); 13 1

java poi导入EXCEL

import jxl.DateCell; import jxl.NumberCell; import org.apache.log4j.Logger; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.use

Java POI导入Excel文件

今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar poi-excelant-3.8-20120326.jar poi-ooxml-3.8-20120326.jar poi-ooxml-schemas-3.8-20120326.jar poi-scratchpad-3.8-20120326.jar xmlbeans-2.3.0.jar 附上百度云盘

ASP.NET MVC导入excel到数据库

MVC导入excel和webform其实没多大区别,以下为代码: 视图StationImport.cshtml的代码: @{ ViewBag.Title = "StationImport"; Layout = "~/Areas/Admin/Views/Shared/_index.cshtml"; } @using (Html.BeginForm("StationImport", "Station", FormMethod.Po