項目中有一需求:需要讀取excel中的信息,帶圖片,需要將每一行的圖片,做對應,整理方法如下:
- controller層
@PostMapping("/uploadFile")
public List<Map<String, String>> uploadMonitorItem(MultipartFile upfile, String providerId) throws Exception {
InputStream in = null;
List<Map<String, String>> listob = null;
in = upfile.getInputStream();
listob = ExcelUtil.readExcelByInputStream(in, providerId);
return listob;
}
2.service層
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.qskj.framework.config.ERPConfig;
public class ExcelUtil {
/**
* 讀取 Excel文件內容
*
* @param inputstream 文件輸入流
* @return
* @throws Exception
*/
public static List<Map<String, String>> readExcelByInputStream(InputStream inputstream, String providerId)
throws Exception {
// 結果集
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
XSSFWorkbook wb = new XSSFWorkbook(inputstream);
String filePath = ERPConfig.getProfile() + "/" + "pic/" + providerId + "/";//圖片保存路徑
final XSSFSheet sheet = wb.getSheetAt(0);// 得到Excel工作表對象
Map<String, PictureData> map = ExcelImgUtil.getPictures(sheet);//獲取圖片和位置
Map<String, String> pathMap = ExcelImgUtil.printImg(map, filePath);//寫入圖片,並返回圖片路徑,key:圖片座標,value:圖片路徑
list = ExcelImgUtil.readData(sheet, pathMap,providerId);
return list;
}
}
3,工具類
package com.qskj.project.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import com.qskj.common.utils.security.Md5Utils;
import com.qskj.framework.config.ERPConfig;
public class ExcelImgUtil {
private static int counter = 0;
/**
* 獲取圖片和位置 (xlsx)
*
* @param sheet
* @return
* @throws IOException
*/
public static Map<String, PictureData> getPictures(XSSFSheet sheet) throws IOException {
Map<String, PictureData> map = new HashMap<String, PictureData>();
List<POIXMLDocumentPart> list = sheet.getRelations();
for (POIXMLDocumentPart part : list) {
if (part instanceof XSSFDrawing) {
XSSFDrawing drawing = (XSSFDrawing) part;
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor anchor = picture.getPreferredSize();
CTMarker marker = anchor.getFrom();
String key = marker.getRow() + "-" + marker.getCol();
byte[] data = picture.getPictureData().getData();
map.put(key, picture.getPictureData());
}
}
}
return map;
}
public static Map<String, String> printImg(Map<String, PictureData> sheetList, String path) throws IOException {
Map<String, String> pathMap = new HashMap<String, String>();
Object[] key = sheetList.keySet().toArray();
File f = new File(path);
if (!f.exists()) {
f.mkdirs(); // 創建目錄
}
for (int i = 0; i < sheetList.size(); i++) {
// 獲取圖片流
PictureData pic = sheetList.get(key[i]);
// 獲取圖片索引
String picName = key[i].toString();
// 獲取圖片格式
String ext = pic.suggestFileExtension();
String fileName = encodingFilename(picName);
byte[] data = pic.getData();
// 圖片保存路徑
String imgPath = path + fileName + "." + ext;
FileOutputStream out = new FileOutputStream(imgPath);
imgPath = imgPath.substring(ERPConfig.getProfile().length(), imgPath.length());// 截取圖片路徑
pathMap.put(picName, imgPath);
out.write(data);
out.close();
}
return pathMap;
}
private static final String encodingFilename(String fileName) {
fileName = fileName.replace("_", " ");
fileName = Md5Utils.hash(fileName + System.nanoTime() + counter++);
return fileName;
}
/**
* 讀取excel文字
*
* Excel 07版本以上
*
* @param sheet
*/
public static List<Map<String, String>> readData(XSSFSheet sheet, Map<String, String> map,String providerId) {
List<Map<String, String>> newList = new ArrayList<Map<String, String>>();// 單行數據
try {
int rowNum = sheet.getLastRowNum() + 1;
for (int i = 1; i < rowNum; i++) {// 從第三行開始讀取數據,第一行是備註,第二行是標頭
Row row = sheet.getRow(i);// 得到Excel工作表的行
if (row != null) {
int col = row.getPhysicalNumberOfCells();
// 單行數據
Map<String, String> mapRes = new HashMap<String, String>();// 每格數據
for (int j = 0; j < col; j++) {
Cell cell = row.getCell(j);
if (cell == null) {
// arrayString.add("");
} else if (cell.getCellType() == 0) {// 當時數字時的處理
mapRes.put(getMapKey(j), new Double(cell.getNumericCellValue()).toString());
} else {// 如果EXCEL表格中的數據類型爲字符串型
mapRes.put(getMapKey(j), cell.getStringCellValue().trim());
}
}
if (i != 1) {// 不是標頭列時,添加圖片路徑
String path = map.get(i + "-9");
mapRes.put(getMapKey(9), path);
}
mapRes.put("providerId", providerId);
newList.add(mapRes);
}
}
} catch (Exception e) {
}
return newList;
}
public static String getMapKey(int num) {
String res = "";
switch (num) {
case 0:// 分類
res = "secondDictCode";
break;
case 1:// 產品名稱
res = "productName";
break;
case 2:// 規格型號
res = "specification";
break;
case 3:// 計量單位
res = "unit";
break;
case 4:// 風格
res = "style";
break;
case 5:// 顏色
res = "color";
break;
case 6:// 採購單價
res = "purchasePrice";
break;
case 7:// 材質
res = "material";
break;
case 8:// 備註
res = "remark";
break;
case 9:// 產品圖片
res = "picture";
break;
default:
break;
}
return res;
}
}
- postman請求測試:/poi/uploadFile?providerId=5
- 最終效果
[
{
"unit": "計量單位",
"color": "顏色",
"material": "材質",
"providerId": "5",
"specification": "規格型號",
"style": "風格",
"remark": "備註",
"purchasePrice": "採購單價",
"secondDictCode": "分類",
"productName": "產品名稱",
"picture": "產品圖片"
},
{
"unit": "平方米",
"color": "白色,綠色,紅色",
"material": "木質1",
"providerId": "5",
"specification": "600*900",
"style": "美式,北歐,中式",
"remark": "大薩達十大1",
"purchasePrice": "66.8",
"secondDictCode": "傢俱",
"productName": "牀",
"picture": "/pic/5/b3e42b2d741cc16bff4fefaa6bb61d87.jpeg"
},
{
"providerId": "5",
"picture": null
}
]
另附項目地址以及excel文件,整體方法: