一、页面示例
二、Excel样例(下面图示不用管 该行删除)
三、在Spring配置文件中设置上传文件大小
<!--上传文件bean配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置上传文件大小-->
<property name="maxInMemorySize" value="5000000"/>
</bean>
四、编辑jsp(knowledge.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<%
String importMsg = "";
if (request.getSession().getAttribute("msg") != null) {
importMsg = request.getSession().getAttribute("msg").toString();
}
request.getSession().setAttribute("msg", "");
%>
<head>
<title>知识库</title>
<style>
body{
padding-top: 70px;
padding-left: 190px;
}
</style>
<script src="${pageContext.request.contextPath}/static/js/jquery-1.11.1.min.js"></script>
<script type="text/javascript">
function check() {
var excel_file = $("#excel_file").val();
if (excel_file == "" || excel_file.length == 0) {
alert("请选择文件路径!");
return false;
} else {
return true;
}
}
$(document).ready(function() {
var msg = "";
if ($("#importMsg").text() != null) {
msg = $("#importMsg").text();
}
if (msg != "") {
alert(msg);
}
});
</script>
</head>
<body>
<form action="knowledge/fileDown" method="get">
<input type="submit" value="下载模板">
</form>
<div>
<font color="blue">批量导入客户</font>
</div>
<form action="knowledge/uploadFile" method="post" enctype="multipart/form-data" οnsubmit="return check();">
<div style="margin: 30px;">
<input id="excel_file" type="file" name="filename" accept="xlsx" size="80" />
<input id="excel_button" type="submit" value="导入Excel" />
</div>
<font id="importMsg" color="red"><%=importMsg%></font><input type="hidden" />
</form>
</body>
</html>
五、编辑java文件
5.1工具类代码(WDWUtil.java)(需要判断Excel版本,不同版本后缀不同)
public class WDWUtil {
// @描述:是否是2003的excel,返回true是2003
public static boolean isExcel2003(String filePath) {
return filePath.matches("^.+\\.(?i)(xls)$");
}
//@描述:是否是2007的excel,返回true是2007
public static boolean isExcel2007(String filePath) {
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
}
5.2工具类代码(ReadExcel.java)
一般来说先将在客户端用户上传的文件拷贝一份至服务器的本地磁盘中,然后再从这个拷贝文件中进行读取,这样就避免了因客户端的网络异常或其他状况而在读取时造成的数据流失或损坏的情况。
import com.wk.model.TKnowledge;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by 锴 on 2018/3/4.
*/
public class ReadExcel {
//总行数
private int totalRows = 0;
//总条数
private int totalCells = 0;
//错误信息接收器
private String errorMsg;
//构造方法
public ReadExcel(){}
//获取总行数
public int getTotalRows() { return totalRows;}
//获取总列数
public int getTotalCells() { return totalCells;}
//获取错误信息
public String getErrorInfo() { return errorMsg; }
/**
* 验证EXCEL文件
* @param filePath
* @return
*/
public boolean validateExcel(String filePath){
if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))){
errorMsg = "文件名不是excel格式";
return false;
}
return true;
}
/**
* 读EXCEL文件,获取客户信息集合
* @param fileName
* @return
*/
public List<TKnowledge> getExcelInfo(String fileName, MultipartFile Mfile){
//把spring文件上传的MultipartFile转换成CommonsMultipartFile类型
CommonsMultipartFile cf= (CommonsMultipartFile)Mfile; //获取本地存储路径
File file = new File("C:\\fileupload");
//创建一个目录 (它的路径名由当前 File 对象指定,包括任一必须的父路径。)
if (!file.exists())
file.mkdirs();
//新建一个文件
// File file1 = new File("C:\\fileupload" + new Date().getTime() + ".xlsx");
File file1 = new File("C:\\fileupload" + File.separator + fileName);
//将上传的文件写入新建的文件中
try {
cf.getFileItem().write(file1);
} catch (Exception e) {
e.printStackTrace();
}
//初始化客户信息的集合
List<TKnowledge> knowledgeList=new ArrayList<TKnowledge>();
//初始化输入流
InputStream is = null;
try{
//验证文件名是否合格
if(!validateExcel(fileName)){
return null;
}
//根据文件名判断文件是2003版本还是2007版本
boolean isExcel2003 = true;
if(WDWUtil.isExcel2007(fileName)){
isExcel2003 = false;
}
//根据新建的文件实例化输入流
is = new FileInputStream(file1);
//根据excel里面的内容读取客户信息
knowledgeList = getExcelInfo(is, isExcel2003);
is.close();
}catch(Exception e){
e.printStackTrace();
} finally{
if(is !=null)
{
try{
is.close();
}catch(IOException e){
is = null;
e.printStackTrace();
}
}
}
return knowledgeList;
}
/**
* 根据excel里面的内容读取客户信息
* @param is 输入流
* @param isExcel2003 excel是2003还是2007版本
* @return
* @throws IOException
*/
public List<TKnowledge> getExcelInfo(InputStream is,boolean isExcel2003){
List<TKnowledge> knowledgeList=null;
try{
/** 根据版本选择创建Workbook的方式 */
Workbook wb = null;
//当excel是2003时
if(isExcel2003){
wb = new HSSFWorkbook(is);
}
else{//当excel是2007时
wb = new XSSFWorkbook(is);
}
//读取Excel里面客户的信息
knowledgeList=readExcelValue(wb);
}
catch (IOException e) {
e.printStackTrace();
}
return knowledgeList;
}
/**
* 读取Excel里面客户的信息
* @param wb
* @return
*/
private List<TKnowledge> readExcelValue(Workbook wb){
//得到第一个shell
Sheet sheet=wb.getSheetAt(0);
//得到Excel的行数
this.totalRows=sheet.getPhysicalNumberOfRows();
//得到Excel的列数(前提是有行数)
if(totalRows>=1 && sheet.getRow(0) != null){
this.totalCells=sheet.getRow(0).getPhysicalNumberOfCells();
}
List<TKnowledge> customerList=new ArrayList<TKnowledge>();
TKnowledge knowledge;
//循环Excel行数,从第二行开始。标题不入库
for(int r=1;r<totalRows;r++){
Row row = sheet.getRow(r);
if (row == null) continue;
knowledge = new TKnowledge();
//循环Excel的列
for(int c = 0; c <this.totalCells; c++){
Cell cell = row.getCell(c);
if (null != cell){
if(c==0){
knowledge.setQuestion1(cell.getStringCellValue());//问题
knowledge.setSolveNum(0);
knowledge.setUnsolveNum(0);
knowledge.setUseNum(0);
}else if(c==1){
knowledge.setAnswer(cell.getStringCellValue());//答案
}else if(c==2){
knowledge.setQuestion2(cell.getStringCellValue());//相似问题1
}else if(c==3){
knowledge.setQuestion3(cell.getStringCellValue());//相似问题2
}else if(c==4){
knowledge.setQuestion4(cell.getStringCellValue());//相似问题3
}else if(c==5){
knowledge.setQuestion5(cell.getStringCellValue());//相似问题4
}else if(c==6){
knowledge.setQuestion6(cell.getStringCellValue());//相似问题5
}
}
}
//添加知识
customerList.add(knowledge);
}
return customerList;
}
}
5.3服务层代码(KnowledgeService.java)
@Resource
private TKnowledgeMapper knowledgeMapper;
@Override
public boolean batchImort(String name, MultipartFile file) {
boolean b = false;
//创建处理EXCEL
ReadExcel readExcel=new ReadExcel();
//解析excel,获取客户信息集合。
List<TKnowledge> knowledgeList = readExcel.getExcelInfo(name ,file);
if(knowledgeList != null){
b = true;
}
//迭代添加客户信息(注:实际上这里也可以直接将customerList集合作为参数,在Mybatis的相应映射文件中使用foreach标签进行批量添加。)
for(TKnowledge knowledge:knowledgeList){
knowledgeMapper.insert(knowledge);
}
return b;
}
@Override
public int insert(TKnowledge record) {
return knowledgeMapper.insert(record);//插入一条数据
}
5.4控制器代码(KnowledgeController.java)
@Controller
@RequestMapping("/web/knowledge")
public class KnowledgeController {
@Resource
private KnowledgeService knowledgeService;
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadFile(@RequestParam(value = "filename") MultipartFile file,
HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("开始上传文件");
//判断文件是否为空
if (file == null) return null;
//获取文件名
String name = file.getOriginalFilename();
//进一步判断文件是否为空(即判断其大小是否为0或其名称是否为null)
long size = file.getSize();
if (name == null || ("").equals(name) && size == 0) return null;
//批量导入。参数:文件名,文件。
boolean b = knowledgeService.batchImort(name, file);
if (b) {
String Msg = "批量导入EXCEL成功!";
request.getSession().setAttribute("msg", Msg);
} else {
String Msg = "批量导入EXCEL失败!";
request.getSession().setAttribute("msg", Msg);
}
return "web/knowledge";
}
@RequestMapping(value = "/fileDown", method = RequestMethod.GET)
public void down(HttpServletRequest request, HttpServletResponse response) throws Exception {
//模拟文件,myfile.txt为需要下载的文件
String fileName = request.getSession().getServletContext().getRealPath("static/file/知识库导入模板.xls");
System.out.println(fileName);
//获取输入流
InputStream bis = new BufferedInputStream(new FileInputStream(new File(fileName)));
//假如以中文名下载的话
String filename = "知识库导入模板.xls";
//转码,免得文件名中文乱码
filename = URLEncoder.encode(filename,"UTF-8");
//设置文件下载头
response.addHeader("Content-Disposition", "attachment;filename=" + filename);
//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("multipart/form-data");
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
int len = 0;
while((len = bis.read()) != -1){
out.write(len);
out.flush();
}
out.close();
}
}
六、最后附上项目结构
此博客忽略模型层代码,工具类和模型层可根据需求更改