java程式碼實現excel檔案資料匯入
因業務需求要實現資料的批量匯入,給了指定的excel模板上傳檔案,用java程式碼實現匯入excel檔案。
重新複習下。
下面是原始碼,僅供參考。
controller層程式碼,建立臨時目錄後,使用DiskFileItemFactory類來實現檔案上傳,List parseRequest(HttpServletRequest request)方法來解析request物件,並把表單中的每一個輸入項包裝成一個fileItem 物件,並返回一個儲存了所有FileItem的list集合。
@RequestMapping("/doImport")
@ResponseBody
@Transactional(rollbackFor = Exception.class, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public Map<String, Object> doImport(HttpServletRequest request, HttpSession session) throws Exception{
Map<String, Object> map = new HashMap<>();
String path = System.getProperty("web.root");
//建立臨時檔案目錄
String tempPath = path + File.separator + "attach" + File.separator;
//建立File類例項
File tempFile = new File(tempPath + "temp");
int userId = PubFunc.parseInt(session.getAttribute("user_id"));
try {
//建立FileItem 物件的工廠
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//指定臨時檔案目錄
diskFileItemFactory.setRepository(tempFile);
//負責處理上傳的檔案資料,並將表單中每個輸入項封裝成一個FileItem 物件中
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//解析request物件,把表單中的每一個輸入項包裝成一個fileItem 物件
List<FileItem> lists = servletFileUpload.parseRequest(request);
int len = lists.size();
for (int n = 0; n < len; n++) {
FileItem item = lists.get(n);
if (!item.isFormField()) {
if (item.getName().length() > 0) {
InputStream inputStream = item.getInputStream();
unabledService.doImportExl(item.getName(), inputStream, userId);
map.put("code",0);
map.put("msg", "檔案上傳中,稍後自動跳轉" );
}
}
}
}catch (FileNotFoundException e) {
map.put("code",1);
map.put("msg", "檔案未找到或檔案格式錯誤!");
} catch (IOException e) {
map.put("code",2);
map.put("msg", "檔案內容讀取失敗");
} catch (IllegalAccessException e) {
map.put("code",3);
map.put("msg", "使用者資訊寫入失敗");
} catch (NoSuchFieldException e) {
map.put("code",4);
map.put("msg", "找不到該屬性值");
} catch (NullPointerException e) {
map.put("code",5);
map.put("msg", "檔案未上傳");
} catch (InvalidFormatException e) {
map.put("code",6);
map.put("msg", "檔案格式錯誤");
} catch (Exception e) {
e.printStackTrace();
map.put("code",7);
map.put("msg", e.getMessage());
}
return map;
}
service層程式碼,裡面有兩個方法需要注意,一個是readExcel(fileName,inputStream)方法,通過流來讀取excel資料,並對excel裡面的資料做重複校驗。另一個是insert_batch(unableds,userId)方法,用來將資料批量插入,
/**
* 執行匯入資料操作
*
* @param fileName 檔名
* @param inputStream 資料流
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
@Override
public int doImportExl(String fileName, InputStream inputStream, int userId) throws Exception {
//讀取資料
List<Map<String, Object>> list = readExcel(fileName, inputStream);
if (list == null || list.isEmpty()) {
throw new Exception("匯入資料存在相同手機號");
}
//插入資料條數記錄
int i = 0;
//迭代器
Iterator<Map<String, Object>> iterator = list.iterator();
Map<String, Object> fieldMap = getFieldsMap(122);
List<Unabled> unableds = new ArrayList<>();
while (iterator.hasNext()) {
Map<String, Object> map = iterator.next();
Unabled unabled = new Unabled();
//反射獲取所有屬性
Class<? extends Unabled> clazz = unabled.getClass();
for (String key : fieldMap.keySet()) {
String value = PubFunc.toString(map.get(PubFunc.toString(fieldMap.get(key))));
if (!PubFunc.isNullStr(value)) {
Field field = clazz.getDeclaredField(key);
//設定私有屬性允許更改
field.setAccessible(true);
field.set(unabled, value);
}
}
unableds.add(unabled);
}
int res = insert_batch(unableds, userId);
return res;
}
readExcel(fileName,inputStream)方法程式碼
private List<Map<String, Object>> readExcel(String fileName, InputStream inputStream) throws IOException, InvalidFormatException {
//校驗檔案
boolean ret = isXls(fileName);
Workbook wb = null;
//根據字尾新建對應的工作簿
if (ret) {
wb = new HSSFWorkbook(inputStream);
} else {
wb = WorkbookFactory.create(inputStream);
}
//獲取第一個sheet
Sheet sheet = wb.getSheetAt(0);
//標題行
Row titleRow = sheet.getRow(0);
//獲取最大行數及列數
int max_row = sheet.getLastRowNum();
int max_cell = titleRow.getLastCellNum() - 1;
//存放資料
List<Map<String, Object>> list = new ArrayList<>();
//存放手機號做重複校驗
for (int i = 1; i <= max_row; i++) {
Map<String, Object> map = new HashMap<>();
Row row = sheet.getRow(i);
if (row == null) {
break;
}
for (int j = 0; j < max_cell; j++) {
String cellTitle = titleRow.getCell(j).getStringCellValue();
Cell cell = row.getCell(j);
String cellValue;
//對空值進行處理
if (cell == null) {
cellValue = "";
} else {
cell.setCellType(Cell.CELL_TYPE_STRING);
cellValue = cell.getStringCellValue();
}
map.put(cellTitle, cellValue);
}
list.add(map);
}
wb.close();
return list;
}
insert_batch(unableds,userId)方法程式碼,newCachedThreadPool建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
public int insert_batch(List<Unabled> unableds, int userId) throws Exception {
//建立一個執行緒安全的ConcurrentHashMap集合
ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
//建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒
ExecutorService threadPoolExecutor = Executors.newCachedThreadPool();
// 主執行緒等待子執行緒執行完成再執行
final CountDownLatch countDownLatch = new CountDownLatch(unableds.size() / 500 == 0 ? 1 : unableds.size() / 500);
for (int i = 0; i < unableds.size(); i += 500) {
if (i > unableds.size()) {
break;
}
int j = i + 500;
List<Unabled> list = j > unableds.size() ? unableds.subList(i, unableds.size()) : unableds.subList(i, j);
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis());
for (int k = 0; k < list.size(); k++) {
Unabled unabled = list.get(k);
int res = 0;
try {
//插入資料
res = insert(unabled, userId);
System.out.println("使用者新增/更新成功:" + unabled.getF_1402() + ":" + unabled.getF_1403());
} catch (Exception e) {
System.out.println("使用者新增失敗:" + unabled.getF_1402() + ":" + unabled.getF_1403());
}
if (res == 0) {
map.put(unabled.getF_1402(), unabled);
}
}
//如果計數到達零,則釋放所有等待的執行緒
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis());
}
});
}
countDownLatch.await();
threadPoolExecutor.shutdown();
for (String key : map.keySet()) {
log.info("匯入失敗:" + key);
System.out.println("匯入失敗:" + key);
throw new Exception("匯入失敗: " + key+",該使用者手機號可能被佔用");
}
return 0;
}
相關文章
- Java POI匯入Excel檔案JavaExcel
- 匯入excel檔案Excel
- JS之實現Excel資料匯入JSExcel
- TP5.1excel匯入資料庫的程式碼?php excel如何匯入資料庫?Excel資料庫PHP
- django實現將後臺資料excel檔案形式匯出DjangoExcel
- php讀取excel檔案資料的匯入和匯出PHPExcel
- java匯出Excel檔案JavaExcel
- Net.Core匯入EXCel檔案裡的資料Excel
- Java 匯入資料到Excel並提供檔案下載介面JavaExcel
- office for Mac Excel匯入csv檔案亂碼MacExcel
- java 從EXCEL匯入到資料庫JavaExcel資料庫
- 利用xlrd模組在Django專案中實現Excel檔案匯入DjangoExcel
- 三行程式碼嵌入 java 實現複雜 Excel 資料入庫行程JavaExcel
- java快速實現匯出生成csv檔案(含註釋程式碼)Java
- EasyExcel完成excel檔案的匯入匯出Excel
- poi 匯出Excel java程式碼ExcelJava
- 如何使用JavaScript匯入和匯出Excel檔案JavaScriptExcel
- Java之POI操作,封裝ExcelUtil實現Excel匯入匯出Java封裝Excel
- Vue + Element 實現匯入匯出ExcelVueExcel
- Excel 表匯入資料Excel
- Oracle 資料匯入ExcelOracleExcel
- 匯入sql檔案出現亂碼SQL
- ASP.NET MVC 匯入Excel檔案ASP.NETMVCExcel
- 程式設計方式實現MySQL批量匯入sql檔案程式設計MySql
- phpExcel實現Excel資料的匯入匯出(全步驟詳細解析)PHPExcel
- odoo 給列表檢視新增按鈕實現資料檔案匯入Odoo
- EasyPoi, Excel資料的匯入匯出Excel
- 前端實現Excel匯入和匯出功能前端Excel
- excel 匯入sqlyog資料庫ExcelSQL資料庫
- 匯入excel 資料時間Excel
- NCF 如何匯入Excel資料Excel
- Laravel5.6中使用Laravel/Excel實現Excel檔案匯出功能LaravelExcel
- Excel匯入匯出神器(Java)ExcelJava
- MATLAB匯入txt和excel檔案技巧彙總:批量匯入、單個匯入MatlabExcel
- DcatAdmin 簡單實現匯入ExcelExcel
- EasyPoi框架實現Excel表格匯入框架Excel
- 小程式批次匯入excel資料,雲開發資料庫匯出cvs亂碼解決方案Excel資料庫
- java 匯出 excel 最佳實踐,java 大檔案 excel 避免OOM(記憶體溢位) excel 工具框架JavaExcelOOM記憶體溢位框架