传智健康第五天
项目需求
体检预约,实现预约的文件的上传下载,预约人数的设置
1、实现预约设置模板文件的下载与上传
POI与JXL都是进行文件上传下载 POI支持所有文件的上下,JXL只支持excel
POI有4个对象,分别为workbook(工作簿)、sheet(工作表)、row(行)、cell(单元格)
- 下载模板文件,将设置好的模板文件存放在consumer的webapp下,通过页面域方法下载模板文件
- 点击文件上传按钮,upload组件自动进行文件上传操作,后端进行文件的读取代码,再进行业务处理,注意逻辑点有,需要判断模板中的日期是否存在数据,如果存在数据就是updata操作,入过不存在数据就是insert操作
2、页面初始化查询所有的当月的预约数据
- 获取当前月的信息,将当前时间传递给后端,后端根据当前时间获取所有的当前月的预约数据,将数据返回至前端
- 前端获取当前月的数据,将数据展示
3、设置预约数据
- 点击设置,填写需要预约设置的预约认输,确认后将设置的日期,可预约人数传递给后端
- 后端接收数据进行业务处理,查询当前时间是否有数据,如果有数据就进行修改操作,如果没有数据就进行添加操作
业务代码
1 <script> 2 new Vue({ 3 el: '#app', 4 data: { 5 today: new Date(),//当前日期 6 currentDay: 1, 7 currentMonth: 1, 8 LocalMonth: 1, 9 currentYear: 1970, 10 currentWeek: 1, 11 days: [], 12 leftobj: []//用于装载页面显示的月份已经进行预约设置的数据 13 }, 14 created: function () {//在vue初始化时调用 15 this.initData(null); 16 }, 17 methods: { 18 //预约设置 19 handleOrderSet(day) { 20 this.$prompt('请输入可预约人数', '预约设置', { 21 confirmButtonText: '确定', 22 cancelButtonText: '取消', 23 inputPattern: /^[0-9]*[1-9][0-9]*$/, 24 inputErrorMessage: '只能输入正整数' 25 }).then(({value}) => { 26 //发送ajax请求,将输入的数据提交到Controller 27 axios.post("/ordersetting/editOrderSettingByDate.do",{ 28 number:value, 29 orderDate:this.formatDate(day.getFullYear(),day.getMonth()+1,day.getDate()) //日期 30 }).then((res) => { 31 if(res.data.flag){ 32 this.initData(this.formatDate(day.getFullYear(), day.getMonth() + 1, 1)); 33 this.$message({ 34 type:'success', 35 message:res.data.message 36 }); 37 }else{ 38 this.$message.error(res.data.message); 39 } 40 }); 41 }).catch(() => { 42 this.$message({ 43 type: 'info', 44 message: '取消输入' 45 }); 46 }); 47 }, 48 //上传之前进行文件格式校验 49 beforeUpload(file) { 50 const isXLS = file.type === 'application/vnd.ms-excel'; 51 if (isXLS) { 52 return true; 53 } 54 const isXLSX = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 55 if (isXLSX) { 56 return true; 57 } 58 this.$message.error('上传文件只能是xls或者xlsx格式!'); 59 return false; 60 }, 61 //下载模板文件 62 downloadTemplate() { 63 //下载模板 这个地方的连接地址有 64 // /template/ordersetting_template.xlsx 正确 /表示根目录下 65 // ./template/ordersetting_template.xlsx 错误 ./ 表示是当前页面的位置 66 window.location.href = "../template/ordersetting_template.xlsx"; 67 }, 68 //上传成功提示 69 handleSuccess(response, file) { 70 this.$message({ 71 type: response.flag ? 'success' : 'error', 72 message: response.message 73 }); 74 console.log(response, file, fileList); 75 }, 76 //初始化当前页要展示的日期 77 initData: function (cur) { 78 var date; 79 var index = 0; //控制显示预定的天数 80 if (cur) { 81 date = new Date(cur); 82 } else { 83 var now = new Date(); 84 var d = new Date(this.formatDate(now.getFullYear(), now.getMonth(), 1)); 85 d.setDate(35); 86 date = new Date(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)); 87 } 88 this.currentDay = date.getDate(); 89 this.currentYear = date.getFullYear(); 90 this.currentMonth = date.getMonth() + 1; 91 this.currentWeek = date.getDay(); // //本月第一天是周几(周日0 周六 6) 92 var today = new Date(); 93 this.LocalMonth = today.getMonth() + 1; 94 if (this.currentWeek == 0) { 95 this.currentWeek = 7; 96 } 97 var str = this.formatDate(this.currentYear, this.currentMonth, this.currentDay); 98 this.days.length = 0; 99 // 今天是周日,放在第一行第7个位置,前面6个 100 //初始化本周 101 for (var i = this.currentWeek - 1; i >= 0; i--) { 102 var d = new Date(str); 103 d.setDate(d.getDate() - i); 104 var dayobject = {}; 105 dayobject.day = d; 106 var now = new Date(); 107 if (d.getDate() === (now.getDate()) && d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear()) { 108 dayobject.index = index++;//从今天开始显示供预定的数量 109 } else if (index != 0 && index < 3) 110 dayobject.index = index++;//从今天开始3天内显示供预定的数量 111 this.days.push(dayobject);//将日期放入data 中的days数组 供页面渲染使用 112 } 113 //其他周 114 for (var i = 1; i <= 35 - this.currentWeek; i++) { 115 var d = new Date(str); 116 d.setDate(d.getDate() + i); 117 var dayobject = {};//dayobject {day:date,index:2} 118 dayobject.day = d; 119 var now = new Date(); 120 if (d.getDate() === (now.getDate()) && d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear()) { 121 dayobject.index = index++; 122 } else if (index != 0 && index < 3) 123 dayobject.index = index++; 124 this.days.push(dayobject); 125 } 126 127 /*this.leftobj = [ 128 { date: 1, number: 120, reservations: 1 }, 129 { date: 3, number: 120, reservations: 1 }, 130 { date: 4, number: 120, reservations: 119 }, 131 { date: 6, number: 120, reservations: 1 }, 132 { date: 8, number: 120, reservations: 1 } 133 ];*/ 134 135 //发送ajax请求,根据当前页面对应的月份查询数据库,封装成相应结果赋值给leftobj模型数据,用于页面展示 136 let newdate = this.currentMonth < 10 ? this.currentYear + "-0" + this.currentMonth : this.currentYear + "-" + this.currentMonth; 137 axios.post("/ordersetting/getOrderSettingByMonth.do?date=" + newdate).then((res) => { 138 if (res.data.flag) { 139 this.leftobj = res.data.data; 140 } else { 141 this.$message.error(res.data.message); 142 } 143 }); 144 }, 145 //切换到当前月份 146 goCurrentMonth: function (year, month) { 147 var d = new Date(); 148 this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)); 149 }, 150 //向前一个月 151 pickPre: function (year, month) { 152 // setDate(0); 上月最后一天 153 // setDate(-1); 上月倒数第二天 154 // setDate(dx) 参数dx为 上月最后一天的前后dx天 155 var d = new Date(this.formatDate(year, month, 1)); 156 d.setDate(0); 157 this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)); 158 }, 159 //向后一个月 160 pickNext: function (year, month) { 161 var d = new Date(this.formatDate(year, month, 1)); 162 d.setDate(35);////获取指定天之后的日期 163 this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)); 164 }, 165 // 返回 类似 2016-01-02 格式的字符串 166 formatDate: function (year, month, day) { 167 var y = year; 168 var m = month; 169 if (m < 10) m = "0" + m; 170 var d = day; 171 if (d < 10) d = "0" + d; 172 return y + "-" + m + "-" + d 173 } 174 } 175 }) 176 </script>
POI文件上传与文件创建代码
文件创建
1 - 内存中创建工作簿对象 2 - 工作簿设置表格名称 3 - 通过索引创建行 4 - 通过索引往单元格写入数据 5 - 创建输出流 6 - 往输出流写入数据 7 8 @Test 9 public void test03() throws IOException { 10 XSSFWorkbook xssfWorkbook = new XSSFWorkbook(); 11 FileOutputStream fileOutputStream = null; 12 try { 13 XSSFSheet sheet = xssfWorkbook.createSheet("娃哈哈"); 14 XSSFRow row1 = sheet.createRow(0); 15 row1.createCell(0).setCellValue("姓名"); 16 row1.createCell(1).setCellValue("成绩"); 17 row1.createCell(2).setCellValue("编号"); 18 XSSFRow row2 = sheet.createRow(1); 19 row2.createCell(0).setCellValue("张三"); 20 row2.createCell(1).setCellValue("100"); 21 row2.createCell(2).setCellValue("N001"); 22 XSSFRow row3 = sheet.createRow(2); 23 row3.createCell(0).setCellValue("李四"); 24 row3.createCell(1).setCellValue("99"); 25 row3.createCell(2).setCellValue("N002"); 26 String resourcePath = this.getClass().getResource("/").getPath(); 27 fileOutputStream = new FileOutputStream(resourcePath+"itcast.xlsx"); 28 xssfWorkbook.write(fileOutputStream); 29 } catch (Exception e) { 30 e.printStackTrace(); 31 } finally { 32 if (fileOutputStream != null) { 33 fileOutputStream.flush(); 34 fileOutputStream.close(); 35 } 36 xssfWorkbook.close(); 37 } 38 }
文件上传
1 import java.io.FileNotFoundException; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.List; 7 import org.apache.poi.hssf.usermodel.HSSFWorkbook; 8 import org.apache.poi.ss.usermodel.Cell; 9 import org.apache.poi.ss.usermodel.Row; 10 import org.apache.poi.ss.usermodel.Sheet; 11 import org.apache.poi.ss.usermodel.Workbook; 12 import org.apache.poi.xssf.usermodel.XSSFWorkbook; 13 import org.springframework.web.multipart.MultipartFile; 14 15 public class POIUtils { 16 private final static String xls = "xls"; 17 private final static String xlsx = "xlsx"; 18 private final static String DATE_FORMAT = "yyyy/MM/dd"; 19 /** 20 * 读入excel文件,解析后返回 21 * @param file 22 * @throws IOException 23 */ 24 public static List<String[]> readExcel(MultipartFile file) throws IOException { 25 //检查文件 26 checkFile(file); 27 //获得Workbook工作薄对象 28 Workbook workbook = getWorkBook(file); 29 //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回 30 List<String[]> list = new ArrayList<String[]>(); 31 if(workbook != null){ 32 for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){ 33 //获得当前sheet工作表 34 Sheet sheet = workbook.getSheetAt(sheetNum); 35 if(sheet == null){ 36 continue; 37 } 38 //获得当前sheet的开始行 39 int firstRowNum = sheet.getFirstRowNum(); 40 //获得当前sheet的结束行 41 int lastRowNum = sheet.getLastRowNum(); 42 //循环除了第一行的所有行 43 for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){ 44 //获得当前行 45 Row row = sheet.getRow(rowNum); 46 if(row == null){ 47 continue; 48 } 49 //获得当前行的开始列 50 int firstCellNum = row.getFirstCellNum(); 51 //获得当前行的列数 52 int lastCellNum = row.getPhysicalNumberOfCells(); 53 String[] cells = new String[row.getPhysicalNumberOfCells()]; 54 //循环当前行 55 for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){ 56 Cell cell = row.getCell(cellNum); 57 cells[cellNum] = getCellValue(cell); 58 } 59 list.add(cells); 60 } 61 } 62 workbook.close(); 63 } 64 return list; 65 } 66 67 //校验文件是否合法 68 public static void checkFile(MultipartFile file) throws IOException{ 69 //判断文件是否存在 70 if(null == file){ 71 throw new FileNotFoundException("文件不存在!"); 72 } 73 //获得文件名 74 String fileName = file.getOriginalFilename(); 75 //判断文件是否是excel文件 76 if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){ 77 throw new IOException(fileName + "不是excel文件"); 78 } 79 } 80 public static Workbook getWorkBook(MultipartFile file) { 81 //获得文件名 82 String fileName = file.getOriginalFilename(); 83 //创建Workbook工作薄对象,表示整个excel 84 Workbook workbook = null; 85 try { 86 //获取excel文件的io流 87 InputStream is = file.getInputStream(); 88 //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象 89 if(fileName.endsWith(xls)){ 90 //2003 91 workbook = new HSSFWorkbook(is); 92 }else if(fileName.endsWith(xlsx)){ 93 //2007 94 workbook = new XSSFWorkbook(is); 95 } 96 } catch (IOException e) { 97 e.printStackTrace(); 98 } 99 return workbook; 100 } 101 public static String getCellValue(Cell cell){ 102 String cellValue = ""; 103 if(cell == null){ 104 return cellValue; 105 } 106 //如果当前单元格内容为日期类型,需要特殊处理 107 String dataFormatString = cell.getCellStyle().getDataFormatString(); 108 if(dataFormatString.equals("m/d/yy")){ 109 cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue()); 110 return cellValue; 111 } 112 //把数字当成String来读,避免出现1读成1.0的情况 113 if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){ 114 cell.setCellType(Cell.CELL_TYPE_STRING); 115 } 116 //判断数据的类型 117 switch (cell.getCellType()){ 118 case Cell.CELL_TYPE_NUMERIC: //数字 119 cellValue = String.valueOf(cell.getNumericCellValue()); 120 break; 121 case Cell.CELL_TYPE_STRING: //字符串 122 cellValue = String.valueOf(cell.getStringCellValue()); 123 break; 124 case Cell.CELL_TYPE_BOOLEAN: //Boolean 125 cellValue = String.valueOf(cell.getBooleanCellValue()); 126 break; 127 case Cell.CELL_TYPE_FORMULA: //公式 128 cellValue = String.valueOf(cell.getCellFormula()); 129 break; 130 case Cell.CELL_TYPE_BLANK: //空值 131 cellValue = ""; 132 break; 133 case Cell.CELL_TYPE_ERROR: //故障 134 cellValue = "非法字符"; 135 break; 136 default: 137 cellValue = "未知类型"; 138 break; 139 } 140 return cellValue; 141 } 142 }