用Java实现将Excel中的记录入库
Excel
Oracle数据库
整个过程
前台form表单提交 -> url拦截 -> 传到后台的servlet -> 后台首先将Excel传到服务器(假设有)的某个路径 -> 然后将Excel分条解析到List里面 -> 将List记录放入Map ->批量方法传到数据库
废话不多说,上代码讲解:
1 上传Excel到服务器某个路径
这里注意一点:
前台form表单提交编码的格式必须是multipart/form-data方式,不能是application/x-www-form-urlencoded,原因和设置方法见getParameter取不到值
package com.trigl.impo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
/**
* 上传Excel并且将Excel信息存入数据库控制类
* @author 白鑫
* @date 2015年12月31日 上午12:50:06
*/
public class UploadExcel extends AbstractController {
private static final Logger log = Logger.getLogger(UploadExcel.class);
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
return this.uploadFileAction(arg0, arg1);
}
/**
* 上传文件方法
* @param request
* @param response
* @return
* @throws Exception
*/
private ModelAndView uploadFileAction(HttpServletRequest request,
HttpServletResponse response) throws Exception {
Properties props = new Properties();
try {
//加载properties文件中的内容
props.load(UploadExcel.class.getClassLoader().getResourceAsStream("uploadpath.properties"));
} catch (IOException e1) {
log.error("获取路径失败!", e1);
}
String data = "";
log.info(request.getContentType());//form提交编码格式
// 设置返回类型, 字符集 ,防止乱码
response.setContentType("text/html; charset=utf-8");
// 参数,上传文件的子目录(以模块命名)
// String childPath = request.getParameter("path");
String childPath = "UploadExcel";
// request转换
// MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest mulRequest = resolver.resolveMultipart(request);
// 获取文件
MultipartFile file = mulRequest.getFile("fileField");
// 服务器存放路径 PATH为 C://dsmc
String dir = props.getProperty("PATH") + childPath;
File filePath = new File(dir);
// 如果文件夹不存在则创建
if (!filePath.exists()) {
filePath.mkdirs();
}
// 获取系统文件名,系统文件名由当前时间的值加上3位随机生成吗构成
String systemFileName = new Long(System.currentTimeMillis()).toString() + new Random().nextInt() % 1000;
// 获取后缀名
String[] s = file.getOriginalFilename().split("\\.");
String suffix = "";
if (s.length > 1)
suffix = s[s.length - 1];
FileOutputStream io = null;
try {
//separatorChar的值为“\\"
io = new FileOutputStream(dir + File.separatorChar + systemFileName + "." + suffix);
io.write(file.getBytes());
if (log.isDebugEnabled()) {
log.debug("文件保存为" + systemFileName + "." + suffix + "上传文件名为:" + file.getOriginalFilename());
}
io.close();
} catch (Exception e) {
// e.printStackTrace();
log.error("上传失败!", e);
data = "{success:false,msg:'文件上传失败'}";
// response.getWriter().print("error");
} finally {
response.getWriter().write(data);
response.getWriter().flush();
}
String fullPath = filePath + "\\" + systemFileName + "." + suffix ;
ImportExcel impExcel = new ImportExcel();
String resultMsg = impExcel.importExcelToDb(fullPath);
return null;
}
}
2 将下载到服务器的Excel解析并入库
package com.trigl.impo;
import java.io.FileInputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.trigl.dao.BaseJdbcTemplate;
import com.trigl.util.TestLoadPath;
/**
* Excel入库类
* @author 白鑫
* @date 2016年1月4日 上午10:30:29
*/
public class ImportExcel extends JdbcDaoSupport {
ApplicationContext ctx = new ClassPathXmlApplicationContext("config/applicationContext-db.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate");
private static final Logger log = Logger.getLogger(ImportExcel.class);
private static int startRow = 1;
public String importExcelToDb(String fullPath) {
//解析excel
Workbook wookbook = null;
//用于放ImpExcelBean的list
final List<ImpExcelBean> exlList = new ArrayList<ImpExcelBean>();
//将Excel的各行记录放入ImpExcelBean的list里面
try {
//WorkbookFactory是用来将Excel内容导入数据库的一个类
wookbook = WorkbookFactory.create(new FileInputStream(fullPath));
Sheet sheet = wookbook.getSheetAt(0);//统计excel的行数
int rowLen = sheet.getPhysicalNumberOfRows();//excel总行数,记录数=行数-1
ImpExcelBean exlBean;
//导入各条记录
for (int i = startRow; i < rowLen; i++) {
Row row = sheet.getRow(i);
exlBean = new ImpExcelBean();
exlList.add(exlBean);
int startCol = 0;
//将Excel中各行记录依次导入到ImpExcelBean的list中
if (row != null) {
// 表英文名
String tbEn = getValue(row.getCell(startCol++)).toUpperCase();
exlBean.setTbEn(tbEn);
//表中文名
String tbCn = getValue(row.getCell(startCol++)).toUpperCase();
exlBean.setTbCn(tbCn);
//表描述
String comment = getValue(row.getCell(startCol++)).toUpperCase();
exlBean.setComment(comment);
//表空间
String tableSpace = getValue(row.getCell(startCol++)).toUpperCase();
exlBean.setTableSpace(tableSpace);
//系统
String sys = getValue(row.getCell(startCol++)).toUpperCase();
exlBean.setSys(sys);
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("", e);
return "0|excel解析失败";
}
// // 添加事务,导入数据库
// DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
// dataSourceTransactionManager.setDataSource(this.getJdbcTemplate().getDataSource());
// DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
// transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
// TransactionStatus status = dataSourceTransactionManager.getTransaction(transDef);
try {
//过滤重复表
final Map<String, ImpExcelBean> exlMap = new HashMap<String, ImpExcelBean>();
for (ImpExcelBean bean : exlList) {
//遍历exlList,若已存在bean.getTbEn(),则不加入到map里面去
if (!exlMap.containsKey(bean.getTbEn()))
exlMap.put(bean.getTbEn(), bean);
}
//对上面的map中的bean放入一个list中
Iterator<Entry<String, ImpExcelBean>> it = exlMap.entrySet().iterator();
final List<ImpExcelBean> exlLt = new ArrayList<ImpExcelBean>();
while (it.hasNext()) {
final Entry<String, ImpExcelBean> en = it.next();
exlLt.add(en.getValue());
}
//导入之前先根据系统删除原来的旧记录
jdbcTemplate.batchUpdate("delete from t_meta_table where SYS_ID=?",
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setString(1, exlLt.get(i).getSys());
}
public int getBatchSize() {
return exlLt.size();
}
});
// 遍历bean list导入数据库
StringBuilder sb = new StringBuilder();
sb.append("insert into t_meta_table ");
sb.append("(tab_id, tab_en, tab_cn, tab_desc, tab_tablespace, sys_id)");
sb.append(" values ");
sb.append("('TAB'||seq_meta_table.nextval, ?,?,?,?,?)");
jdbcTemplate.batchUpdate(sb.toString(), new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException {
ImpExcelBean bean = exlLt.get(i);
ps.setString(1, bean.getTbEn());
ps.setString(2, bean.getTbCn());
ps.setString(3, bean.getComment());
ps.setString(4, bean.getTableSpace());
ps.setString(5, bean.getSys());
}
public int getBatchSize() {
return exlLt.size();
}
});
// dataSourceTransactionManager.commit(status);// 提交
return "1|success";
} catch (Exception el) {
el.printStackTrace();
// dataSourceTransactionManager.rollback(status);// 回滚
return "0|失败";
}
}
/**
* 判断表格中值的类型并且返回一个String类型的值
* @param cell
* @return
*/
private String getValue(Cell cell) {
if (cell == null)
return "";
if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return String.valueOf(cell.getBooleanCellValue()).trim();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
return String.valueOf(cell.getNumericCellValue()).trim();
} else {
return String.valueOf(cell.getStringCellValue()).trim();
}
}
}
3 springmvc-servlet.xml中URL拦截器的配置
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/upfiles.html">upfiles</prop>
</props>
</property>
</bean>
<bean id="upfiles" class="com.trigl.impo.UploadExcel" scope="prototype">
</bean>
4 applicationContext-db.xml中的数据源配置
<!-- 数据源定义 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT=1521)) )(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = orcl)))" />
<property name="username" value="KFDB" />
<property name="password" value="KFDB" />
<!-- 初始化连接数 -->
<property name="initialSize" value="1" />
<!-- 最大活动连接数 -->
<property name="maxActive" value="50" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="5" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="15" />
<!-- 获取连接超时等待时间(毫秒) -->
<property name="maxWait" value="10000" />
<!-- 空闲池空闲连接激活线程的运行间隔时间(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 空闲池中空闲连接能够被激活前的最小空闲时间(毫秒) -->
<property name="minEvictableIdleTimeMillis" value="10000" />
</bean>
<!-- JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
5 配置上传文件根路径的properties文件:uploadpath.properties
PATH = C://dsmc//
6 前台jsp
<body>
<form action="upfiles.html" method="post" enctype="multipart/form-data">
<input type="file" name="fileField" class="file" id="fileField"
size="28" /> <input type="submit" name="submit" class="btn"
value="上传" />
</form>
</body>
7 运行测试
选择Excel,点击上传,然后打开plsql developer看是否入库。
OVER