项目介绍:标注分析系统
主要功能:对上传的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,不管他们是不是老恶心棱(嘿嘿)