1. 程式人生 > >Springmvc檔案上傳例子,上傳帶圖片的Excel,並利用poi解析。

Springmvc檔案上傳例子,上傳帶圖片的Excel,並利用poi解析。

直奔主題,第一步:上傳一個帶圖片的Excel。第二步:解析該Excel檔案,得到Excel資料和圖片。 1.pom.xml

		<!-- 檔案上傳 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- 解析excel -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.11</version>
		</dependency>

2.spring-mvc.xml

	<!-- 檔案上傳解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 簡單配置一個編碼格式 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 設定檔案上傳的最大值為5MB,5*1024*1024
		<property name="maxUploadSize" value="5242880"></property> -->
		<!-- 設定檔案上傳時寫入記憶體的最大值,如果小於這個引數不會生成臨時檔案,預設為10240 
		<property name="maxInMemorySize" value="40960"></property>-->
		<!-- 上傳檔案的臨時路徑 
		<property name="uploadTempDir" value="//"></property>-->
		<!-- 延遲檔案解析 
		<property name="resolveLazily" value="true" />-->
	</bean>

3.簡單超low jsp頁面 ,一個上傳form表單

	<form action="file/importExcel" method="post"
		enctype="multipart/form-data">
		<input name="file" type="file"> <input type="submit"
			value="upload">
	</form>

4.FileAction控制器

@RequestMapping("/file")
@RestController
public class FileAction {

	@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
	public String importExcel(@RequestParam(value = "file", required = false) MultipartFile uploadFile)
			throws IOException {
		File target = UploadUtil.upLoadFile(uploadFile);// 檔案上傳
		UploadUtil.analysisExcel(target);//如果只要檔案上傳,執行完上一步就檔案上傳成功了。這一步解析Excel檔案
		return "upload success";
	}
}

5.UploadUtils工具類,處理檔案上傳和解析excel檔案

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFShape;
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.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import sun.misc.BASE64Decoder;

public class UploadUtils{

	private static final Logger logger = LoggerFactory.getLogger(UploadUtil.class);

	/**
	 * 檔案上傳
	 * 
	 * @param uploadFile
	 * @throws IOException
	 */
	public static File upLoadFile(MultipartFile uploadFile) throws IOException {
		String uploadPath = "E://";
		File uploadFlie = new File(uploadPath);
		if (!uploadFlie.exists()) {
			uploadFlie.mkdir();
		}
		MultipartFile file = uploadFile;
		String uploadFileName = file.getOriginalFilename();
		InputStream isRef = file.getInputStream();
		File targetFile = new File(uploadPath, uploadFileName);
		FileOutputStream fosRef = new FileOutputStream(targetFile);
		IOUtils.copy(isRef, fosRef);
		return targetFile;
	}

	/**
	 * 解析excel
	 * 
	 * @param target
	 * @throws IOException
	 */
	@SuppressWarnings("resource")
	public static void analysisExcel(File target) throws IOException {
		try {
			InputStream excelFile = new FileInputStream(target);// 輸入流
			HSSFWorkbook wb = new HSSFWorkbook(excelFile);// 得到Excel工作簿物件
			final Sheet sheet = wb.getSheetAt(0);// 得到Excel工作表物件
			final HSSFSheet hssfSheet = wb.getSheetAt(0);
			ExecutorService executorService = Executors.newFixedThreadPool(5);
			executorService.execute(new Runnable() {

				@Override
				public void run() {
					try {
						readPictures(hssfSheet);
					} catch (IOException e) {
						logger.error("e", e);
					}
				}
			});
			executorService.execute(new Runnable() {

				@Override
				public void run() {
					try {
						readData(sheet);
					} catch (Exception e) {
						logger.error("e", e);
					}
				}
			});
		} catch (Exception e) {
			logger.error("e", e);
		}
	}

