<Java导入Excel> 3.0 Java实现Excel动态模板导入数据

前提:
在<Java导出Excel> 1.0 Java实现Excel动态模板导出 的基础上,我们做动态模板数据的导入!

枚举类:


public enum ErrorCodeEnum {
    NULL_PARAM(900, "参数不能为空"),
    DUPLICATE_USER(9011, "用户已存在"),
    DOWN_TEMPLATE_01(500,"服务异常,模板下载失败!"),
    SERVICE_EXCEPTION(500,"服务异常"),
    DOWN_POSITION_CHECKLIST_01(400,"上传文件不能为空");
    private final int code;

    private final String description;

    ErrorCodeEnum(int code, String description) {
        this.code = code;
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }
}

Controller层:


	/**
     * 导入:表单数据
     * 权限-管理员
     *
     * @param multipartFile
     * @return
     */
    @PostMapping(value = "/uploadListData")
    @AuthInterceptor("mag:getUpload:uploadListData")  // 资源项
    public Result uploadListData(HttpServletRequest request, @RequestParam("file") MultipartFile multipartFile) {
        try {
            if (multipartFile.isEmpty()) {
            	// DOWN_POSITION_CHECKLIST_01(400,"上传文件不能为空");
                return CommonUtil.getErrorInfo(ErrorCodeEnum.DOWN_POSITION_CHECKLIST_01);
            }
            return heimaListService.uploadListData(request, multipartFile);
        } catch (Exception e) {
            log.error("=== uploadListDatais error===:" + e.getMessage(), e);
            // SERVICE_EXCEPTION(500,"服务异常"),
            return CommonUtil.getErrorInfo(ErrorCodeEnum.SERVICE_EXCEPTION);
        }
    }
    

service接口层:

Result uploadListData(HttpServletRequest request , MultipartFile multipartFile) throws Exception;

serviceImpl实现层:


	/*
     *导入:表单数据
     *
     */
    @Override
    public synchronized Result uploadListData(HttpServletRequest request, MultipartFile multipartFile) throws Exception {
    	/*
	     * getHeaderss_1 为导出的模板:
	     * 如果导出模板字段和导入模板字段一致,则可以使用导出的模板数据;
	     * 如果导出模板字段和导入模板字段不一致,则需要对getHeaderss_1 的数据进行调整(具体根据业务调整);
	     * 如:导出数据模板里面有序号这个字段,但是导出模板和导入数据模板不需要这个字段,则自行调整 
	     */ 
    	
        List<Map<String, Object>> headers = getHeaderss_1();
        Result result = CommonUtil.checkExcel(multipartFile, headers);
        if (result != null) {
            return result;
        }
        String[][] data = CommonUtil.getExcelData(multipartFile);
        for (int i = 1; i < data.length; i++) {
            if (data[0].length != headers.size()
                    || data[i].length != headers.size()) {
                return Result.failure("上传清单模板与系统不一致,请重新下载模板!");
            }
        }

        // 插入数据库并返回结果
        return insertList(data, request);
    }
	
	/*
     * 数据入库
     *
     */
    private Result insertList(String[][] data, HttpServletRequest request) throws Exception {
        List<Map<String, Object>> positons = CommonUtil.excelCellToSqlTypes(data, getHeaderss_1());
        List<Map<String, Object>> oldPositons = CommonUtil.excelCellToSqlTypes(data, getHeaderss_1());
        // 获取总数
        int total = oldPositons .size();
        // 批量入库
        batchInsertList(positons,request);
        return Result.success().result(null);
    }
	
	/**
     * 批量入库
     *
     */
    private void batchInsertList(List<Map<String, Object>> xxListData, HttpServletRequest request) {
        List<Map<String, Object>> ListNews = new ArrayList();
        List<Map<String, Object>> queMap = heimaListMapper.getHeimaListAll();  // 查询所有数据

        if(xxListData.size() > 0){
            xxListData.remove(0);  // 删除第一行字段提示;
			// 该处for循环为一段业务逻辑,实际导入可根据业务调整;此处记录单据编号生成思路的代码
            for (int i = 0; i < xxListData.size(); i++) {
                //xxListData.remove(0);  // 第一行元素为字段提示,需删除;

                // 计算单据编号算法:
                String waysOfProbleml = String.valueOf(xxListData.get(i).get("waysOfProbleml"));  // 获取表格当前行数据,字段为:途径
                String month = String.valueOf(xxListData.get(i).get("month"));  // 获取表格当前行数据:月份
                if(month.isEmpty() || month.equals("null")){
                    month = DateUtil.getCurrentDate().substring(0,7);
                }else{
                    month = month.replace("年","-").replace("月","");  // 获取表格当前行数据:稽查月度 转换数据格式
                }
                xxListData.get(i).put("month",month);
                List<Integer> integerList = new ArrayList<>();  // 创建新集合,用于存储:表格中当前行月度与数据库已有数据月度相等时候的单据编号;
                String sqMonth = "";  // 获取数据库查询的当前月份
                if(queMap.size() > 0){  // 循环数据库已有的数据,根据月度获取单据编号排序;
                    for (Map<String, Object> map : queMap) {
                        // 表格中当前行月度与数据库已有数据月度相等,获取数据库中所有数据的单号
                        if(month.equals(map.get("month"))){
                            sqMonth = String.valueOf(map.get("month"));
                            String qu = String.valueOf(map.get("numberNo"));
                            integerList.add(new Integer(Integer.parseInt(qu.substring(qu.length() - 8))));
                        }
                    }
                }
                Collections.sort(integerList);  // 根据单据编号排序;
                String queNo = "";
                if(integerList.size() > 0){
                    queNo = String.valueOf(integerList.get(integerList.size()-1));  // 获取与当前表格数据月份匹配且单据编号最大的编号;
                }
                String numberNo = "";
                // 表单中第一条数据:单据编号的计算需要根据数据库中存在的数据计算;
                if(queMap.size() < 1){
                    //表中第一次插入数据的时候,从0001递增;
                    numberNo = "0001";
                }else{
                    //如果输入的月份与数据库查询的月份相等,则为同月;递增;否则重置清零递增;
                    //if(xxListData.get(i).get("month").equals(sqMonth)){
                    if(month.equals(sqMonth)){
                        numberNo = Integer.toString(Integer.parseInt(queNo.substring(queNo.length() - 4)) + 1);
                    }else{
                        numberNo = "0001";
                    }
                }
                if(waysOfProbleml.equals("员工自主申报")){
                    waysOfProbleml = "ESD";  // Employee self declaration 缩写:ESD
                }
                month = month.replace("-","").substring(2,6);  // 获取表格当前行数据:月度
                String result = CommonUtil.getId(waysOfProbleml + month,Integer.parseInt(numberNo));
                xxListData.get(i).put("numberNo",result);  // 新生成的单据编号添加到表格当前行数据中;
                queMap.add(xxListData.get(i));  // 将新生成单据编号的数据每次都添加到数据库查询的数据中,当作历史数据,每次需重新根据月份匹配最大单据编号;
                ListNews.add(xxListData.get(i));  // 将当前行数据添加新集合,用于数据批量插入;
            }
        }
        if (ListNews.size() > 0) {
            heimaListMapper.uploadListData(ListNews);
        }
    }
    

mapper接口层:

void uploadListData(List<Map<String, Object>> paramList);

mapper.xml层:

	<!-- 表单数据批量入库 -->
    <insert id="uploadListData" parameterType="java.util.List">
        <foreach collection="list" item="question" index="index" separator=";">
            INSERT IGNORE INTO bcg_question_list_form_data
            <foreach collection="question.entrySet()" index="key" separator="," open="(" close=")">
                ${key}
            </foreach>
            VALUES
            <foreach collection="question.entrySet()" item="value" separator="," open="(" close=")">
                #{value}
            </foreach>
        </foreach>
    </insert>

Excel读取数据操作工具类:

package com.itheima.service.common.util;

