項目介紹:標註分析系統
主要功能:對上傳的EXCEL文件進行解析,進行一些CRUD操作。
主要難點:
1.excel文件上傳
使用sheetjs插件讀取excel文件
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
var file = $("#dataList").get(0).files[0];
var reader = new FileReader();
reader.onload = function(e){
var data = e.target.result;
var workbook = XLSX.read(data, {
type : 'binary'
});
var sheet = workbook.Sheets[workbook.SheetNames[0]];
var rowList = XLSX.utils.sheet_to_json(sheet);
//這樣excel的第一行就變成了JSON的key,底下的每行就是value
//但如何給這些key取別名還不會,這樣excel的第一行就可以使用複雜文本了
}
2.導出txt文件
//發送Response
private void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = new String(fileName.getBytes(),"ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
//導出txt
public void exportTxt() throws IOException {
String missionCode = getParam("missionCode");
String txtName = missionCode + ".txt";
//獲取需要導出的list
try {
this.setResponseHeader(getRes(), txtName);
OutputStream out = getRes().getOutputStream();
for (int i = 0; i < list.size(); i++) {
String str1 = list.get(i) + "\t\t\t";
out.write(str1.getBytes());
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//導出成excel文件也類似
public void exportExcel(){
String excelName = "excel.xlsx";
String sheetName = "sheet0";
String[] title = {"批次號", "問法", "推薦問題", "狀態"};
//把要導出的數據寫成二維數組的形式,使用ExcelUtil工具類方便導出
XSSFWorkbook workbook = ExcelUtil.getWorkbook(sheetName, title, content);
XSSFSheet sheet = workbook.getSheetAt(0);
//設置excel樣式
sheet.setColumnWidth(0, 25*255);
sheet.setColumnWidth(1, 55*255);
sheet.setColumnWidth(2, 45*255);
sheet.setColumnWidth(3, 15*255);
OutputStream outputStream = null;
try {
this.setResponseHeader(getRes(), excelName);
outputStream = getRes().getOutputStream();
workbook.write(outputStream);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//ExcelUtil工具類,把二維數組轉化成XSSFWorkbook
public class ExcelUtil {
public static XSSFWorkbook getWorkbook(String sheetName, String[] title, String[][] content){
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(sheetName);
XSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
XSSFRow titleRow = sheet.createRow(0);
for (int i = 0; i < title.length; i++) {
XSSFCell cell = titleRow.createCell(i);
cell.setCellValue(title[i]);
cell.setCellStyle(style);
}
for (int i = 0; i < content.length; i++) {
XSSFRow row = sheet.createRow(i+1);
for (int j = 0; j < content[i].length; j++) {
XSSFCell cell = row.createCell(j);
cell.setCellValue(content[i][j]);
cell.setCellStyle(style);
}
}
return workbook;
}
}
項目缺點:
1.最大的敗筆是數據庫中設計了存放當前任務的總條數、已打標條數,每次打標、刪除、導入都會改變一次這些狀態,遇到一些異常情況非常容易出錯。後期需求有改變的時候往往要直接操作線上數據庫,也容易使這些狀態數據對不上實際。最開始設計成這樣主要是想做進度條的時候可以直接做成marked_size/total_size,每次操作也可以不用每次都select count(*),而是標註的時候在前端改數字在後臺給marked_size加1,實際上導致了後期維護起來非常麻煩,出異常的時候幾乎是必對不上數字。以後這種頻繁變化的狀態屬性一定不要存起來,而是每次用到去查詢一下。
2.項目使用了大量的ajax套ajax,其實可以全部在一個ajax裏判斷,這麼寫就像if裏套if一樣顯得臃腫。根本原因還是export層很少使用Map<String, Object>這種通用的返回類型,而是用的都是String, List這種只能返回一類結果的類型,導致我需要使用多個ajax來獲取數據。
項目經驗:
作爲從0開始的第一個Java項目,我逐漸理解了MVC設計模式。在開發系統的時候,不能完全按照產品經理的要求面向產品經理編程,而是要站在用戶的角度,不斷思考怎樣使用這個系統的人更便利,在這個基礎上可以增加用戶需要的功能,甚至刪除用戶不需要的功能,因爲產品經理往往也不能一開始就構思好全部細節。最後,我一定要感謝工作中幫助過我的領導和小夥伴,沒有他們的幫忙我應該永遠也做不成這個簡單到批爆的CRUD,不管他們是不是老噁心棱(嘿嘿)