0
点赞
收藏
分享

微信扫一扫

将Excel数据批量导入到数据库(项目案例)

你在工作中是否遇到这样的问题?数据一般存放在Excel表中,逐条迁移到数据库中太麻烦,而且很多时候企业的数据量都是以万起步,单条导入显然不现实。那么该如何解决呢?

我们今天就给大家介绍一个用途非常广泛的功能:批量导入,在很多系统中,这也是必须实现的功能。而且当Excel表结构越复杂时,实现的难度就越高。

不管项目如何复杂,原理却基本相同,一般是前台页面选择Excel文件,后台获取后进行数据转化,然后循环执行​​Sql语句​​即可,了解这些原理后,一切也就变得简单。

下面为了重点演示,项目进行简化,只有批量导入功能,将Excel数据导入到Mysql数据库中。

Mysql数据库user表结构

将Excel数据批量导入到数据库(项目案例)_Java

Excel中数据

将Excel数据批量导入到数据库(项目案例)_Java_02


如果Excel中必填项数据为空,提示导入失败,报告错误信息及位置,项目演示图:

将Excel数据批量导入到数据库(项目案例)_数据库_03


如果数据正确,提示导入数据库成功:

将Excel数据批量导入到数据库(项目案例)_Java_04

具体实现过程

首先是JSP页面,name的名称是重点:

<form action="${pageContext.request.contextPath }/excelsave.action" method="post" enctype="multipart/form-data">
<input type="file" name="fileinput" multiple="multiple"/>
<button type="submit" name="subimit">上传</button>
</form>

前台点击上传后跳转到action处理,action中首先定义:

private File fileinput;

private String fileinputFileName;

然后在方法体中直接调用:


ExcelUtil(fileinput);

ExcelUtil是处理Excel工具类,直接使用,代码如下:

@SuppressWarnings("rawtypes")
public class ExcelUtil {

public FileInputStream fis ;
public HSSFWorkbook workBook;
public HSSFSheet sheet;
public XMLUtil parseXmlUtil;
public StringBuffer errorString;


public String curEntityCode;


public Map curEntityHeadMap ;


public Map curEntityColRequired;


public List listDatas ;


public ExcelUtil(File excelFile){
try {
if(excelFile == null){
throw new FileNotFoundException();
}
fis = new FileInputStream(excelFile);
workBook = new HSSFWorkbook(fis);
parseXmlUtil = new XMLUtil();
errorString = new StringBuffer();
readExcelData();

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



public void readExcelData(){
int sheetSize = workBook.getNumberOfSheets();
for(int i=0;i<sheetSize;i++){
sheet = workBook.getSheetAt(i);
String entityName = workBook.getSheetName(i);
readSheetData(sheet,entityName);
}

}


public void readSheetData(HSSFSheet sheet,String entityName){

int rowNumbers = sheet.getPhysicalNumberOfRows();
Map ent = (Map) parseXmlUtil.getEntityMap().get(entityName);
this.setCurEntityCode((String) ent.get("code"));
if(rowNumbers == 0){
System.out.println("excel中数据为空!");
errorString.append(Constans.ERROR_EXCEL_NULL);
}
List colList = (List) parseXmlUtil.getColumnListMap().get(entityName);
int xmlRowNum = colList.size();
HSSFRow excelRow = sheet.getRow(0);
int excelFirstRow = excelRow.getFirstCellNum();
int excelLastRow = excelRow.getLastCellNum();
if(xmlRowNum != (excelLastRow-excelFirstRow)){
System.out.println("xml列数与excel列数不相符,请检查");
errorString.append(Constans.ERROR_EXCEL_COLUMN_NOT_EQUAL);
}
readSheetHeadData(sheet);

readSheetColumnData(sheet,entityName);

}


@SuppressWarnings({ "unchecked", "static-access"})
public void readSheetHeadData(HSSFSheet sheet){

Map headMap = new HashMap();
curEntityHeadMap = new HashMap();
curEntityColRequired = new HashMap();
HSSFRow excelheadRow = sheet.getRow(0);
int excelLastRow = excelheadRow.getLastCellNum();
String headTitle = "";
for(int i=0;i<excelLastRow;i++){
HSSFCell cell = excelheadRow.getCell(i);
headTitle = this.getStringCellValue(cell).trim();
if(headTitle.endsWith("*")){
curEntityColRequired.put(this.getCurEntityCode()+"_"+headTitle,true);
}else{
curEntityColRequired.put(this.getCurEntityCode()+"_"+headTitle,false);
}
headMap.put(i, headTitle);
}
curEntityHeadMap.put(this.getCurEntityCode(), headMap);
}


@SuppressWarnings({ "unchecked", "static-access" })
public void readSheetColumnData(HSSFSheet sheet,String entityName){

HSSFRow excelheadRow = sheet.getRow(0);
int excelLastcell = excelheadRow.getLastCellNum();
int excelRowNum = sheet.getLastRowNum();
Map headMap = (Map) this.getCurEntityHeadMap().get(this.getCurEntityCode());
Map colMap = parseXmlUtil.getColumnMap();
listDatas =new ArrayList();

for(int i=1;i<excelRowNum+1;i++){
HSSFRow columnRow = sheet.getRow(i);
if(columnRow != null){
Map curRowCellMap = new HashMap();
for(int j =0; j<excelLastcell;j++){
int cout = headMap.get(j).toString().indexOf("*");
String headTitle ="";
if(cout == -1){
headTitle = headMap.get(j).toString();
}else{
headTitle = headMap.get(j).toString().substring(0, cout);
}
Map curColMap = (Map) colMap.get(entityName+"_"+headTitle);
String curColCode = (String) curColMap.get("code");
String curColType = (String) curColMap.get("type");
HSSFCell colCell = columnRow.getCell(j);
String value =this.getStringCellValue(colCell);
if(value != null){
value = value.trim();
}
String xmlColType = (String) curColMap.get("type");
int intVal = 0;
if(xmlColType.equals("int")){
if(value != null) {
intVal = Integer.valueOf(value);
}
curRowCellMap.put(curColCode, intVal);
}else{
curRowCellMap.put(curColCode, value);
}

validateCellData(i+1,j+1,colCell,entityName,headTitle,curColType,listDatas);
}
listDatas.add(curRowCellMap);
}
}

if(this.getErrorString().length() ==0){
saveExcelData(entityName);
System.out.println("导入数据库成功");
}else{

String[] strArr = errorString.toString().split("<br>");
for(String s: strArr){
System.out.println(s);
}

}


}

@SuppressWarnings("static-access")
public void validateCellData(int curRow,int curCol,HSSFCell colCell,String entityName,String headName,String curColType,List listDatas){

List rulList = (List) parseXmlUtil.getColumnRulesMap().get(entityName+"_"+headName);
if(rulList != null && rulList.size()>0){
for(int i=0 ; i<rulList.size() ; i++){
Map rulM = (Map) rulList.get(i);
String rulName = (String) rulM.get("name");
String rulMsg = (String) rulM.get("message");
String cellValue = "";
if(this.getStringCellValue(colCell)==null) {

}else {
cellValue = this.getStringCellValue(colCell).trim();
}
if(rulName.equals(Constans.RULE_NAME_NULLABLE)){
if(cellValue.equals("")||cellValue == null){
errorString.append("导入失败,错误信息:第"+curRow+"行,第"+curCol+"列:"+rulMsg+"<br>");
}
}


}

}
}


@SuppressWarnings("unchecked")
public void saveExcelData(String entityName){

List<User> users= new ArrayList();
for(int i = 0 ; i<this.getListDatas().size();i++){
Map excelCol = (Map) this.getListDatas().get(i);
User user = new User();
try {
User obj = (User) BeanToMapUtil.convertMap(user.getClass(), excelCol);
users.add(obj);
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

}

Dao dao = new Dao();
for(int i = 0;i<users.size();i++){
try{
dao.saveUser(users.get(i));

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

}


public static String getStringCellValue(HSSFCell cell) {
if (cell == null){
return null;
}

String result = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
result = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell)) {
java.text.SimpleDateFormat TIME_FORMATTER = new java.text.SimpleDateFormat(
"yyyy-MM-dd");
result = TIME_FORMATTER.format(cell.getDateCellValue());
}
else{
double doubleValue = cell.getNumericCellValue();
result = "" + doubleValue;
}
break;
case HSSFCell.CELL_TYPE_STRING:
if (cell.getRichStringCellValue() == null){
result = null;
}
else{
result = cell.getRichStringCellValue().getString();
}
break;
case HSSFCell.CELL_TYPE_BLANK:
result = null;
break;
case HSSFCell.CELL_TYPE_FORMULA:
try{
result = String.valueOf(cell.getNumericCellValue());
}catch(Exception e){
result = cell.getRichStringCellValue().getString();
}
break;
default:
result = "";
}

return result;
}


public String getCurEntityCode() {
return curEntityCode;
}
public void setCurEntityCode(String curEntityCode) {
this.curEntityCode = curEntityCode;
}
public Map getCurEntityHeadMap() {
return curEntityHeadMap;
}
public void setCurEntityHeadMap(Map curEntityHeadMap) {
this.curEntityHeadMap = curEntityHeadMap;
}
public XMLUtil getParseXmlUtil() {
return parseXmlUtil;
}
public void setParseXmlUtil(XMLUtil parseXmlUtil) {
this.parseXmlUtil = parseXmlUtil;
}
public Map getCurEntityColRequired() {
return curEntityColRequired;
}
public void setCurEntityColRequired(Map curEntityColRequired) {
this.curEntityColRequired = curEntityColRequired;
}
public List getListDatas() {
return listDatas;
}
public void setListDatas(List listDatas) {
this.listDatas = listDatas;
}
public StringBuffer getErrorString() {
return errorString;
}
public void setErrorString(StringBuffer errorString) {
this.errorString = errorString;
}

}

项目中定义一个XML文件,主要做一些条件限制,比如用户名不能为空,email不能重复等,所以就有一个XML解析类:

@SuppressWarnings("rawtypes")
public class XMLUtil {


public Map entityMap ;


public Map columnMap;


public Map ruleMap ;


public Map columnRulesMap ;


public Map columnListMap ;


public List columnList ;



public XMLUtil(){
SAXReader reader = new SAXReader();
InputStream in = getClass().getClassLoader().getResourceAsStream("user.xml");
try {
Document doc = reader.read(in);
Element root = doc.getRootElement();
Iterator itEntity = root.elements("entity").iterator();
while(itEntity.hasNext()){
Element entity = (Element) itEntity.next();
parseEntity(entity);
}


Map enMap = (Map) this.getEntityMap().get("用户表");
Set<?> set = enMap.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
String uu = (String) it.next();
}
}catch(Exception e){
e.printStackTrace();
}

}


@SuppressWarnings("unchecked")
public void parseEntity(Element entity){
if(entity != null){


columnListMap = new HashMap();
columnMap = new HashMap();
entityMap = new HashMap();
ruleMap = new HashMap();
columnRulesMap = new HashMap();
columnList = new ArrayList();

setEntityMap(entity);
String entityName = entity.attributeValue("name");
Iterator itColumn = entity.elements("column").iterator();
while(itColumn.hasNext()){
Element column = (Element) itColumn.next();
setColumnMap(entityName,column);
}
columnListMap.put(entityName, columnList);
}
}




@SuppressWarnings("unchecked")
public void setEntityMap(Element entity){
Map ent = new HashMap();
String name = entity.attributeValue("name");
String code = entity.attributeValue("code");
ent.put("name", name);
ent.put("code", code);
entityMap.put(name, ent);
}


@SuppressWarnings("unchecked")
public void setColumnMap(String entityName,Element column){
if(column != null){
Map col = new HashMap();
String name = column.attributeValue("name");
String code = column.attributeValue("code");
String type = column.attributeValue("type");
col.put("name", name);
col.put("code", code);
col.put("type", type);
String columnMapKey = entityName+"_"+name;
columnMap.put(columnMapKey, col);
columnList.add(col);
Iterator ruleIt = column.elements("rules").iterator();
while(ruleIt.hasNext()){
Element rules = (Element)ruleIt.next();
Iterator rule = rules.elements("rule").iterator();
while(rule.hasNext()){
Element ruleValid = (Element) rule.next();
setRuleMap(entityName,name,ruleValid);
}
}
}
}


@SuppressWarnings("unchecked")
public void setRuleMap(String entityName,String columnName,Element ruleValid){
if(ruleValid != null){
String ruleName = ruleValid.attributeValue("name");
String ruleMsg = ruleValid.attributeValue("message");
Map ruleValidMap = new HashMap();
ruleValidMap.put("name", ruleName);
ruleValidMap.put("message", ruleMsg);
String ruleStrKey = entityName+"_"+columnName+"_"+ruleName;
String colStrKey = entityName+"_"+columnName;
if(this.getColumnRulesMap().containsKey(colStrKey)){
List valids = (List) this.getColumnRulesMap().get(colStrKey);
valids.add(ruleValidMap);
}else{
List valids = new ArrayList();
valids.add(ruleValidMap);
this.columnRulesMap.put(colStrKey, valids);
}
ruleMap.put(ruleStrKey, ruleValidMap);
}
}




public Map getEntityMap() {
return entityMap;
}

public void setEntityMap(Map entityMap) {
this.entityMap = entityMap;
}

public Map getColumnMap() {
return columnMap;
}

public void setColumnMap(Map columnMap) {
this.columnMap = columnMap;
}

public Map getRuleMap() {
return ruleMap;
}

public void setRuleMap(Map ruleMap) {
this.ruleMap = ruleMap;
}

public Map getColumnRulesMap() {
return columnRulesMap;
}

public void setColumnRulesMap(Map columnRulesMap) {
this.columnRulesMap = columnRulesMap;
}

public Map getColumnListMap() {
return columnListMap;
}

public void setColumnListMap(Map columnListMap) {
this.columnListMap = columnListMap;
}
}

XML解析类定义完成后,ExcelUtil会调用处理,处理完成后返回,导入结束。

至于数据库连接,任何方式都行,这里不做要求,另外需要定义一个实体User,属性根据自己的业务设置。

以上就是具体实现过程,如果有任何问题,我们共同交流讨论。

举报

相关推荐

0 条评论