	/**
	 * 讀取excel內容
	 * 
	 * @param sheet
	 */
	public static void readData(Sheet sheet) {
		try {
			String name = "", phone = "";
			int rowNum = sheet.getLastRowNum() + 1;
			for (int i = 1; i < rowNum; i++) {// 從第二行開始讀取資料,第一行是表頭
				try {
					Row row = sheet.getRow(i);// 得到Excel工作表的行
					int cellNum = row.getLastCellNum();// 取得一行的有效單元格個數
					for (int j = 0; j < cellNum; j++) {
						Cell cell = row.getCell(j);// 得到Excel工作表指定行的單元格
						String cellValue = null;
						if (cell != null && cell.getCellType() != HSSFCell.CELL_TYPE_BLANK) {
							/*
							 * CELL_TYPE_NUMERIC 數值型 0 CELL_TYPE_STRING 字串型 1
							 * CELL_TYPE_FORMULA 公式型 2 CELL_TYPE_BLANK 空值 3
							 * CELL_TYPE_BOOLEAN 布林型 4 CELL_TYPE_ERROR 錯誤 5
							 */
							switch (cell.getCellType()) { // 判斷excel單元格內容的格式,並對其進行轉換,以便插入資料庫
							case 0:
								cellValue = String.valueOf((long) cell.getNumericCellValue());
								break;
							case 1:
								cellValue = cell.getStringCellValue();
								break;
							case 2:
								cellValue = String.valueOf((int) cell.getNumericCellValue());
								break;
							case 3:
								cellValue = cell.getStringCellValue();
								break;
							case 4:
								cellValue = cell.getStringCellValue();
								break;
							}

							switch (j) {// 通過列數來判斷對應插如的欄位
							case 0:
								name = cellValue;
								break;
							case 1:
								phone = cellValue;
								break;
							}
						}
					}
					logger.info("第{}行,姓名:{},手機號:{}", i, name, phone);
				} catch (Exception e) {
					logger.error("e", e);
				}
			}
		} catch (Exception e) {
			logger.error("e", e);
		}
	}

	/**
	 * 獲得excel中所有圖片
	 * 
	 * @param sheet
	 * @throws IOException
	 */
	public static void readPictures(HSSFSheet sheet) throws IOException {
		try {
			List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();
			for (HSSFShape shape : list) {
				if (shape instanceof HSSFPicture) {
					HSSFPicture picture = (HSSFPicture) shape;
					HSSFPictureData pdata = picture.getPictureData();
					String extension = pdata.suggestFileExtension();
					GenerateImage(byteToBase64String(pdata.getData()), ((HSSFPicture) shape).getFileName(), extension);
				}
			}
		} catch (Exception e) {
			logger.error("e", e);
		}
	}

	/**
	 * 二進位制資料編碼為BASE64字串
	 * 
	 * @param b
	 * @return
	 */
	public static String byteToBase64String(byte[] b) {
		return new String(Base64.encodeBase64(b));
	}

	/**
	 * 生成圖片
	 * 
	 * @param imgStr
	 * @param name
	 *            圖片名
	 * @param extension
	 *            字尾、副檔名
	 * @return
	 */
	public static boolean GenerateImage(String imgStr, String name, String extension) {
		try {
			if (imgStr == null)
				return false;
			BASE64Decoder decoder = new BASE64Decoder();
			try {
				// Base64解碼
				byte[] b = decoder.decodeBuffer(imgStr);
				for (int i = 0; i < b.length; ++i) {
					if (b[i] < 0) {// 調整異常資料
						b[i] += 256;
					}
				}
				String path = "E://";
				String imgFilePath = path + name + "." + extension;// 新生成的圖片
				logger.info("生成的圖片:{}", imgFilePath);
				OutputStream out = new FileOutputStream(imgFilePath);
				out.write(b);
				out.flush();
				out.close();
				return true;
			} catch (Exception e) {
				return false;
			}
		} catch (Exception e) {
			logger.error("e", e);
		}
		return false;
	}
}

6.執行專案,輸入地址http://localhost:8080/ssm-example/upload.jsp,出現一個很簡陋的檔案上傳頁面 在這裡插入圖片描述 上傳Excel檔案,Excel裡面的資料為 在這裡插入圖片描述 在這裡插入圖片描述 點選upload上傳檔案,控制檯打印出執行結果 在這裡插入圖片描述 再去E盤檢視檔案,可以看到剛才上傳的文件和匯出Excel文件裡面的圖片,圖片的名字就是圖片拉入Excel前的名字。 在這裡插入圖片描述

講到這裡,本篇文章到此也就結束了,中間可能存在一些問題,有一些不夠嚴謹完善的地方,希望大家體諒體諒。有問題的話,歡迎大家留意,交流交流。

最後附上本專案github的地址https://github.com/Albert-WuBinBin/ssm-example,可以clone下來,執行上面的訪問地址,直接訪問就可以了。