JAVA:Excel匯入匯出詳解(2)--匯入
阿新 • • 發佈:2018-11-11
1. 瀏覽資料夾,選擇需要上傳的檔案
程式碼
jsp
<li class="col-sm-1"> <span>上 傳:</span> </li> <li class="col-sm-3"> <span> <input type="file" id="upfile" name="upfile" placeholder=""/> </span> </li> <li class="col-sm-2"> <button onclick="importExp();" class="btn btn-success btn-sm ">導 入</button> <span>格式:.xls</span> </li>
js
//匯入檔案 function importExp() { var formData = new FormData(); var name = $("#upfile").val(); formData.append("file", $("#upfile")[0].files[0]); formData.append("name", name); $.ajax({ url: '/manage/order/upload', type: 'POST', async: false, data: formData, // 告訴jQuery不要去處理髮送的資料 processData: false, // 告訴jQuery不要去設定Content-Type請求頭 contentType: false, beforeSend: function () { console.log("正在進行,請稍候"); }, success: function (responseStr) { if (responseStr != "0") { alert("匯入成功" + responseStr + "條資料!"); } else { alert("匯入失敗"); } } }); }
注意
2. 將本地檔案上傳至伺服器指定位置
程式碼
/** * 上傳檔案 * * @param * @return */ @RequestMapping(value = "upload", method = RequestMethod.POST) @ResponseBody public String importExp(@RequestParam("file") MultipartFile file, HttpServletRequest request) { String realPath = request.getRealPath(""); String filePath = realPath + "/upload/upload.xls"; int resmsg = 0; // 判斷檔案是否為空 if (!file.isEmpty()) { Integer rowCount = 1000; Integer columnCount = 8; try { deleteFile(filePath); // 轉存檔案 file.transferTo(new File(filePath)); File fileNew = new File(filePath); List<ExcelSheetPO> list = readExcel(fileNew, rowCount, columnCount); System.out.println(list); resmsg = manualOrder(list.get(0).getDataList()); } catch (Exception e) { e.printStackTrace(); } } return (resmsg + ""); }
注意
路徑獲取,可使用 String realPath = request.getRealPath("");
獲取root的路徑,在拼出file的路徑。
3. 伺服器解析Excel檔案
ExcelUtil程式碼
package com.jy.util.excelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
//import com.zkingsoft.common.tools.FileUtil;
/**
* Created by SchonZhang on 2018/10/19 0019.
* excel工具類 提供讀取和寫入excel的功能
*
*/
public class ExcelUtil {
/**
* 標題樣式
*/
private final static String STYLE_HEADER = "header";
/**
* 表頭樣式
*/
private final static String STYLE_TITLE = "title";
/**
* 資料樣式
*/
private final static String STYLE_DATA = "data";
/**
* 儲存樣式
*/
private static final HashMap<String, CellStyle> cellStyleMap = new HashMap<>();
/**
* 讀取excel檔案裡面的內容 支援日期,數字,字元,函式公式,布林型別
* @param file
* @param rowCount
* @param columnCount
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public static List<ExcelSheetPO> readExcel(File file, Integer rowCount, Integer columnCount)
throws FileNotFoundException, IOException {
// 根據字尾名稱判斷excel的版本
// String extName = FileUtil.getFileExtName(file);
String extName = "."+FilenameUtils.getExtension(file.getName());
Workbook wb = null;
if (ExcelVersion.V2003.getSuffix().equals(extName)) {
wb = new HSSFWorkbook(new FileInputStream(file));
} else if (ExcelVersion.V2007.getSuffix().equals(extName)) {
wb = new XSSFWorkbook(new FileInputStream(file));
} else {
// 無效字尾名稱,這裡之能保證excel的字尾名稱,不能保證檔案型別正確,不過沒關係,在建立Workbook的時候會校驗檔案格式
throw new IllegalArgumentException("Invalid excel version");
}
// 開始讀取資料
List<ExcelSheetPO> sheetPOs = new ArrayList<>();
// 解析sheet
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
List<List<Object>> dataList = new ArrayList<>();
//合併單元格處理,獲取合併行
List<CellRangeAddress> cras = getCombineCell(sheet);
ExcelSheetPO sheetPO = new ExcelSheetPO();
sheetPO.setSheetName(sheet.getSheetName());
sheetPO.setDataList(dataList);
int readRowCount = 0;
if (rowCount == null || rowCount > sheet.getPhysicalNumberOfRows()) {
readRowCount = sheet.getPhysicalNumberOfRows();
} else {
readRowCount = rowCount;
}
// 解析sheet 的行
for (int j = sheet.getFirstRowNum(); j < readRowCount; j++) {
//判斷是否為合併行
if(isMergedRegion(sheet,j,0)){
int lastRow = getRowNum(cras,sheet.getRow(i).getCell(0),sheet);
for(;j<=lastRow;j++){
Row row = sheet.getRow(j);
if (row == null) {
continue;
}
if (row.getFirstCellNum() < 0) {
continue;
}
int readColumnCount = 0;
if (columnCount == null || columnCount > row.getLastCellNum()) {
readColumnCount = (int) row.getLastCellNum();
} else {
readColumnCount = columnCount;
}
List<Object> rowValue = new LinkedList<Object>();
// 解析sheet 的列
for (int k = 0; k < readColumnCount; k++) {
// if(isMergedRegion(sheet,j,k)) {
// rowValue.add(getMergedRegionValue(sheet, j, k));
// }else{
// Cell cell = row.getCell(k);
// rowValue.add(getCellValue(wb, cell));
// }
//不取合併單元格的數值
Cell cell = row.getCell(k);
rowValue.add(getCellValue(wb, cell));
}
dataList.add(rowValue);
}
j--;
}else{
Row row = sheet.getRow(j);
if (row == null) {
continue;
}
if (row.getFirstCellNum() < 0) {
continue;
}
int readColumnCount = 0;
if (columnCount == null || columnCount > row.getLastCellNum()) {
readColumnCount = (int) row.getLastCellNum();
} else {
readColumnCount = columnCount;
}
List<Object> rowValue = new LinkedList<Object>();
// 解析sheet 的列
for (int k = 0; k < readColumnCount; k++) {
Cell cell = row.getCell(k);
rowValue.add(getCellValue(wb, cell));
}
dataList.add(rowValue);
}
}
sheetPOs.add(sheetPO);
}
return sheetPOs;
}
private static Object getCellValue(Workbook wb, Cell cell) {
Object columnValue = null;
if (cell != null) {
DecimalFormat df = new DecimalFormat("0");// 格式化 number
// String
// 字元
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化日期字串
DecimalFormat nf = new DecimalFormat("0.00");// 格式化數字
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
columnValue = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
columnValue = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle().getDataFormatString())) {
columnValue = nf.format(cell.getNumericCellValue());
} else {
columnValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()));
}
break;
case Cell.CELL_TYPE_BOOLEAN:
columnValue = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_BLANK:
columnValue = "#";
break;
case Cell.CELL_TYPE_FORMULA:
// 格式單元格
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateFormulaCell(cell);
CellValue cellValue = evaluator.evaluate(cell);
columnValue = cellValue.getNumberValue();
break;
default:
columnValue = cell.toString();
}
}
return columnValue;
}
/**
* 在硬碟上寫入excel檔案
* @param version
* @param excelSheets
* @param filePath
* @throws IOException
*/
public static void createWorkbookAtDisk(ExcelVersion version, List<ExcelSheetPO> excelSheets, String filePath)
throws IOException {
FileOutputStream fileOut = new FileOutputStream(filePath);
createWorkbookAtOutStream(version, excelSheets, fileOut, true);
}
/**
* 把excel表格寫入輸出流中,輸出流會被關閉
* @param version
* @param excelSheets
* @param outStream
* @param closeStream
* 是否關閉輸出流
* @throws IOException
*/
public static void createWorkbookAtOutStream(ExcelVersion version, List<ExcelSheetPO> excelSheets,
OutputStream outStream, boolean closeStream) throws IOException {
if (CollectionUtils.isNotEmpty(excelSheets)) {
Workbook wb = createWorkBook(version, excelSheets);
wb.write(outStream);
if (closeStream) {
outStream.close();
}
}
}
private static Workbook createWorkBook(ExcelVersion version, List<ExcelSheetPO> excelSheets) {
Workbook wb = createWorkbook(version);
for (int i = 0; i < excelSheets.size(); i++) {
ExcelSheetPO excelSheetPO = excelSheets.get(i);
if (excelSheetPO.getSheetName() == null) {
excelSheetPO.setSheetName("sheet" + i);
}
// 過濾特殊字元
Sheet tempSheet = wb.createSheet(WorkbookUtil.createSafeSheetName(excelSheetPO.getSheetName()));
buildSheetData(wb, tempSheet, excelSheetPO, version);
}
return wb;
}
private static void buildSheetData(Workbook wb, Sheet sheet, ExcelSheetPO excelSheetPO, ExcelVersion version) {
sheet.setDefaultRowHeight((short) 400);
sheet.setDefaultColumnWidth((short) 30);
createTitle(sheet, excelSheetPO, wb, version);
createHeader(sheet, excelSheetPO, wb, version);
createBody(sheet, excelSheetPO, wb, version);
}
private static void createBody(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
List<List<Object>> dataList = excelSheetPO.getDataList();
for (int i = 0; i < dataList.size() && i < version.getMaxRow(); i++) {
List<Object> values = dataList.get(i);
Row row = sheet.createRow(2 + i);
for (int j = 0; j < values.size() && j < version.getMaxColumn(); j++) {
Cell cell = row.createCell(j);
cell.getCellStyle().cloneStyleFrom(getStyle(STYLE_DATA, wb));
if(values.get(j)!=null){
cell.setCellValue(values.get(j).toString());
}
}
}
}
private static void createHeader(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
String[] headers = excelSheetPO.getHeaders();
Row row = sheet.createRow(1);
for (int i = 0; i < headers.length && i < version.getMaxColumn(); i++) {
Cell cellHeader = row.createCell(i);
cellHeader.getCellStyle().cloneStyleFrom(getStyle(STYLE_HEADER, wb));
cellHeader.setCellValue(headers[i]);
}
}
private static void createTitle(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
Row titleRow = sheet.createRow(0);
Cell titleCel = titleRow.createCell(0);
titleCel.setCellValue(excelSheetPO.getTitle());
// titleCel.setCellStyle(getStyle(STYLE_TITLE, wb));
titleCel.getCellStyle().cloneStyleFrom(getStyle(STYLE_TITLE, wb));
// 限制最大列數
int column = excelSheetPO.getDataList().size() > version.getMaxColumn() ? version.getMaxColumn()
: excelSheetPO.getDataList().size();
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, column ));
}
private static CellStyle getStyle(String type, Workbook wb) {
if (cellStyleMap.containsKey(type)) {
return cellStyleMap.get(type);
}
// 生成一個樣式
CellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setWrapText(true);
if (STYLE_HEADER == type) {
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
Font font = wb.createFont();
font.setFontHeightInPoints((short) 16);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(font);
} else if (STYLE_TITLE == type) {
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
Font font = wb.createFont();
font.setFontHeightInPoints((short) 18);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(font);
} else if (STYLE_DATA == type) {
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
Font font = wb.createFont();
font.setFontHeightInPoints((short) 12);
style.setFont(font);
}
cellStyleMap.put(type, style);
return style;
}
private static Workbook createWorkbook(ExcelVersion version) {
switch (version) {
case V2003:
return new HSSFWorkbook();
case V2007:
return new XSSFWorkbook();
}
return null;
}
/**
* 獲取單元格的值
* @param cell
* @return
*/
public static String getCellValue(Cell cell){
if(cell == null) return "";
if(cell.getCellType() == Cell.CELL_TYPE_STRING){
return cell.getStringCellValue();
}else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
return String.valueOf(cell.getBooleanCellValue());
}else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
return cell.getCellFormula() ;
}else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
return String.valueOf(cell.getNumericCellValue());
}
return "";
}
/**
* 合併單元格處理,獲取合併行
* @param sheet
* @return List<CellRangeAddress>
*/
public static List<CellRangeAddress> getCombineCell(Sheet sheet)
{
List<CellRangeAddress> list = new ArrayList<CellRangeAddress>();
//獲得一個 sheet 中合併單元格的數量
int sheetmergerCount = sheet.getNumMergedRegions();
//遍歷所有的合併單元格
for(int i = 0; i<sheetmergerCount;i++)
{
//獲得合併單元格儲存進list中
CellRangeAddress ca = sheet.getMergedRegion(i);
list.add(ca);
}
return list;
}
//獲得合併單元格的起始行, 結束行
private static int getRowNum(List<CellRangeAddress> listCombineCell, Cell cell, Sheet sheet){
int xr = 0;
int firstC = 0;
int lastC = 0;
int firstR = 0;
int lastR = 0;
for(CellRangeAddress ca:listCombineCell)
{
//獲得合併單元格的起始行, 結束行, 起始列, 結束列
firstC = ca.getFirstColumn();
lastC = ca.getLastColumn();
firstR = ca.getFirstRow();
lastR = ca.getLastRow();
if(cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR)
{
if(cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC)
{
xr = lastR;
}
}
}
return lastR;
// return xr;
}
/**
* 判斷單元格是否為合併單元格,是的話則將單元格的值返回
* @param listCombineCell 存放合併單元格的list
* @param cell 需要判斷的單元格
* @param sheet sheet
* @return
*/
public String isCombineCell(List<CellRangeAddress> listCombineCell,Cell cell,Sheet sheet)
throws Exception{
int firstC = 0;
int lastC = 0;
int firstR = 0;
int lastR = 0;
String cellValue = null;
for(CellRangeAddress ca:listCombineCell)
{
//獲得合併單元格的起始行, 結束行, 起始列, 結束列
firstC = ca.getFirstColumn();
lastC = ca.getLastColumn();
firstR = ca.getFirstRow();
lastR = ca.getLastRow();
if(cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR)
{
if(cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC)
{
Row fRow = sheet.getRow(firstR);
Cell fCell = fRow.getCell(firstC);
cellValue = getCellValue(fCell);
break;
}
}
else
{
cellValue = "";
}
}
return cellValue;
}
/**
* 獲取合併單元格的值
* @param sheet
* @param row
* @param column
* @return
*/
public static String getMergedRegionValue(Sheet sheet, int row, int column){
int sheetMergeCount = sheet.getNumMergedRegions();
for(int i = 0 ; i < sheetMergeCount ; i++){
CellRangeAddress ca = sheet.getMergedRegion(i);
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow();
if(row >= firstRow && row <= lastRow){
if(column >= firstColumn && column <= lastColumn){
Row fRow = sheet.getRow(firstRow);
Cell fCell = fRow.getCell(firstColumn);
return getCellValue(fCell) ;
}
}
}
return null ;
}
/**
* 判斷指定的單元格是否是合併單元格
* @param sheet
* @param row 行下標
* @param column 列下標
* @return
*/
private static boolean isMergedRegion(Sheet sheet, int row, int column) {
int sheetMergeCount = sheet.getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress range = sheet.getMergedRegion(i);
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
if(row >= firstRow && row <= lastRow){
if(column >= firstColumn && column <= lastColumn){
return true;
}
}
}
return false;
}
}
ExcelSheetPO程式碼
package com.jy.util.excelUtil;
/**
* Created by SchonZhang on 2018/10/19 0019.
*/
import java.util.List;
/**
* 定義表格的資料物件
*/
public class ExcelSheetPO {
/**
* sheet的名稱
*/
private String sheetName;
/**
* 表格標題
*/
private String title;
/**
* 頭部標題集合
*/
private String[] headers;
/**
* 資料集合
*/
private List<List<Object>> dataList;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String[] getHeaders() {
return headers;
}
public void setHeaders(String[] headers) {
this.headers = headers;
}
public List<List<Object>> getDataList() {
return dataList;
}
public void setDataList(List<List<Object>> dataList) {
this.dataList = dataList;
}
public String getSheetName() {
return sheetName;
}
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
}
ExcelVersion程式碼
package com.jy.util.excelUtil;
/**
* Created by SchonZhang on 2018/10/19 0019.
*/
/**
* excel版本列舉
*
*/
public enum ExcelVersion {
/**
* 雖然V2007版本支援最大支援1048575 * 16383 ,
* V2003版支援65535*255
* 但是在實際應用中如果使用如此龐大的物件集合會導致記憶體溢位,
* 因此這裡限制最大為10000*100,如果還要加大建議先通過單元測試進行效能測試。
* 1000*100 全部匯出預計時間為27s左右
*/
V2003(".xls", 10000, 7), V2007(".xlsx", 100, 100);
private String suffix;
private int maxRow;
private int maxColumn;
ExcelVersion(String suffix, int maxRow, int maxColumn) {
this.suffix = suffix;
this.maxRow = maxRow;
this.maxColumn = maxColumn;
}
public String getSuffix() {
return this.suffix;
}
public int getMaxRow() {
return maxRow;
}
public void setMaxRow(int maxRow) {
this.maxRow = maxRow;
}
public int getMaxColumn() {
return maxColumn;
}
public void setMaxColumn(int maxColumn) {
this.maxColumn = maxColumn;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
注意
- FilenameUtils:需引入import org.apache.commons.io.FilenameUtils;
- 格式xls V2003 對應HSSFWorkbook
- 格式xlsl V2007對應XSSFWorkbook
- 本程式碼支援對合並單元格的處理,若不需要,可刪除
- 表格中需要匯入的列數,由ExcelVersion中的maxColumn控制
4. 將Excel中解析的資料存入資料庫中
程式碼
/**
* 將解析出的資料存入資料庫
* @param list
* @return
*/
public int manualOrder(List<List<Object>> list) {
boolean flag = true;
Long userId = 1L;
Calendar currentDate = Calendar.getInstance();
DdOrderVo ddOrderVo = null;
int successOrder = 0;
Long mainorderNum = this.getOrdercode(userId);
Long orderNum = this.getOrdercode(userId);
try {
//產生新訂單///////////////////////////////////////////////////////////////////////
for (List<Object> excelSheetPO : list) {
ddOrderVo = new DdOrderVo();
ddOrderVo.setOrderType(2);
// ddOrderVo.setOuterOrderNum(structurizationTrade.getFullOrderInfo().getOrderInfo().getTid());
//插入訂單商品表
//根據商品名稱獲得商品id////
DdGoodsVo ddGoodsVo = new DdGoodsVo();
//判斷資料是否滿足8個都對應
if (excelSheetPO.size() < 8) {
continue;
}
ddGoodsVo.setName(excelSheetPO.get(6) + "");
ddGoodsVo = ddGoodsService.findById(ddGoodsVo);
if (ddGoodsVo == null) {
continue;
}
DdOrderGoodsVo orderGoodsVo = new DdOrderGoodsVo();
orderGoodsVo.setGoodsName(ddGoodsVo.getName());
orderGoodsVo.setGoodsId(ddGoodsVo != null ? ddGoodsVo.getId() : 0);
String goodsNum = excelSheetPO.get(7).toString();
orderGoodsVo.setGoodsNum((int) Double.parseDouble((goodsNum)));
orderGoodsVo.setGoodsState(Short.parseShort("5"));
orderGoodsVo.setUserId(userId);
Object o = excelSheetPO.get(0);
if (o.toString() != "#" || excelSheetPO.get(0) != "#") {
mainorderNum = this.getOrdercode(userId);
orderNum = this.getOrdercode(userId);
//生成訂單////////////////////////////////////////////
ddOrderVo = new DdOrderVo();
ddOrderVo.setMainorderNum(mainorderNum);
ddOrderVo.setOrderNum(orderNum);
ddOrderVo.setOrderState(1);
ddOrderVo.setOrderType(2);
ddOrderVo.setOrderTime(DateUtil.getTimestamp());
ddOrderVo.setUserId(userId);
ddOrderService.insert(ddOrderVo);
//生成訂單發貨地址/////////////////////////////////////////
SysAddressVo sysAddressVo = new SysAddressVo();
sysAddressVo.setUserid(ddOrderVo.getId());
sysAddressVo.setAddressee((excelSheetPO.get(0) + ""));
sysAddressVo.setPhone((excelSheetPO.get(5) + ""));
sysAddressVo.setProvince((excelSheetPO.get(1) + ""));
sysAddressVo.setCity((excelSheetPO.get(2) + ""));
sysAddressVo.setDistrict((excelSheetPO.get(3) + ""));
sysAddressVo.setAddress((excelSheetPO.get(4) + ""));
sysAddressService.insert(sysAddressVo);
}
orderGoodsVo.setOrderNum(orderNum);
ddOrderGoodsService.insert(orderGoodsVo);
successOrder++;
}
} catch (Exception e) {
e.printStackTrace();
}
return successOrder;
}
注意
- 注意處理一個訂單多個商品即excel中合併單元格的處理。
以上就是我在做excel匯入中遇到的一些問題;
如果能幫到你,我將非常的開心;
若果有哪裡沒有說清楚的,可以再評論區寫出來,我會每天處理一次的。