单表通用excle导入(只要是单表都可以,只需要传文件跟表名及用户id即可)

首先在controller层的导入方法:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bytx.salary.controller.oa.ExcelUtil;
import com.bytx.salary.controller.sys.BaseController;
import com.bytx.salary.mapper.emp.EmpEntryMapper;
import com.bytx.salary.mapper.emp.InviteMapper;
import com.bytx.salary.model.emp.EmpEntry;
import com.bytx.salary.model.emp.Invite;
import com.bytx.salary.model.emp.InviteResult;
import com.bytx.salary.model.oa.ParameterTable;
import com.bytx.salary.service.emp.EmpEntryService;
import com.bytx.salary.service.emp.InviteService;
import com.bytx.salary.service.oa.TestTableImpl;
import com.bytx.salary.utils.CustomPage;
import com.bytx.salary.utils.ReturnUtil;
import com.bytx.salary.utilsc.ChineseToSpell;
import com.bytx.salary.utilsc.ImportExeclUtil;
import com.bytx.salary.utilsc.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* 导入接口
*
* @return
*/
@ResponseBody
@RequestMapping(value = "/readExcel1", method = RequestMethod.POST)
protected JSONObject readExcel1(@RequestParam MultipartFile file,@RequestParam String currentUserId,@RequestParam String tableName) throws Exception {
Integer result = 0;
List<Map<String, Object>> list=new ArrayList<>();
String table_schema = "bytx_salary";//如果是一个库的话直接设置常量
String table_name = tableName; //这个是页面传过来的参数,也可以传多个表名
String fileName=file.getOriginalFilename();//获取文件名称的方法
List<Map<String, String>> columns = testTableImpl.getField(table_name,table_schema);//查询单表的字段英文及字段注释
for (int j = 0; j < columns.size(); j++) {
Map<String, String> map = columns.get(j);
if (map.get("COLUMN_NAME").toString().equals("uuid") || map.get("COLUMN_NAME").toString().equals("creator_id") || map.get("COLUMN_NAME").toString().equals("creator")||
map.get("COLUMN_NAME").toString().equals("create_time")|| map.get("COLUMN_NAME").toString().equals("modifier") || map.get("COLUMN_NAME").toString().equals("modifier_id")|| map.get("COLUMN_NAME").toString().equals("modify_time") || map.get("COLUMN_NAME").toString().equals("creator_org_id")) {
columns.remove(j);
j--;
}
}
List<ParameterTable> listTable = new ArrayList<>();//将字段注释跟字段英文放到list中去,让它变成一个有序的集合
for (int i = 0; i < columns.size(); i++) {
ParameterTable parameterTable = new ParameterTable();
parameterTable.setCOLUMN_NAME(columns.get(i).get("COLUMN_NAME"));
parameterTable.setCOLUMN_COMMENT(columns.get(i).get("COLUMN_COMMENT"));
listTable.add(parameterTable);
}
Map<Integer, String> map = new HashMap<>();
Map<String, String> map1 = new HashMap<>();

for (int i = 0; i <listTable.size() ; i++) {//将list中的字段英文数据下划线去掉并让下划线的下一个字母大写(就是将字段转换成驼峰)
map.put(i,replaceUnderlineAndfirstToUpper(listTable.get(i).getCOLUMN_NAME(), "_", ""));
map1.put(listTable.get(i).getCOLUMN_COMMENT(),replaceUnderlineAndfirstToUpper(listTable.get(i).getCOLUMN_NAME(), "_", ""));//这是将中文注释跟英文进行对应集合,导入类后面要用
}
list =ImportExeclUtil.readExcel(fileName,file,map,map1,1);//fileName为文件名称,file为文件,map,map1为字段的英文集合,1是开始行数(如果你的导入有中文和英文两行就改成2)
for (int i=0;i<list.size();i++) {//这是将list集合中的map取出并放到一个新的map中去,进行入库的操作
     Map<String, Object> map4 = new HashMap<>();
      Map<String,Object> map3 = list.get(i);
for (String key : map3.keySet()) {
String a = upperCharToUnderLine(key);//由于之前英文字段已经转成驼峰,在这里为了再恢复原本的字段与表进行对应,所以又转了回去
Object b = map3.get(key);
map4.put(a,b);
}
String uuid=UUID.randomUUID().toString().replace("-", "");这是表中自动生成uuid的方法
map4.put("uuid",uuid);
result = inviteService.save(map4,table_name);table_name为动态表名
result++;
}

return result > 0 ?
ReturnUtil.ajaxDone(ReturnUtil.CODE_SUCCESS, "导入成功!") :
ReturnUtil.ajaxDone(ReturnUtil.CODE_FAIL, "导入失败!");

}

