linux系統服務器下javaweb項目中實現excel導入數據到數據庫中

實現思路:

  1. 用戶在瀏覽器上傳xlsx或者xls文件
  2. servlet或controller將文件上傳到servlet或controller將文件上傳到項目文件夾
  3. 後端工具類將Excel文件解析並轉換爲csv文件並輸出到系統數據庫安全路徑("/var/lib/mysql-files/")
  4. 通過mybatis拼接sql語句將csv數據導入數據庫表中
    瀏覽器界面:
    在這裏插入圖片描述

Excel模板
在這裏插入圖片描述

jsp中

<!-- 上傳考勤表的表單 -->
		<form id="excel" method="post" enctype="multipart/form-data">   
			<input id="file" class="easyui-filebox" name="file" style="width:300px" buttonText="選擇本地考勤表" data-options="prompt:'請選擇Excel文件'">	
			<input type="submit" value="確認上傳">
			<input type="reset" value="重置">
		</form> 

js中

$(function(){
		$('#excel').form({    
		    url:"<%=basePath%>attendance/upload",    
		    onSubmit: function() {
				var fileName= $('#file').filebox('getValue'); 
				  //對文件格式進行校驗  
                 var d1=/\.[^\.]+$/.exec(fileName);
				if (fileName == "") {  
				      $.messager.alert('請選擇將要上傳的文件!'); 
				      return false;  
				 }else if(d1!=".xls" && d1!=".xlsx"){
					 $.messager.alert('提示','請選擇xls或者xlsx格式文件!','info');  
					 return false; 
				 }
                return true;  
            }, 
		    success:function(data){ 
		    	var data = eval('(' + data + ')');
		    	if(!data["state"]){
		    		console.log(data)
		    		console.log(data.state);
		    		$.messager.alert('失敗','文件格式是否規範呢?')
		    	}else{
		    		$.messager.alert('成功','請刷新考勤表')
		    	}
		    },
		    error:function(err){
		    	console.log(err)
		    }
		});
		
		// 規定爲Excel文件類型
		$('#file').filebox({    
		    accept:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
		})

easyui中文件上傳表單設置accept可以規定文件類型,但是用戶可以強行上傳其他類型的文件。所以還需要在onsubmit方法中再判斷一次。

controller中

**
	 * 
	
	 * <p>Title: upload</p>  
	
	 * <p>Description: </p>  
		上傳考勤表
	 * @param files	上傳的文件數組
	 * @param req	request
	 * @return  
	 * <p> @date 2018年12月10日  </p>
	 */
	@RequestMapping("upload")
	@SystemControllerLog(type=2,description="上傳考勤表")
	@ResponseBody
	public JsonData upload(@RequestParam("file")MultipartFile[] files, HttpServletRequest req){
		String upDirRealPath = req.getServletContext().getRealPath("/uploadDir/");
		String msg = null;
		Boolean state = null;
		Integer value = null;
		// 從session中獲取操作者
		Admin admin = (Admin)(req.getSession().getAttribute("admin"));
		// 上傳到指定路徑
		for(MultipartFile file : files){
			// 將項目下的uploaddir文件夾絕對路徑,連接文件名,得到文件的絕對路徑
			String src = upDirRealPath.concat(file.getOriginalFilename());
				try {
					// 傳進絕對路徑,上傳
					file.transferTo(new File(src));
					// 上傳成功後,調用service中的方法,進行轉換csv和導入數據庫
					value = as.fileInsert(src, admin.getAdminId());
					state = true;
				} catch (IllegalStateException e) {
					msg = "IllegalStateException";
					e.printStackTrace();
				} catch (IOException e) {
					msg = "IOException";
					e.printStackTrace();
				}
		}
		return new JsonData("上傳文件", value, msg, state);
	}
	

Service中

public Integer fileInsert(String src, Long adminId) {
		// 調用csvutil工具類,轉換成csv文件並獲取csv文件在安全路徑下的絕對路徑
		String csvPath = CsvUtil.excel(src, adminId);
		// 調用dao層的方法上傳到數據庫
		return ad.csvInsert(csvPath);
	}
	

CsvUtil中
寫了三個方法。
前兩個方法基本相同,是xls與xlsx格式的表格轉換成csv文件並返回csv文件路徑,
最後一個方法供調用,傳入文件名後匹配後綴,決定執行前面的哪一個方法
所以,只需要搞定第一個方法即可

幾個特別注意的地方:

  1. 數據庫安全路徑。linux系統中mysql默認安全上傳路徑是 “/var/lib/mysql-files/”
  2. linux系統和windows系統中路徑用的斜槓符號不同。處理路徑字符串時一定要用File.separator
  3. Excel 日期格式的判斷。先判斷是不是數值型,再判斷是否爲日期型
  4. 如果excel表第一行不是數據,而是表頭,則要跳過第一行。
package com.bs.admin.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;

import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/* * 

* <p>Title: CsvUtil</p>  

* <p>Description: </p>  
	用於將excel文件轉換成csv文件
* @author zhengjian  

* <p> @date 2018年12月11日</p>
 */
public class CsvUtil {

	// 輸出路徑(mysql安全路徑。本地默認路徑是在c盤ProgramData裏面。而linux系統默認路徑爲"/var/lib/mysql-files/"。這裏在枚舉中獲取到linux系統默認路徑"/var/lib/mysql-files/")
//	 private static String csvDir = "C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/";
	private static String csvDir = PropertyUtil.CSVDIR.getName();

	/**
	 * 
	 * 
	 * <p>
	 * Title: excelToCsv
	 * </p>
	 * 
	 * <p>
	 * Description:
	 * </p>
	 * 將上傳的xlsx錶轉爲csv格式,然後將Excel文件刪除
	 * 
	 * @param src
	 *            <p>
	 * @return 
	 * 			@date 2018年12月7日
	 *            </p>
	 */
	public static String xlsxToCsv(String src, Long adminId) {
		XSSFWorkbook workbook = null;
		BufferedWriter bw = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		File file = new File(src);
		FileInputStream fis = null;
		// linux與windows中的斜槓不同。這裏一定要用File.separator。切割文件的絕對路徑獲取文件名
		String filename = src.substring(src.lastIndexOf(File.separator)+1,src.lastIndexOf("."));
		try {
			fis = new FileInputStream(file);
			workbook = new XSSFWorkbook(fis);
			bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvDir.concat(filename).concat(".csv")), "UTF-8"));
			XSSFSheet sheet = workbook.getSheetAt(0);
//			System.out.println(sheet.getLastRowNum());
			// 第一行表頭跳過。一定要跳過,不然格式錯誤
			for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
				XSSFRow row = sheet.getRow(i);
				if(row == null){
					System.out.println("空行");
					continue;
				}
				for (Cell cell : row) {
					if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING){
						bw.write(cell.getStringCellValue());
					}
					else if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC){
					// Excel 日期格式的判斷。先判斷是不是數值型,再判斷是否爲日期型
						if(DateUtil.isCellDateFormatted(cell)){
							bw.write(sdf.format(cell.getDateCellValue()));
						}else{
							bw.write("" + cell.getNumericCellValue());
						}
					}
					else if (cell.getCellType() == XSSFCell.CELL_TYPE_BOOLEAN){
						bw.write("" + cell.getBooleanCellValue());
					}
					bw.write(",");
				}
				// 操作者id
				bw.write(adminId+",");
				bw.newLine();
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (null != bw) {
					bw.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					if (null != fis) {
						fis.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		//刪除Excel文件,返回csv文件路徑
		boolean delete = file.delete();
//		System.out.println(delete);
		return csvDir.concat(filename).concat(".csv");
	}
	
	
	/**
	 * 
	
	 * <p>Title: xlsToCsv</p>  
	
	 * <p>Description: </p>  
		將xls文件轉換爲csv文件
	 * @param fileName  
	 * <p> @date 2018年12月10日  </p>
	 */
	public static String xlsToCsv(String src, Long adminId) {
		HSSFWorkbook workbook = null;
		BufferedWriter bw = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String filename = src.substring(src.lastIndexOf("\\")+1,src.lastIndexOf("."));
//		String csvPath = csvDir.concat(fileName.substring(0,fileName.indexOf("."))).concat(".csv");
		File file = new File(src);
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			workbook = new HSSFWorkbook();
			bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvDir.concat(filename).concat(".csv")), "UTF-8"));
			HSSFSheet sheet = workbook.getSheetAt(0);
			// 第一行表頭跳過 int i = 0; i < sheet.getLastRowNum(); i++
			for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
				HSSFRow row = sheet.getRow(i);
				for (Cell cell : row) {
					if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING){
						bw.write(cell.getStringCellValue());
					}
					else if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC){
						if(DateUtil.isCellDateFormatted(cell)){
							bw.write(sdf.format(cell.getDateCellValue()));
						}else{
							bw.write("" + cell.getNumericCellValue());
							
						}
					}
					else if (cell.getCellType() == XSSFCell.CELL_TYPE_BOOLEAN){
						bw.write("" + cell.getBooleanCellValue());
					}
					bw.write(",");
				}
				// 操作者id
				bw.write(adminId+",");
				bw.newLine();
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (null != bw) {
					bw.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					if (null != fis) {
						fis.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		//刪除Excel文件,返回csv文件路徑
		boolean delete = file.delete();
		return csvDir.concat(filename).concat(".csv");
	}
	
	/**
	 * 
	
	 * <p>Title: excel</p>  
	
	 * <p>Description: </p>  
		傳入路徑+文件全名(如“c://excel/data.xlsx”)根據文件後綴判斷需要執行哪個方法。返回csv文件路徑
	 * @param fileName  
	 * <p> @date 2018年12月10日  </p>
	 */
	public static String excel(String src, Long adminId){
		String suffix = src.substring(src.lastIndexOf(".")+1);
		if(suffix.equals("xlsx")){
			return xlsxToCsv(src, adminId);
		}else{
			return xlsToCsv(src, adminId);
		}
	}
}

dao層

public Integer csvInsert(String src) {
		return am.csvInsert(src);
	}

mapper接口層

Integer csvInsert(@Param("src") String src);

mapper.xml中

<select id="csvInsert" parameterType="map">
    load data local infile #{src}
	into table t_attendance character set gb2312
	fields terminated by ',' optionally enclosed by '"' escaped by '"'
	lines terminated by '\r\n'
	(emp_id,work_day,leave_day,late_day,early_day,att_date,admin_id);
</select>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章