1. 程式人生 > >web開發excel檔案上傳及解析(下)

web開發excel檔案上傳及解析(下)

前言:

接著上一篇部落格檔案上傳,這一篇部落格實踐的是excel檔案的解析,通常我們會需要這樣的需求,就是讓使用者下載一個格式的模板,然後在模板中按照要求填寫資料,最後的就是將excel中的內容全部儲存到資料庫中,從而實現一種批量的上傳的作用,節省很多時間。

準備工作:

要實現excel檔案的解析,我們同樣需要依賴相應的jar包。如果是maven依賴則需要在pom.xml中新增如下依賴

 <!-- 解析Excel檔案的jar包 用於2003- 版本的excel -->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.17</version>
</dependency>
<!-- 解析Excel檔案的jar包 用於2007+ 版本的excel -->
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>3.17</version>
</dependency>

如果需要下載jar包,則從下面的地址中下載相應的jar包,然後匯入到專案中

連結:https://pan.baidu.com/s/1wkc7Aak4P_fwvmYoxlIwHQ 密碼:wiji

功能實現:

全部程式碼如下:

ExcelUtil.java

package com.tools.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
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;

public class ExcelUtils {

	/**
	 * 根據檔案路徑,生成workbook例項
	 * @param filePath
	 * @return
	 */
	public static Workbook readExcel(String filePath) {
		Workbook workbook = null;
		if(filePath == null) return null;
		InputStream inputStream;
		try {
			inputStream = new FileInputStream(filePath);
			workbook = new XSSFWorkbook(inputStream);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return workbook;
	}
	
	/**
	 * 通過流獲取workbook的例項
	 * @param in
	 * @return
	 */
	public static Workbook readExcel(InputStream in) {
		Workbook workbook = null;
		try {
			//這裡僅僅解析的是xlsx型別的excel,如果是xls格式的new HSSFWorkbook(in),大家可根據檔案的字尾不同,自動適配
			workbook = new XSSFWorkbook(in);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return workbook;
	}
	
	public static List<Map<String, String>> analysisWorkbook(Workbook workbook){
		if(workbook == null) return null;
		List<Map<String,String>> result = new ArrayList<>();
		//定義excel有哪些欄位
		String[] colunms = {"name","age","score"};
		//獲取第一個sheet
		Sheet firstSheet = workbook.getSheetAt(0);
		int rowNums = firstSheet.getPhysicalNumberOfRows();
		//獲取第一行
		Row row = firstSheet.getRow(0);
		//獲取最大的列數
		int colunmNums = row.getPhysicalNumberOfCells();
		
		for(int i=1;i<rowNums;i++) {
			row = firstSheet.getRow(i);
			Map<String,String> cellMap = new HashMap<>();
			if(row!=null) {
				for(int j=0;j<colunmNums;j++) {
					cellMap.put(colunms[j],(String) getCellValue(row.getCell(j)));
				}
			}
			result.add(cellMap);
		}
		return result;
	}
	
	/**
	 * 獲取每一個excel表格中的value
	 * @param cell
	 * @return
	 */
	public static Object getCellValue(Cell cell) {
		Object result = null;
		if(cell == null) return null;
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_NUMERIC:
			result = String.valueOf(cell.getNumericCellValue());
			break;
		case Cell.CELL_TYPE_FORMULA:
			//判斷cell是否是日期格式
			if(DateUtil.isCellDateFormatted(cell)) {
				result = cell.getDateCellValue();
			}else {
				result = String.valueOf(cell.getNumericCellValue());
			}
			break;
		case Cell.CELL_TYPE_STRING:
			result = cell.getRichStringCellValue().getString();
			break;
		default:
			result="";
			break;
		}
		return result;
	}
	
}

 Controller中的部分程式碼

@RequestMapping(value="/uploadExcelFile",method=RequestMethod.POST,produces = "text/html;charset=UTF-8")
	@ResponseBody
	public String uploadExcelFile(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) {
		try {
			//file upload start
			String path = request.getSession().getServletContext().getRealPath("/");
			String fileName = "display.xlsx";
			File excelFile = new File(path+fileName);
			LOGGER.info("uploadExcelFile file = "+excelFile.toString());
			if(excelFile.exists()) {
				excelFile.delete();
			}
			file.transferTo(excelFile);
			//file upload end
			//解析
			InputStream in = new FileInputStream(excelFile);
			Workbook workbook = ExcelUtils.readExcel(in);
			List<Map<String, String>> list = ExcelUtils.analysisWorkbook(workbook);
			for(Map<String,String> map : list) {
				for(Entry<String,String> entry : map.entrySet()) {
					System.out.println(entry.getKey()+":"+entry.getValue());
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "fail";
		}
		return "success";
	}

這部分程式碼僅僅是簡單寫的實踐的例項,controller中不應該寫這麼多邏輯,這裡為了簡單演示功能,上面congroller中的程式碼,前半部分是檔案上傳,後半部分是檔案解析。而檔案的解析,我單獨封裝到一個ExcelUtil中了。

執行結果:

首先看下要解析的excel的內容

接下來看一下,解析的結果:

excel的簡單解析的功能就介紹到這裡了,大家可以以這個為demo,開發自己的解析excel的需求了,如需要了解檔案上傳可檢視上一篇部落格檔案上傳的實踐