下面是下划线转成驼峰,驼峰转成下划线格式的方法:
/**
* 替换字符串并让它的下一个字母为大写
*
* @param srcStr
* @param org
* @param ob
* @return
*/
public static String replaceUnderlineAndfirstToUpper(String srcStr, String org, String ob) {
String newString = "";
int first = 0;
while (srcStr.indexOf(org) != -1) {
first = srcStr.indexOf(org);
if (first != srcStr.length()) {
newString = newString + srcStr.substring(0, first) + ob;
srcStr = srcStr.substring(first + org.length(), srcStr.length());
srcStr = StringUtil.upperFirstChar(srcStr);
}
}
newString = newString + srcStr;
return newString;
}

/**
* 替换字符串恢复下滑线格式
*将字符串中的大写字母变成小写并且将小写之后的字母前面加下划线
* @param srcStr
* @param org
* @param ob
* @return
*/

public static String upperCharToUnderLine(String param) {
Pattern p= Pattern.compile("[A-Z]");
if(param==null ||param.equals("")){
return "";
}
StringBuilder builder=new StringBuilder(param);
Matcher mc=p.matcher(param);
int i=0;
while (mc.find()) {
System.out.println(builder.toString());
System.out.println("mc.start():" + mc.start() + ", i: " + i);
System.out.println("mc.end():" + mc.start() + ", i: " + i);
builder.replace(mc.start()+i, mc.end()+i, "_"+mc.group().toLowerCase());
i++;
}

if('_' == builder.charAt(0)){
builder.deleteCharAt(0);
}
return builder.toString();
}

导入工具类:

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
*
* excel读取工具类
*
* @author daochuwenziyao
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class ImportExeclUtil
{

/**
*
* @param
* @param <T>
* @param fileName 文件名
* @param map 对象中的属性名
* Map<Integer, String> map = new HashMap<>();
* map.put(0, "id");
* map.put(1, "name");
* map.put(2, "age");
*
* @param dataStartIndex 开始行
* @param
* @return
* @throws Exception
*/
public static <T> List<Map<String, Object>> readExcel(String fileName, MultipartFile file, Map<Integer, String> map, Map<String, String> map1,
int dataStartIndex) throws Exception {
//获取文件名后缀判断文件类型
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1,
fileName.length());
Map<Integer, String> map2 = new HashMap<>();

//根据文件类型及文件输入流新建工作簿对象
POIFSFileSystem fi = new POIFSFileSystem(file.getInputStream());
Workbook wb = null;
List<Map<String, Object>> list = new ArrayList<>();
if (fileType.equals("xls")) {
wb = new HSSFWorkbook(fi);
} else if (fileType.equals("xlsx")) {
wb = WorkbookFactory.create(fi);
} else {
System.out.println("您上传的excel格式不正确");
throw new Exception("您上传的excel格式不正确");
}

//获取要取的数据列
Set<Integer> keySet = map.keySet();
// 获取第一个Sheet表
Sheet hssfSheet = wb.getSheetAt(0);
int MAX_ROW=20000;
//设置默认最大行数,当超出最大行数时返回异常
if (hssfSheet != null && hssfSheet.getLastRowNum() > MAX_ROW) {
throw new Exception("Excel 数据超过20000行,请检查是否有空行,或分批导入");
}
System.out.println("readExcel {}"+hssfSheet.getLastRowNum());
// 遍历Excel中的每一行
for (int rowNum = 0; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
        Map<String, Object> map3 = new HashMap<>();
            //获取当前行
Row hssfRow = hssfSheet.getRow(rowNum);
Iterator<Integer> it1 = keySet.iterator();//这个是获取英文map的数量(一张表有多少字段的数量)
while (it1.hasNext()) {//由于我的导入模板只有中文,在这里单独处理
Integer key1 = it1.next();
if (key1 == null) {
throw new Exception("配置map key不能为null");
} else if (key1 >= 0 && key1 < hssfRow.getLastCellNum()) {
//得到中文名
Cell cell = hssfRow.getCell(key1);//这里是得到中文的所有名字
Object val = getCellFormatValue(cell);//这里是获取的所有的名字的值
for (String key2 : map1.keySet()) {//这里是将map1中对应的中文取出来
if (key2.equals(val.toString())) {//这里是将导入的file文件中文和表字段的注释进行对比,一直就加入新的map集合
map2.put(key1, map1.get(key2));
}
}
}
}
//获取要取的数据列
Set<Integer> keySet2 = map2.keySet();
if (rowNum >= dataStartIndex) {
//实例化反射类对象
// Object obj = clazz.newInstance();
//当前行数据为空时,跳出本次循环进入下一行
boolean flag = false;
Iterator<Integer> it = keySet2.iterator();
while (it.hasNext()) {
Integer key = it.next();
if (key == null) {
throw new Exception("配置map key不能为null");
} else if (key >= 0 && key < hssfRow.getLastCellNum()) {
//得到属性名
String attrName = map2.get(key);
//得到属性类型
// Class<?> attrType = BeanUtils.findPropertyType(attrName,
// new Class[]{obj.getClass()});
//得到属性值
Cell cell = hssfRow.getCell(key);//这是file文件读取出来的具体的值
if (cell != null && !("").equals(cell.toString().trim())) {
Object val = getCellFormatValue(cell);//这是将读取出来的值进行类型判断然后进行转换
// Object val = getValue(cell, attrType);
if (StringUtils.isNotBlank((String) val)) {
map3.put(attrName,val);//这是将英文对应的值放入集合中然后再放到list中去
// setter(obj, attrName, val, attrType, rowNum, key, attrName);
flag = true;
}
}
} else {
System.out.println("导入模板非法");
}
}
if (!flag) {
break;
}
list.add(map3);
}
}

return list;
}




/**
* 将字段转为相应的格式
* @param cell
* @return
*/
private static Object getCellFormatValue(Cell cell) {
Object cellValue = null;
if (cell != null) {
//判断cell类型
if(cell.toString().contains("-") && checkDate(cell.toString())){//由于poi对于日期格式的处理能力很弱所以这里是对日期的处理
String ans = "";
try {
ans = new SimpleDateFormat("yyyy/MM/dd").format(cell.getDateCellValue());
} catch (Exception e) {
ans = cell.toString();
}
return ans;
}

switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC: {
short format = cell.getCellStyle().getDataFormat();
if(format == 14 || format == 31){
Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());

}else {
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case Cell.CELL_TYPE_FORMULA: {
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = cell.getDateCellValue();////转换为日期格式YYYY-mm-dd
} else {
cellValue = String.valueOf(cell.getNumericCellValue()); //数字
}
break;
}
case Cell.CELL_TYPE_STRING: {
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
} else {
cellValue = "";
}
return cellValue;
}
/**
* 判断是否是“02-十一月-2006”格式的日期类型
*/
private static boolean checkDate(String str){//上面类型转换的时候发现如日期是
“02-十一月-2006”格式的日期类型就调用这个方法进行处理

String[] dataArr =str.split("-");
try {
if(dataArr.length == 3){
int x = Integer.parseInt(dataArr[0]);
String y = dataArr[1];
int z = Integer.parseInt(dataArr[2]);
if(x>0 && x<32 && z>0 && z< 10000 && y.endsWith("月")){
return true;
}
}
} catch (Exception e) {
return false;
}
return false;
}

}
service层:
import com.bytx.salary.mapper.emp.InviteMapper;
import com.bytx.salary.model.emp.Invite;
import com.bytx.salary.model.emp.InviteResult;
import com.bytx.salary.utils.CustomPage;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
* Created by 13671 on 2020/6/15.
*/
@Service("inviteService")
public class InviteService {

@Autowired
private InviteMapper inviteMapper;




public int save(Map<String,Object> map4,String table_name){
int result =inviteMapper.save(map4,table_name);
return result;
}


}
mapper接口层:
import com.bytx.salary.model.emp.Invite;
import com.bytx.salary.model.emp.InviteResult;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.common.Mapper;

import java.util.List;
import java.util.Map;

/**
* Created by 13671 on 2020/6/15.
*/
@Component
public interface InviteMapper extends Mapper<Invite> {



int save(@Param("map4") Map<String,Object> map4,@Param("table_name")String table_name);

}

mybatis的SQL语句层:
<insert id="save" parameterType="java.util.Map" >
insert into ${table_name}
<foreach collection="map4.keys" separator="," item="key" open="(" close=")">
${key}
</foreach>
values
<foreach collection="map4.keys" item="key" separator="," open="(" close=")">
#{map4[${key}]}
</foreach>



</insert>
原文地址:https://www.cnblogs.com/sukuokuo/p/13328766.html