ajax上傳excel檔案匯入資料
一直以來上傳檔案都是用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;
}