jxl實現excel匯入匯出的完整demo
阿新 • • 發佈:2018-12-23
@RequestMapping("/pointsImport.do")
public void StructureImport(HttpServletRequest request, HttpServletResponse response, Long driveId) {
String msg = null;
try {
response.setContentType("text/html;charset=utf-8");
MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
MultipartFile fileM = re.getFile("upFile" );
CommonsMultipartFile cf = (CommonsMultipartFile) fileM;
InputStream inputStream = cf.getInputStream();
if (inputStream != null) {
Workbook workbook = null;
try {
workbook = Workbook.getWorkbook(inputStream);
processData(workbook, response, driveId);
} catch (Exception e) {
logger.error("上傳檔案錯誤:" + e);
}
}
} catch (Exception e) {
logger.error("上傳檔案錯誤:" + e);
}
}
也可以用path來獲取檔案,可path大多時候,獲取的是相對路徑,具體為什麼我也不清楚…..
response.setContentType("text/html;charset=utf-8");
MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
CommonsMultipartFile file = (CommonsMultipartFile) re.getFile("upFile" );
DiskFileItem dfi = (DiskFileItem) file.getFileItem();
String path = dfi.getStoreLocation().getPath().toString();
File toFile = new File(path);
if (toFile != null) {
//file.transferTo(toFile);
Workbook workbook = null;
try {
// excel檔案上傳
workbook = Workbook.getWorkbook(toFile);
//處理資料,如果需要userid的話,這裡可以追加
processData(workbook, response);
} catch (Exception e) {
msg = "上傳檔案錯誤!";
}
}
} catch (Exception e) {
msg = "上傳檔案錯誤!";
}
上傳控制元件:
<form id="edit_form" action="<%=basePath%>tpManagerDownLoad/pointsImport.do" method="post" class="data-form" enctype="multipart/form-data">
<input type="hidden" name="deviceStoreId" value="${deviceStoreId }" />
<input type="hidden" name="id" value="${driveId}" />
<input type="hidden" id="document" name="document" value="${document }" />
<table width="100%">
<tbody>
<tr>
<td class="field-lable"><label>驅動檔案:</label></td>
<td><input type="file" title="請選擇檔案" id="upFile" name="upFile" onselect="getFileName()" onchange="getFileName()"/></td>
</tr>
</tbody>
</table>
<table class="btn-ct">
<tbody><tr>
<td>
<button type="submit" id="save">確定</button>
</td>
</tr>
</tbody></table>
</div>
</form>
也可以這麼寫:
<div class="panel-top-banner">
<form action="StructureExIm/StructureImport.do" id="form" method="post" enctype="multipart/form-data">
上傳:
<input id="upFile" name="upFile" type="file" />
<input type="submit" value="提交"/>
<br/>
</form>
</div>
所有上傳和下載的程式碼demo:
package com.tdenergys.platform.web.controller;
import com.tdenergys.platform.core.model.Project;
import com.tdenergys.platform.core.model.Structure;
import com.tdenergys.platform.core.service.IProjectService;
import com.tdenergys.platform.core.service.IStructureService;
import jxl.*;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.*;
import jxl.write.biff.RowsExceededException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.lang.Boolean;
import java.util.*;
import java.util.regex.Matcher;
/**
* 結構匯入
* Created by Jerry.ZR on 15-3-4.
*/
@Controller
@RequestMapping("/StructureExIm")
public class StructureExImController {
@Resource(name = "structureService")
private IStructureService structureService;
@Resource(name = "projectService")
private IProjectService projectService;
private static final String IMPORT_TEMP_FILE_NAME = "Structure_import_temp.xls";
private static final String[] STORE_HOUSE_IMPORT_TEMP_FILE_TITLE =
{"專案名稱", "父親名稱", "結構名稱", "結構編號"};
private static final String[] STORE_HOUSE_IMPORT_TEMP_FILE_TITLE_ID =
{"project_id", "parent_id", "name", "code"};
public static final String STORE_HOUSE_FAIL = "失敗";
public static final String STORE_HOUSE_SUCCESS = "成功";
private static final String IMPORT_TEMP_RESULT_NAME = "Structure_import_result";
//資料字典頁的表頭
private static final String[] STORE_HOUSE_DICTIONARY_TITLE = {"專案名稱"};
//與資料字典表頭對應的id號
private static final String STORE_HOUSE_DICTIONARY_ID = "projectName";
/**
* 裝置匯入 模版下載
*
* @param request
* @param response
* @return
*/
@RequestMapping("/StructureDownload.do")
public void StructureDownload(HttpServletRequest request, HttpServletResponse response) {
response.setCharacterEncoding("utf-8");
response.setContentType("aplication/msexcel;charset=utf-8"); // 設定檔案型別
response.setHeader("Content-disposition", "attachment; filename=" + IMPORT_TEMP_FILE_NAME);
WritableWorkbook workbook = null;
String[] titles = STORE_HOUSE_IMPORT_TEMP_FILE_TITLE;
String[] titleIds = STORE_HOUSE_IMPORT_TEMP_FILE_TITLE_ID;
try {
// 建立工作簿
workbook = Workbook.createWorkbook(response.getOutputStream());
// 建立匯入資料頁
WritableSheet sheet0 = workbook.createSheet("匯入資料", 0);
CellView cellView = new CellView();
// 設定自動大小
cellView.setAutosize(true);
// 設定字型 普通格式
WritableFont font = new WritableFont(WritableFont.ARIAL, 10);
WritableCellFormat cellFormat = new WritableCellFormat(font);
// 設定背景顏色;
cellFormat.setBackground(Colour.YELLOW);
// 設定必填欄位為紅色字型 特殊字型
WritableFont fontRed = new WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.RED);
WritableCellFormat cellFormatRed = new WritableCellFormat(fontRed);
// 設定背景色為黃色
cellFormatRed.setBackground(Colour.YELLOW);
// 定義單元格為文字樣式
WritableCellFormat wcf = new WritableCellFormat(NumberFormats.TEXT);
// 定義一個列顯示樣式
CellView cv = new CellView();
// 把定義的單元格格式初始化進去
cv.setFormat(wcf);
// 設定列寬度(不設定的話是0,不會顯示)
cv.setSize(10 * 265);
//excel寫上註釋
WritableCellFeatures projectNameWCF = new WritableCellFeatures();
projectNameWCF.setComment("專案名稱不能為空");
WritableCellFeatures structureNameWCF = new WritableCellFeatures();
structureNameWCF.setComment("結構名稱不能為空");
if (titles != null) {
for (int i = 0; i < titles.length; i++) {
// 將所有列設定為文字格式,且寬度為10 * 265
sheet0.setColumnView(i, cv);
String title = titles[i];
String titleId = titleIds[i];
if (StringUtils.isNotBlank(title)) {
// 列名
Label label = null;
// 設定必填欄位為紅色字型
if (i == 0 || i == 2) {
// Label(列,行,標題)
label = new Label(i, 0, titles[i], cellFormatRed);
} else {
label = new Label(i, 0, titles[i], cellFormat);
}
//編寫excel註釋
if ("project_id".equals(titleId)) {
label.setCellFeatures(projectNameWCF);
}
if ("name".equals(titleId)) {
label.setCellFeatures(structureNameWCF);
}
sheet0.addCell(label);
}
}
}
// 建立資料辭典頁
WritableSheet sheet1 = workbook.createSheet("資料辭典", 1);
Map<String, Object> result2 = new HashMap<String, Object>();
Project p = new Project();
List<Project> list = projectService.selectEntitys(p);
result2.put("projectName", list);
List<Object> listProject = new ArrayList<Object>();
//將多個list的資料放入一個Map中
if (list.size() != 0) {
List<Project> valueProject = (List<Project>) result2.get("projectName");
for (int j = 0; j < valueProject.size(); j++) {
listProject.add(valueProject.get(j).getName());
}
}
Map<String, Object> result = new HashMap<String, Object>();
result.put("projectName", listProject);
String[] DataDictionary = STORE_HOUSE_DICTIONARY_ID.split(",");
String[] dictionaryTitles = STORE_HOUSE_DICTIONARY_TITLE;
//對應sheet0中的第幾列
int[] dictionaryId = {0};
String key = "";
String dictionaryTitle = "";
int columnNum;
//每列都執行
for (int i = 0; i < DataDictionary.length; i++) {
//key為第i列的列名id
key = DataDictionary[i];
//對應sheet0中的第幾列
columnNum = dictionaryId[i];
//value接收的是result中第一列的值
List<Object> value = (List<Object>) result.get(key);
List<String> codeList = new ArrayList<String>();
//獲取第I列的文字資訊
dictionaryTitle = dictionaryTitles[i];
//給第一列命名
if (StringUtils.isNotBlank(dictionaryTitle)) {
Label label = new Label(i, 0, dictionaryTitles[i], cellFormat);
sheet1.addCell(label);
}
if (value != null) {
for (int j = 0; j < value.size(); j++) {
String manufactureValue = "";
Object manufactureValueMap = value.get(j);
manufactureValue = manufactureValueMap.toString();
Label label = new Label(i, j + 1, manufactureValue);
sheet1.addCell(label);
codeList.add(manufactureValue);
}
// 設定資料有效性,預設設定1000行
int[] target = new int[2];
int[] current = new int[2];
//將列表框的資料隱藏在22行附近,這個列數可以隨意改,只要比當前列數大就行
int defultColumn = 22;
Label label = new Label(defultColumn + i, 0, dictionaryTitles[i]);
//從第幾行開始展現下拉框
for (int j = 1; j < 1000; j++) {
//行
target[0] = columnNum;
target[1] = j;
//列
current[0] = defultColumn + i;
current[1] = 1;
buildDataValidationCell(sheet0, target, current, codeList);
}
}
}
workbook.write();
workbook.close();
} catch (Exception e) {
e.printStackTrace();
// logger.error("匯出excel檔案錯誤!" + e);
}
}
/**
* 建立excel的資料有效性
*
* @param sheet
* @param target 要設定資料驗證性的單元格位置
* @param current 要存放驗證性資料的單元格位置
* @param data
* @return
*/
private int[] buildDataValidationCell(WritableSheet sheet, int[] target, int[] current, List<String> data) {
try {
//data儲存的是下拉框中的資訊
if (data.size() == 0)
return current;
//strings去掉data中空的資料
List<String> strings = new ArrayList<String>();
for (String d : data) {
if (d != null && !"".equals(d.trim()))
strings.add(d);
}
//如果有65535行資料,那麼報錯
if (strings.size() > 65535)
throw new RuntimeException("excel2003單列上限,資料驗證只能使用單列或單行");
// excel2003上限是65535,所以隱藏的行數超過5w就換另外一列,
// 列上限是255。暫時不考慮行列都到上限的情況
if (current[1] > 50000 || (current[1] > 50000 && strings.size() > 15535)) {
current[0] = current[0] + 1;
current[1] = 0;
}
// 構建下拉資料範圍
buildDataValidationRange(sheet, target, current, strings);
// 設定隱藏
CellView cv = new CellView();
cv.setHidden(true);
sheet.setColumnView(current[0], cv);
// 填充資料
for (String s : strings) {
Label b = new Label(current[0], current[1], s);
sheet.addCell(b);
current[1] += 1;
}
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
return current;
}
/**
* 構建下拉資料範圍
*
* @param sheet
* @param target 要設定資料驗證性的單元格位置
* @param current 要存放驗證性資料的單元格位置
* @param strings
* @throws WriteException
* @throws RowsExceededException
*/
private void buildDataValidationRange(WritableSheet sheet, int[] target, int[] current, List<String> strings) throws WriteException, RowsExceededException {
WritableCellFeatures wcf = null;
// 資料驗證初始cell值,預設為空
Label targetCell = new Label(target[0], target[1], "");
wcf = new WritableCellFeatures();
// 資料驗證範圍
StringBuffer buff = new StringBuffer();
// 起點
CellReferenceHelper.getCellReference(current[0], true, current[1], true, buff);
buff.append(":");
// 終點
CellReferenceHelper.getCellReference(current[0], true, current[1] + strings.size() - 1, true, buff);
// 設定資料驗證性
wcf.setDataValidationRange(buff.toString());
targetCell.setCellFeatures(wcf);
sheet.addCell(targetCell);
}
/**
* 對匯入模版excel進行解析並插入資料庫
*
* @param request
* @param response
* @return
*/
@RequestMapping("/StructureImport.do")
public void StructureImport(HttpServletRequest request, HttpServletResponse response) {
String msg = null;
try {
這裡還可以用inputStream
===========================================================================================================
@RequestMapping("/pointsImport.do")
public void StructureImport(HttpServletRequest request, HttpServletResponse response, Long driveId) {
String msg = null;
try {
response.setContentType("text/html;charset=utf-8");
MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
MultipartFile fileM = re.getFile("upFile");
CommonsMultipartFile cf = (CommonsMultipartFile) fileM;
InputStream inputStream = cf.getInputStream();
if (inputStream != null) {
Workbook workbook = null;
try {
workbook = Workbook.getWorkbook(inputStream);
//處理資料,如果需要userId的話,這裡可以追加
processData(workbook, response, driveId);
} catch (Exception e) {
logger.error("上傳檔案錯誤:" + e);
}
}
} catch (Exception e) {
logger.error("上傳檔案錯誤:" + e);
}
}
=============================================================
response.setContentType("text/html;charset=utf-8");
MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
CommonsMultipartFile file = (CommonsMultipartFile) re.getFile("upFile");
DiskFileItem dfi = (DiskFileItem) file.getFileItem();
String path = dfi.getStoreLocation().getPath().toString();
File toFile = new File(path);
if (toFile != null) {
//file.transferTo(toFile);
Workbook workbook = null;
try {
// excel檔案上傳
workbook = Workbook.getWorkbook(toFile);
//處理資料,如果需要userid的話,這裡可以追加
processData(workbook, response);
} catch (Exception e) {
msg = "上傳檔案錯誤!";
}
}
} catch (Exception e) {
msg = "上傳檔案錯誤!";
}
// return null;
}
private String processData(Workbook workbook, final HttpServletResponse response) {
String msg = null;
try { // 獲取第一頁
Sheet sheet = workbook.getSheet(0);
// 獲取行數
int rows = sheet.getRows();
if (rows > 1) {
// 獲取有多少列
int columns = sheet.getColumns();
int titleLength = STORE_HOUSE_IMPORT_TEMP_FILE_TITLE.length;
// 比較title數量與sheet實際列數,切掉多餘列
if (columns > titleLength)
columns = titleLength;
List<List<String>> resultList = new ArrayList<List<String>>();
List<List<String>> successResultList = new ArrayList<List<String>>();
//儲存excel中所有行的資料,用來辨別找不到父親的記錄
List<String[]> allDatas = getAllExcelData(rows, sheet);
//檢驗excel中是否存在重複
List<List<String>> checkResultList = new ArrayList<List<String>>();
//=========================================================
//取出資料表中的所有記錄,放入記憶體
Structure a = new Structure();
List<Structure> list = structureService.selectEntitys(a);
//=========================================================
boolean checkAllSuccess = true;
// 從第1行開始遍歷,i=0時候是標題行
for (int i = 1; i < rows; i++) {
// data儲存每一行的所有資料(所有列)
String[] datas = new String[titleLength + 2];
// 如果名稱(第一列)為空則不校驗此行資料
if (StringUtils.isBlank(sheet.getCell(0, i).getContents()) && StringUtils.isBlank(sheet.getCell(2, i).getContents())) {
continue;
}
for (int j = 0; j < columns; j++) {
Cell cell = sheet.getCell(j, i);
if (StringUtils.isNotBlank(cell.getContents())) {
datas[j] = cell.getContents().trim();
} else {
datas[j] = "";
}
}
String[] datasClon = datas.clone();
if (columns == titleLength) {
//校驗資料
String result = checkData(datas, datasClon, list);
//檢驗excel中是否有重複資料
result += isExistInExcel(checkResultList, datasClon);
checkResultList.add(Arrays.asList(datasClon));
//檢測有沒有找不到父親的記錄
result += findFather(datasClon, allDatas);
int leng = titleLength + 2;
if (StringUtils.isNotBlank(result)) {
datas[leng - 2] = STORE_HOUSE_FAIL;
datas[leng - 1] = result;
checkAllSuccess = false;
} else {
datas[leng - 2] = STORE_HOUSE_SUCCESS;
successResultList.add(Arrays.asList(datasClon));
}
}
resultList.add(Arrays.asList(datas));
}
// 只有所有的資料都校驗成功後,再進行批量儲存資料
if (checkAllSuccess) {
cleanData(successResultList);
}
// 將結果資料匯出
if (resultList.size() > 0) {
String[] titles = new String[columns + 2];
for (int i = 0; i < columns; i++) {
titles[i] = null;
}
int leng = titleLength + 2;
titles[leng - 2] = "處理結果";
titles[leng - 1] = "原因";
//如果出錯的話,返回一個excel。
commonExportExcel(IMPORT_TEMP_RESULT_NAME, titles, resultList, workbook, response);
} else {
msg = "處理成功!";
}
} else {
msg = "上傳檔案沒有內容資訊!";
}
} catch (Exception e) {
msg = "讀取excel異常!";
} finally {
if (workbook != null) {
workbook.close();
}
}
return msg;
}
private String checkData(String[] datas, String[] datasClon, List<Structure> list) {
String error = "";
// //檢驗資料是否重複
error += isExistInDBBySelectAll(datasClon, list);
//
// // 校驗不能為空的欄位:名稱 編號
int[] checkIsBlankId = {2};
error += checkDataIsBlank(datasClon, checkIsBlankId, STORE_HOUSE_IMPORT_TEMP_FILE_TITLE);
//
// // 校驗期數字段為正整數,長度暫定為15,
// // 2是地區編號 4是郵編 7是電話 8是oldId
// int[] checkBatchNo = {4, 7};
// for (int i = 0; i < checkBatchNo.length; i++) {
// if (!StringUtils.isBlank(datas[i]))
// error += checkNumber(datasClon, checkBatchNo[0], STORE_HOUSE_IMPORT_TEMP_FILE_TITLE, "+", 15);
// }
return error;
}
/**
* 校驗不能為空的欄位
*
* @param datas 需要校驗的資料
* @param titleId 需要校驗的欄位在資料陣列中的位置
* @param titleNames 需要校驗的資料的所有欄位的中文名稱
* @return
*/
private String checkDataIsBlank(String[] datas, int[] titleId, String[] titleNames) {
String error = "";
if (titleId != null && datas != null && titleNames != null) {
for (int i = 0; i < titleId.length; i++) {
int checkId = titleId[i];
String checkValue = datas[checkId];
if (StringUtils.isBlank(checkValue)) {
error += titleNames[checkId] + "為空,";
}
}
}
return error;
}
/**
* @param datas 需要校驗的資料
* @param titleId 需要校驗的欄位在資料陣列中的位置
* @param titleNames 需要校驗的資料的所有欄位的中文名稱
* @param type "0+":非負整數 "+":正整數 "-0":非正整數 "-":負整數 "":整數
* @param MaxLength 數字的最大位數
* @return
*/
private String checkNumber(String[] datas, int titleId, String[] titleNames, String type, int MaxLength) {
String error = "";
String eL = "";
String value = "";
if (type.equals("0+")) {
eL = "^\\d+$";// 非負整數
value = "非負整數";
} else if (type.equals("+")) {
eL = "^\\d*[1-9]\\d*$";// 正整數
value = "正整數";
} else if (type.equals("-0")) {
eL = "^((-\\d+)|(0+))$";// 非正整數
value = "非正整數";
} else if (type.equals("-")) {
eL = "^-\\d*[1-9]\\d*$";// 負整數
value = "負整數";
} else {
eL = "^-?\\d+$";// 整數
value = "整數";
}
if (datas != null && titleNames != null) {
String checkValue = datas[titleId];
java.util.regex.Pattern p = java.util.regex.Pattern.compile(eL);
Matcher m = p.matcher(checkValue);
boolean b = m.matches();
if (!b) {
error += titleNames[titleId] + "不是" + value;
} else {
int length = checkValue.length();
if (length > 2 && "-".equals(checkValue.substring(0, 1))) {
length = length - 1;
}
if (length > MaxLength) {
error += titleNames[titleId] + "大於" + MaxLength + "位的" + value;
}
}
}
return error;
}
/**
* 匯出excel檔案
*
* @param name 檔名
* @param titles 標題
* @param dataList 內容資料
* @param response
*/
public void commonExportExcel(String name, String[] titles, List<List<String>> dataList, Workbook workbook, HttpServletResponse response) {
try {
response.setCharacterEncoding("utf-8");
response.setContentType("aplication/msexcel;charset=utf-8"); // 設定檔案型別
response.setHeader("Content-disposition", "attachment; filename=" + name + ".xls");
WritableWorkbook book = null;
WritableSheet sheet = null;
WorkbookSettings settings = new WorkbookSettings();
settings.setWriteAccess(null);
if (workbook != null) {
book = Workbook.createWorkbook(response.getOutputStream(), workbook, settings); // 建立檔案
sheet = book.getSheet(0);
} else {
book = Workbook.createWorkbook(response.getOutputStream());
sheet = book.createSheet("sheet", 0);
}
if (titles != null) {
Cell cell = sheet.getCell(0, 0);
for (int i = 0; i < titles.length; i++) {
String title = titles[i];
if (StringUtils.isNotBlank(title)) {
Label label = new Label(i, 0, titles[i]);
label.setCellFormat(cell.getCellFormat());
sheet.addCell(label);
}
}
}
for (int i = 0; i < dataList.size(); i++) {
List<String> list = dataList.get(i);
for (int j = 0; j < list.size(); j++) {
Label label = new Label(j, i + 1, list.get(j));
sheet.addCell(label);
}
}
book.write();
book.close();
} catch (Exception e) {
}
}
/**
* 判斷excel中是否有重複資料
*
* @param datas
* @param current
* @return
*/
private String isExistInExcel(List<List<String>> datas, String[] current) {
String error = "";
for (int i = 0; i < datas.size(); i++) {
Boolean check = true;
for (int j = 0; j < datas.get(i).size() - 2; j++) {
if (!current[j].equals(datas.get(i).get(j))) {
check = false;
break;
}
}
if (check) {
error += "與excel第" + (i + 1) + "行重複;";
}
}
return error;
}
/**
* 判斷此記錄資料庫中是否已經存在,目前是根據裝置所屬專案,裝置名稱,兩個來確定一條記錄
* <p/>
* 這種方式是先將資料表中所有資料都取出來放入記憶體中,然後每一條資料都到這個list中進行匹配,這樣
* 只訪問一次資料庫,其他全在記憶體中操作,速度會非常快,但有可能會消耗大量記憶體,目前沒有觀察到記憶體方面都壓力
*
* @param datas
* @return
*/
private String isExistInDBBySelectAll(String[] datas, List<Structure> list) {
String error = "";
Long projectId = new Long(-1);
//
if (StringUtils.isNotBlank(datas[0])) {
projectId = selectProjectName(datas[0]).getId();
}
//迴圈從記憶體中取出結果
for (int i = 0; i < list.size(); i++) {
Structure structure = new Structure();
structure = list.get(i);
if ( structure.getProjectId()==projectId
&& datas[2].equals(structure.getName())) {
error += "此條記錄資料庫已存在;";
break;
}
}
return error;
}
/**
* 根據project名稱名稱取id
*
* @param
* @return
*/
private Project selectProjectName(String projectName) {
Project project = new Project();
project.setName(projectName);
return projectService.selectEntity(project);
}
/**
* 根據parentName取ID
*
*/
private Structure selectStructureParentId(String ParentName) {
Structure structure = new Structure();
structure.setName(ParentName);
return structureService.selectEntity(structure);
}
/**
* 儲存資料
*
* 這裡的儲存資料比較特殊,必須按層級來儲存,先儲存祖先,再儲存第二輩祖先
* 保證有祖先的都能在資料庫裡面找到id號,而且能走到這一步的資料,都是肯定能找到祖先的
*
* @param dataList 入庫資料
*/
private void saveData(List<List<String>> dataList) {
List<Structure> structures = new ArrayList<Structure>();
for (List<String> data : dataList) {
Structure structure = new Structure();
Long projectId = null;
Long structureId = null;
//專案id,專案名稱不為空時候,用它去取對應的id
if (StringUtils.isNotBlank(data.get(0)))
projectId = selectProjectName(data.get(0)).getId();
//parentId
if (StringUtils.isNotBlank(data.get(1)))
structureId = selectStructureParentId(data.get(1)).getId();
structure.setProjectId(projectId);
structure.setParentId(structureId);
structure.setName(data.get(2));
structure.setCode(data.get(3));
structures.add(structure);
}
structureService.insertBatch(structures);
}
/**
* 整理資料,把資料分層
*/
private List<List<String>> cleanData(List<List<String>> dataList){
Map<String,Object> a = new HashMap<String, Object>();
//先把父親為空的放進去
a = findRoot(dataList);
List<List<String>> paixu = (List<List<String>>) a.get("root");
dataList = (List<List<String>>) a.get("dataList");
a.clear();
saveData(paixu);
//遞迴,一級級走下去
while (dataList.size()!=0){
//再把第二級放進去
a = findNextRoot(dataList,paixu);
List<List<String>> paixuN = (List<List<String>>) a.get("root");
dataList = (List<List<String>>) a.get("dataList");
a.clear();
saveData(paixuN);
paixu=paixuN;
}
return null;
}
/**
* 尋找第一層的祖先
*/
private Map<String,Object> findRoot(List<List<String>> dataList){
List<List<String>> root = new ArrayList<List<String>>();
Map<String,Object> a = new HashMap<String, Object>();
//祖先加入root
for (List<String> data : dataList) {
if (!StringUtils.isNotBlank(data.get(1))){
root.add(data);
}
}
//祖先加完後,從總資料中移除
for(List<String> data : root){
dataList.remove(data);
}
a.put("root",root);
a.put("dataList",dataList);
return a;
}
/**
* 尋找第二級祖先,
*/
private Map<String,Object> findNextRoot(List<List<String>> dataList,List<List<String>> paixu){
List<List<String>> root = new ArrayList<List<String>>();
Map<String,Object> a = new HashMap<String, Object>();
for (List<String> data : dataList) {
for (List<String> dataCompare : paixu){
if (data.get(1).equals(dataCompare.get(2))){
root.add(data);
break;
}
}
}
//祖先加完後,從總資料中移除
for(List<String> data : root){
dataList.remove(data);
}
a.put("root",root);
a.put("dataList"