import com.github.pagehelper.PageHelper;
import com.itheima.service.common.constant.Constants;
import com.itheima.service.common.entity.DeptInfo;
import com.itheima.service.exception.ErrorCodeEnum;
import com.isoftstone.ican.platform.common.tools.model.Result;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import static com.google.common.io.ByteStreams.copy;

public class CommonUtil {
	// linux 下
    public static final String XX_PATH = "listdata"+ File.separator;

    // windows下
	// public static final String XX_PATH = "listdata/";

    /**
     * 获取两个数组的不同元素
     *
     * @param t1
     * @param t2
     * @return
     */
    public static <T> List<T> compare(T[] t1, T[] t2) {
        //将t1数组转成list数组
        List<T> list1 = Arrays.asList(t1);

        for (int i = 0; i < list1.size(); i++) {
            String header = list1.get(i).toString().replace("\n", "");
            list1.set(i, (T) header);
        }
        //用来存放2个数组中不相同的元素
        List<T> list2 = new ArrayList<T>();
        for (T t : t2) {
            if (!list1.contains(t)) {
                list2.add(t);
            }
        }
        return list2;
    }

    /**
     * 获取错误信息
     *
     * @param DUPLICATE_USER
     * @return
     */
    public static Result getErrorInfo(ErrorCodeEnum DUPLICATE_USER) {
        return Result.failure(DUPLICATE_USER.getCode(), DUPLICATE_USER.getDescription());

    }

    /**
     * 获取模板表头信息
     *
     * @param headers
     * @return
     */
    public static List<List<String>> getTemplateHeaders(List<Map<String, Object>> headers) {
        List<List<String>> cells = new ArrayList<List<String>>();
        for (Map<String, Object> header : headers) {
            List<String> headerList = new ArrayList<String>();
            headerList.add(header.get("headerName").toString());
            cells.add(headerList);
        }
        return cells;
    }


    /**
     * 清单上传校验
     *
     * @param multipartFile
     * @param templateHeaders
     * @return
     * @throws Exception
     */
    public static Result checkExcel(MultipartFile multipartFile,
                                    List<Map<String, Object>> templateHeaders) throws Exception {
        String fileName = multipartFile.getOriginalFilename();
        // 校验后缀
        if (!"xls".equals(fileName.split("\\.")[1]) &&
                !"xlsx".equals(fileName.split("\\.")[1])) {
            return Result.failure("上传文件格式不正确,请检查");
        }
        String[][] data = getExcelData(multipartFile);
        // 对excel表头校验
        String[] dataArray = data[0];
        // 查表表头信息
        List<Object> tempHeader = templateHeaders.stream().map(
                e -> e.get("headerName")).collect(Collectors.toList());
        String[] headers = tempHeader.toArray(new String[tempHeader.size()]);
        List<String> list = CommonUtil.compare(dataArray, headers);
        if (list != null && list.size() > 0) {
            return Result.failure(ExcelUtil.getStringMessage(list).toString());
        }
        return null;

    }

    /**
     * 读取excel数据
     *
     * @param multipartFile
     * @return
     * @throws Exception
     */
    public static String[][] getExcelData(MultipartFile multipartFile) throws Exception {
        String[][] data;
        String fileName = multipartFile.getOriginalFilename();
        InputStream inputStream = multipartFile.getInputStream();
        String flag = fileName.substring(fileName.lastIndexOf("."));
        if (Constants.EXCEL_XLSX_VERSION.equals(flag)) {
            data = ExcelUtil.getXlsxData(inputStream, 0);
        } else {
            data = ExcelUtil.getXlsData(inputStream, 0);
        }
        return data;
    }

    /**
     * excel表头转换成sql中的字段
     *
     * @param data
     * @param headers
     * @return
     */
    public static List<Map<String, String>> excelCellToSqlType(
            String[][] data, List<Map<String, Object>> headers) {
        List<Map<String, String>> dataPositons = new ArrayList<Map<String, String>>();
        for (int i = 1; i < data.length; i++) {
            Map<String, String> map = new HashMap<String, String>();
            for (int columnNo = 0; columnNo < data[i].length; columnNo++) {
                String columnName = data[0][columnNo].replace("\n", "");
                String columnValue = data[i][columnNo];
                map.put(columnName, columnValue);
            }
            dataPositons.add(map);
        }
        dataPositons = changeColumnName(dataPositons, headers);
        return dataPositons;
    }
	
