一直以来上传文件都是用form表单来上传的,在项目中也有过ajax异步无刷新的上传文件,因为记录下来ajax如何文件。
本次上传文件是用jsp作为前台界面,servlet为后台,没有使用框架处理,上传文件用的ajaxfileupload.js封装的工具类
上传文件需要commons-fileupload-1.3.1.jar,commons-io-2.2.jar。
处理excel使用的是poi包 poi-3.9.jar,poi-ooxml-3.9.jar,poi-ooxml-schemas-3.9.jar,xmlbeans-2.3.0.jar,dom4j-1.6.1.jar,
如果excel后缀是xls的话就不用加xmlbeans-2.3.0.jar,dom4j-1.6.1.jar这个两个jar。这两个jar主要解决比较老版的excel后缀为xlsx的
前台界面引用以下js文件
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>js代码
$(function(){
$("#upload").on("change",function(){
var objId = $.trim($(this).attr('id'));
fileUpload(objId);
});
function fileUpload(objId){
var _obj = $('#'+objId);
$.ajaxFileUpload({
url : 'servlet/uploadServlet?number='+Math.random(),//后台请求地址
type: 'post',//请求方式 当要提交自定义参数时,这个参数要设置成post
secureuri : false,//是否启用安全提交,默认为false。
fileElementId : 'upload',// 需要上传的文件域的ID,即<input type="file">的ID。
dataType : 'json',//服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。如果json返回的带pre,这里修改为json即可解决。
success : function (json, status) {//提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
alert(json.data);
$('#tbList').html("");
var html = "<tr><td>编号</td><td>姓名</td><td>年龄</td></tr>";
if(json.data.length > 0){
for(var i = 0; i < json.data.length; i++){
html +="<tr>";
html +="<td>"+json.data[i].id+"</td>";
html +="<td>"+json.data[i].name+"</td>";
html +="<td>"+json.data[i].age+"</td>";
html +="</tr>";
}
}
$('#tbList').html(html);
},
complete: function(xmlHttpRequest) {
_obj.replaceWith('<input type="file" class="upload" id="'+objId+'" name="'+objId+'" style="display:none;"/>');
$("#"+objId).on("change", function(){
fileUpload(objId);
});
},
error : function (json, status, e) {//提交失败自动执行的处理函数。
alert("上传失败");
}
});
}
});这是每次改变控件内容的时候触发上传,但是HTML的File控件存在一个bug,触发一次change事件后无法再继续触发下一次,所以特意在complete函数里面替换控件,在重新绑定change事件就可以了。
HTML代码
<div class="btn-file-box pos-rel">
<input type="file" id="upload" name="upload"
style="font-size: 0;opacity: 0;width: 100px;height: 100px;position: absolute;
left: 0;top: 0;" />
<span class="btn ">选择文件</span>
<br/>
<br/>
<table id="tbList" border="1" width="300px">
<tr>
<td width="100px">编号</td>
<td width="100px">姓名</td>
<td width="100px">年龄</td>
</tr>
</table>
</div>前台界面很简单没有做什么美化,这次主要是讲文件上传导入数据功能。
servlet代码
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/json;charset=UTF-8");
PrintWriter out = response.getWriter();
//临时文件存储路径
String temp_file_path = request.getSession().getServletContext().getRealPath("/")+File.separator+"corpfile"+File.separator;
File file = new File(temp_file_path);
if(!file.exists()){
file.mkdir();
}
//配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置内存临界值,上传文件若超出后这个值,则产生临时文件存放临时目录中
factory.setSizeThreshold(1024 * 1024 * 3);
//设置临时目录
factory.setRepository(new File(temp_file_path));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8");
JSONObject jsonobj = new JSONObject();
try {
//获取请求参数解析文件数据
List<FileItem> list = upload.parseRequest(request);
for (FileItem item : list) {
if(item.isFormField()){ //判断此项是不是普通类型,不是file类型
String name = item.getFieldName();
String value = item.getName();
}else{
//创建Workbook
Workbook workbook = WorkbookFactory.create(item.getInputStream());
//获取excel表格行数
Integer rowCount = getAllRows(workbook,0);
//解析excel表格
List<String[]> rowsList = readExcel(workbook, 0,3);
List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();
Map<String,Object> map = null;
for (int i = 0; i < rowsList.size(); i++) {
String[] str = rowsList.get(i);
map = new HashMap<String, Object>();
map.put("id", str[0]);
map.put("name", str[1]);
map.put("age", str[2]);
resultList.add(map);
}
jsonobj.put("data", resultList);
jsonobj.put("retCode","200");
jsonobj.put("retMsg","上传成功!");
}
}
} catch (Exception e) {
e.printStackTrace();
jsonobj.put("retCode","500");
jsonobj.put("retMsg","error");
}
out.write(jsonobj.toString());
out.flush();
out.close();
}public static Integer getAllRows(Workbook wb, Integer numSheet) {
Sheet sheet = wb.getSheetAt(numSheet);//根据传的参数获取工作表
Integer count=sheet.getPhysicalNumberOfRows()-1;
if (count < 0) {
count = 0;
}
return count;
}public static List<String[]> readExcel(Workbook wb, Integer numSheet, int cellCount) {
List<String[]> list = new ArrayList<String[]>();
if (wb!=null) {
// 循环工作表Sheet
Sheet sheet = wb.getSheetAt(numSheet);// 根据传的参数获取工作表
// 循环行Row
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
String[] str = new String[cellCount];
if (row.getRowNum() != 0) {
// 循环列Cell
for (int cellNum = 0; cellNum < cellCount; cellNum++) {
Cell cell = row.getCell(cellNum);
if (cell == null) {
continue;
}
str[cellNum] = getCellValue(cell);
}
list.add(str);
}
}
}
return list;
}
public static String getCellValue(Cell cell) {
String strValue = "";
if( cell == null ){
return "";
}
switch (cell.getCellType()) { // 根据cell中的类型来输出数据
case HSSFCell.CELL_TYPE_NUMERIC:
try {
boolean cdf=HSSFDateUtil.isCellDateFormatted(cell);
boolean cidf=HSSFDateUtil.isCellInternalDateFormatted(cell);
if (cdf||cidf) {
strValue = formatDateToString(cell.getDateCellValue());
}else{
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false);
strValue = nf.format(cell.getNumericCellValue());
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case HSSFCell.CELL_TYPE_STRING:
strValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
strValue = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
int resultType=cell.getCachedFormulaResultType();
if (resultType==0) {
strValue = String.valueOf(cell.getNumericCellValue());
}else{
strValue = cell.getCellFormula();
}
break;
case HSSFCell.CELL_TYPE_ERROR:
strValue = String.valueOf(cell.getErrorCellValue());
break;
}
return strValue.trim();
}
public static String formatDateToString(Date date) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = "";
if (date != null) {
dateStr = format.format(date);
}
return dateStr;
}