Springmvc檔案上傳例子,上傳帶圖片的Excel,並利用poi解析。
阿新 • • 發佈:2018-12-16
直奔主題,第一步:上傳一個帶圖片的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下來,執行上面的訪問地址,直接訪問就可以了。