    // excel表头转换成sql中的字段2
    public static List<Map<String, Object>> excelCellToSqlTypes(
            String[][] data, List<Map<String, Object>> headers) {
        List<Map<String, Object>> dataPositons = new ArrayList<Map<String, Object>>();
        for (int i = 1; i < data.length; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            for (int columnNo = 0; columnNo < data[i].length; columnNo++) {
                String columnName = data[0][columnNo].replace("\n", "");
                String columnValue = data[i][columnNo];
                map.put(columnName, columnValue);
            }
            dataPositons.add(map);
        }
        dataPositons = changeColumnNames(dataPositons, headers);
        return dataPositons;
    }

    /**
     * 属性名与属性转换
     *
     * @param dataPositons
     * @param headers
     * @return
     */
    private static List<Map<String, String>> changeColumnName(
            List<Map<String, String>> dataPositons,
            List<Map<String, Object>> headers) {
        List<Map<String, String>> dataPositonsNews = new ArrayList<Map<String, String>>();
        for (Map<String, String> xxPostion : dataPositons) {
            Map<String, String> keyPositionNew = new HashMap<String, String>();
            for (Map<String, Object> header : headers) {
                if (!StringUtils.isEmpty(xxPostion.get(header.get("headerName")))) {
                    keyPositionNew.put(header.get("headerField").toString(),
                            xxPostion.get(header.get("headerName")));
                }
            }
            dataPositonsNews.add(keyPositionNew);
        }
        return dataPositonsNews;
    }
	
    // 属性名与属性转换2
    private static List<Map<String, Object>> changeColumnNames(
            List<Map<String, Object>> dataPositons,
            List<Map<String, Object>> headers) {
        List<Map<String, Object>> dataPositonsNews = new ArrayList<Map<String, Object>>();
        for (Map<String, Object> xxPostion : dataPositons) {
            Map<String, Object> keyPositionNew = new HashMap<String, Object>();
            for (Map<String, Object> header : headers) {
                if (!StringUtils.isEmpty(String.valueOf(xxPostion.get(header.get("headerName"))))) {
                    keyPositionNew.put(header.get("headerField").toString(),
                            xxPostion.get(header.get("headerName")));
                }
            }
            dataPositonsNews.add(keyPositionNew);
        }
        return dataPositonsNews;
    }

    public static String getObjectKey(String filePath) {
        return XX_PATH + filePath;
    }

    public static byte[] inputStreamToByte(InputStream input) throws Exception {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        copy(input, output);
        return output.toByteArray();
    }
	
	public static void getPageHelper(Map<String, Object> params) {
        if (params.get("pageNum") != null) {
            PageHelper.startPage(Integer.parseInt(String.valueOf(params.get("pageNum"))),
                    Integer.parseInt(String.valueOf(params.get("pageSize"))));
        }
    }
    
    /**
     * 由年月日时分秒毫秒  生成流水号
     *
     * @return
     */
    public static String getSerialNumber(String strFlag) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String dateString = formatter.format(currentTime);
        return strFlag + dateString;
    }

    /*
     * 自定义:自增流水号工具类
     *
     * @param prefix
     * @param id
     */
    private static final Integer ONE = 1;
    private static final Integer TWO = 2;
    private static final Integer THREE = 3;
    public static String getId(String prefix, Integer id){
        //判断位数
        String s = id + "";
        int count = s.length();
        String producerNum = prefix;
        if (ONE == count){
            producerNum += "000"+ String.valueOf(id);
        }else if (TWO == count){
            producerNum += "00"+ String.valueOf(id);
        }else if (THREE == count){
            producerNum += "0" + String.valueOf(id);
        }else {
            producerNum += String.valueOf(id);
        }
        return producerNum;
    }

}

ExcelUtil 工具类查找:
<Java导出Excel> 1.0 Java实现Excel动态模板导出

你可能感兴趣的:(java,java,excel,python)