一、Apache POI:实现对Excel中数据的读和写
1.POI介绍
Apache POI是用Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。
maven坐标:
POI结构:
2.从Excel文件读取数据1:使用POI可以从一个已经存在的Excel文件中读取数据。
//使用POI读取Excel文件中的数据
@Test
public void test1() throws IOException {
//加载指定文件,创建一个Excel对象(工作簿)
XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("D:\\JavaEE_Demo\\score.xlsx")));
//读取Excel文件中第一个Sheet标签页
XSSFSheet sheet = excel.getSheetAt(0);
//遍历Sheet标签页,获得每一行数据
for (Row row : sheet) {
//遍历行,获得每个单元格对象
for (Cell cell : row) {
System.out.print(cell.getStringCellValue()+" ");
}
System.out.println();
}
//关闭资源
excel.close();
}
通过上面的入门案例可以看到,POI操作Excel表格封装了几个核心对象:
上面案例是通过遍历工作表获得行,遍历行获得单元格,最终获取单元格中的值。
2.从Excel文件读取数据2:使用POI可以从一个已经存在的Excel文件中读取数据。
还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象,代码如下:
//使用POI读取Excel文件中的数据
@Test
public void test2() throws Exception{
//加载指定文件,创建一个Excel对象(工作簿)
XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("D:\\JavaEE_Demo\\score.xlsx")));
//读取Excel文件中第一个Sheet标签页
XSSFSheet sheet = excel.getSheetAt(0);
//获得当前工作表中最后一个行号,需要注意:行号从0开始
int lastRowNum = sheet.getLastRowNum();
for(int i=0;i<=lastRowNum;i++){
XSSFRow row = sheet.getRow(i);//根据行号获取每一行
//获得当前行最后一个单元格索引
short lastCellNum = row.getLastCellNum();
for(int j=0;j<lastCellNum;j++){
XSSFCell cell = row.getCell(j);//根据单元格索引获得单元格对象
System.out.print(cell.getStringCellValue()+" ");
}
System.out.println();
}
//关闭资源
excel.close();
}
3.向Excel文件写入数据
使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘。
//使用POI向Excel文件写入数据,并且通过输出流将创建的Excel文件保存到本地磁盘
@Test
public void test3() throws Exception{
//在内存中创建一个Excel文件(工作簿)
XSSFWorkbook excel = new XSSFWorkbook();
//创建一个工作表对象
XSSFSheet sheet = excel.createSheet("oracle");
//在工作表中创建行对象
XSSFRow title = sheet.createRow(0);
//在行中创建单元格对象
title.createCell(0).setCellValue("姓名");
title.createCell(1).setCellValue("地址");
title.createCell(2).setCellValue("年龄");
XSSFRow dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("小明");
dataRow.createCell(1).setCellValue("北京");
dataRow.createCell(2).setCellValue("20");
//创建一个输出流,通过输出流将内存中的Excel文件写到磁盘
FileOutputStream out = new FileOutputStream(new File("D:\\JavaEE_Demo\\score.xlsx"));
excel.write(out);
out.flush();
excel.close();
}
二、批量导入预约设置信息
1.前端页面ordersetting.html点击模板下载执行流程
2.前端页面ordersetting.html点击上传文件执行流程
3.完善OrderSettingController
后台OrderSettingController处理流程
1.接收一个文件类型的变量MultipartFile excelFile
2.List<String[]> list = POIUtils.readExcel(excelFile);//使用POI解析表格数据得到一个List集合,集合里面存储的是一个一个的数组
3.通过遍历List集合将String[]数组转换成OrderSetting,也就是说List<String[]>---->List<OrderSetting> [[2020/6/17,400],[2020/6/18,400]]--->[OrderSetting{orderDate=2020/6/17,number=400},OrderSetting{orderDate=2020/6/18,number=400}]
4.通过dubbo远程调用服务实现数据批量导入到数据库
package com.oracle.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.oracle.constant.MessageConstant;
import com.oracle.entity.Result;
import com.oracle.pojo.OrderSetting;
import com.oracle.service.OrderSettingService;
import com.oracle.utils.POIUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/ordersetting")
public class OrderSettingController {
@Reference
OrderSettingService orderSettingService;
@RequestMapping("/upload")
public Result uploadFromOrderSetting(MultipartFile excelFile){
try {
List<String[]> list = POIUtils.readExcel(excelFile);//使用POI解析表格数据
List<OrderSetting> data = new ArrayList<>();
for (String[] strings : list) {
String orderDate = strings[0];
String number = strings[1];
OrderSetting orderSetting = new OrderSetting(new Date(orderDate),Integer.parseInt(number));
data.add(orderSetting);
}
//通过dubbo远程调用服务实现数据批量导入到数据库
orderSettingService.addFileData(data);
return new Result(true, MessageConstant.IMPORT_ORDERSETTING_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.IMPORT_ORDERSETTING_FAIL);
}
}
}
4.完善OrderSettingService接口
package com.oracle.service;
import com.oracle.pojo.OrderSetting;
import java.util.List;
import java.util.Map;
public interface OrderSettingService {
//数据批量导入到数据库
void addFileData(List<OrderSetting> list);
}
5.完善OrderSettingServiceImpl实现类
package com.oracle.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.oracle.dao.OrderSettingDao;
import com.oracle.pojo.OrderSetting;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
@Service(interfaceClass = OrderSettingService.class)
public class OrderSettingServiceImpl implements OrderSettingService{
@Autowired
OrderSettingDao orderSettingDao;
@Override
public void addFileData(List<OrderSetting> list) {
if(list!=null && list.size()>0){
for (OrderSetting orderSetting : list) {
//判断当前日期是否已经进行了预约设置
long countByOrderDate = orderSettingDao.findCountByOrderDate(orderSetting.getOrderDate());
if(countByOrderDate > 0){
//已经进行了预约设置,执行更新操作
orderSettingDao.editNumberByOrderDate(orderSetting);
}else{
//没有进行预约设置,执行插入操作
orderSettingDao.addFileData(orderSetting);
}
}
}
}
}
6.完善OrderSettingDao接口
package com.oracle.dao;
import com.oracle.pojo.OrderSetting;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Repository
public interface OrderSettingDao {
//判断当前日期是否已经进行了预约设置
long findCountByOrderDate(Date orderDate);
//已经进行了预约设置,执行更新操作
void editNumberByOrderDate(OrderSetting orderSetting);
//没有进行预约设置,执行插入操作
void addFileData(OrderSetting orderSetting);
}
6.完善OrderSettingDao接口
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oracle.dao.OrderSettingDao">
<!--判断当前日期是否已经进行了预约设置-->
<select id="findCountByOrderDate" parameterType="date" resultType="long">
select count(id) from t_ordersetting where orderDate = #{orderDate}
</select>
<!--已经进行了预约设置,执行更新操作-->
<update id="editNumberByOrderDate" parameterType="com.oracle.pojo.OrderSetting">
update t_ordersetting
set number = #{number}
where orderDate = #{orderDate}
</update>
<!--没有进行预约设置,执行插入操作-->
<insert id="addFileData" parameterType="com.oracle.pojo.OrderSetting">
insert into t_ordersetting
(orderDate,number,reservations)
values
(#{orderDate},#{number},#{reservations})
</insert>
</mapper>
7.启动测试
点击上传文件。
将实现定义好的数据导入进去
然后查看对应数据表(t_ordersetting):
三、日历展示预约设置信息
前面已经完成了预约设置功能,现在就需要通过日历的方式展示出来每天设置的预约人数。
在页面中已经完成了日历的动态展示,我们只需要查询当前月份的预约设置信息并展示到日历中即可,同时在日历中还需要展示已经预约的人数,效果如下:
1.完善页面
1.1 使用静态数据调试
为了能够快速看到效果,我们可以先使用静态数据模拟,然后再改为发送ajax请求查询数据库。
实现步骤:
(1)预约设置数据对应的模型数据为leftobj,在initData方法最后为leftobj模型数据赋值:
其中date表示日期,number表示可预约人数,reservations表示已预约人数。
(2)使用VUE的v-for标签遍历上面的leftobj模型数据,展示到日历上:
查看页面效果:
1.2 发送ajax获取动态数据
3.完善OrderSettingController
后台OrderSettingController处理流程
1.接收一个文件类型的变量String date //date格式为:yyyy-MM
2.在OrderSettingServiceImpl中调用DAO,根据日期范围查询预约设置数据 {end=2020-06-31, begin=2020-06-1}
3.定义一个map集合,将从数据库中查到的信息添加到map集合
[{date=16, number=200, reservations=0}, {date=17, number=400, reservations=0}, {date=18, number=401, reservations=0}, {date=19, number=402, reservations=0}, {date=20, number=403, reservations=8}, {date=21, number=404, reservations=0}, {date=22, number=405, reservations=12}, {date=23, number=406, reservations=3}, {date=24, number=407, reservations=407}, {date=25, number=408, reservations=2}, {date=26, number=409, reservations=1}, {date=27, number=410, reservations=410}, {date=28, number=411, reservations=5}, {date=29, number=412, reservations=0}, {date=30, number=413, reservations=0}]
package com.oracle.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.oracle.constant.MessageConstant;
import com.oracle.entity.Result;
import com.oracle.pojo.OrderSetting;
import com.oracle.service.OrderSettingService;
import com.oracle.utils.POIUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/ordersetting")
public class OrderSettingController {
@Reference
OrderSettingService orderSettingService;
@RequestMapping("/upload")
public Result uploadFromOrderSetting(MultipartFile excelFile){
try {
List<String[]> list = POIUtils.readExcel(excelFile);//使用POI解析表格数据
List<OrderSetting> data = new ArrayList<>();
for (String[] strings : list) {
String orderDate = strings[0];
String number = strings[1];
OrderSetting orderSetting = new OrderSetting(new Date(orderDate),Integer.parseInt(number));
data.add(orderSetting);
}
//通过dubbo远程调用服务实现数据批量导入到数据库
orderSettingService.addFileData(data);
return new Result(true, MessageConstant.IMPORT_ORDERSETTING_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.IMPORT_ORDERSETTING_FAIL);
}
}
//根据月份查询对应的预约设置数据
@RequestMapping("/getOrderSettingByMonth")
public Result getOrderSettingByMonth(String date){//date格式为:yyyy-MM
try{
//为什么封装成List<Map>,根据我们之前测试的静态数据分析出来的
List<Map> list = orderSettingService.getOrderSettingByMonth(date);
return new Result(true, MessageConstant.GET_ORDERSETTING_SUCCESS,list);
}catch (Exception e){
e.printStackTrace();
return new Result(false,MessageConstant.GET_ORDERSETTING_FAIL);
}
}
}
4.完善OrderSettingService接口
package com.oracle.service;
import com.oracle.pojo.OrderSetting;
import java.util.List;
import java.util.Map;
public interface OrderSettingService {
//数据批量导入到数据库
void addFileData(List<OrderSetting> list);
//根据月份查询对应的预约设置数据
List<Map> getOrderSettingByMonth(String date);
}
5.完善OrderSettingServiceImpl实现类
package com.oracle.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.oracle.dao.OrderSettingDao;
import com.oracle.pojo.OrderSetting;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
@Service(interfaceClass = OrderSettingService.class)
public class OrderSettingServiceImpl implements OrderSettingService{
@Autowired
OrderSettingDao orderSettingDao;
@Override
public void addFileData(List<OrderSetting> list) {
if(list!=null && list.size()>0){
for (OrderSetting orderSetting : list) {
//判断当前日期是否已经进行了预约设置
long countByOrderDate = orderSettingDao.findCountByOrderDate(orderSetting.getOrderDate());
if(countByOrderDate > 0){
//已经进行了预约设置,执行更新操作
orderSettingDao.editNumberByOrderDate(orderSetting);
}else{
//没有进行预约设置,执行插入操作
orderSettingDao.addFileData(orderSetting);
}
}
}
}
@Override
//根据月份查询对应的预约设置数据
public List<Map> getOrderSettingByMonth(String date) {//格式:yyyy-MM
String begin = date + "-1";//2019-6-1
String end = date + "-31";//2019-6-31
Map<String,String> map = new HashMap<>();
map.put("begin",begin);
map.put("end",end);
//调用DAO,根据日期范围查询预约设置数据
List<OrderSetting> list = orderSettingDao.getOrderSettingByMonth(map);
List<Map> result = new ArrayList<>();
if(list != null && list.size() > 0){
for (OrderSetting orderSetting : list) {
Map<String,Object> m = new HashMap<>();
m.put("date",orderSetting.getOrderDate().getDate());//获取日期数字(几号)
m.put("number",orderSetting.getNumber());
m.put("reservations",orderSetting.getReservations());
result.add(m);
}
}
return result;
}
}
6.完善OrderSettingDao接口
package com.oracle.dao;
import com.oracle.pojo.OrderSetting;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Repository
public interface OrderSettingDao {
//判断当前日期是否已经进行了预约设置
long findCountByOrderDate(Date orderDate);
//已经进行了预约设置,执行更新操作
void editNumberByOrderDate(OrderSetting orderSetting);
//没有进行预约设置,执行插入操作
void addFileData(OrderSetting orderSetting);
//根据日期范围查询预约设置数据
List<OrderSetting> getOrderSettingByMonth(Map<String, String> map);
}
6.完善OrderSettingDao接口
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oracle.dao.OrderSettingDao">
<!--判断当前日期是否已经进行了预约设置-->
<select id="findCountByOrderDate" parameterType="date" resultType="long">
select count(id) from t_ordersetting where orderDate = #{orderDate}
</select>
<!--已经进行了预约设置,执行更新操作-->
<update id="editNumberByOrderDate" parameterType="com.oracle.pojo.OrderSetting">
update t_ordersetting
set number = #{number}
where orderDate = #{orderDate}
</update>
<!--没有进行预约设置,执行插入操作-->
<insert id="addFileData" parameterType="com.oracle.pojo.OrderSetting">
insert into t_ordersetting
(orderDate,number,reservations)
values
(#{orderDate},#{number},#{reservations})
</insert>
<!--根据日期范围查询-->
<select id="getOrderSettingByMonth" parameterType="map" resultType="com.oracle.pojo.OrderSetting">
select * from t_ordersetting where orderDate between #{begin} and #{end}
</select>
</mapper>
7.启动测试
四、基于日历实现预约设置
本章节要完成的功能为通过点击日历中的设置按钮来设置对应日期的可预约人数。效果如下:
1.点击预约设置,然后点击确认之后的html执行流程
3.完善OrderSettingController
package com.oracle.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.oracle.constant.MessageConstant;
import com.oracle.entity.Result;
import com.oracle.pojo.OrderSetting;
import com.oracle.service.OrderSettingService;
import com.oracle.utils.POIUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/ordersetting")
public class OrderSettingController {
@Reference
OrderSettingService orderSettingService;
@RequestMapping("/upload")
public Result uploadFromOrderSetting(MultipartFile excelFile){
try {
List<String[]> list = POIUtils.readExcel(excelFile);//使用POI解析表格数据
List<OrderSetting> data = new ArrayList<>();
for (String[] strings : list) {
String orderDate = strings[0];
String number = strings[1];
OrderSetting orderSetting = new OrderSetting(new Date(orderDate),Integer.parseInt(number));
data.add(orderSetting);
}
//通过dubbo远程调用服务实现数据批量导入到数据库
orderSettingService.addFileData(data);
return new Result(true, MessageConstant.IMPORT_ORDERSETTING_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, MessageConstant.IMPORT_ORDERSETTING_FAIL);
}
}
//根据月份查询对应的预约设置数据
@RequestMapping("/getOrderSettingByMonth")
public Result getOrderSettingByMonth(String date){//date格式为:yyyy-MM
try{
//为什么封装成List<Map>,根据我们之前测试的静态数据分析出来的
List<Map> list = orderSettingService.getOrderSettingByMonth(date);
return new Result(true, MessageConstant.GET_ORDERSETTING_SUCCESS,list);
}catch (Exception e){
e.printStackTrace();
return new Result(false,MessageConstant.GET_ORDERSETTING_FAIL);
}
}
//根据日期设置对应的预约设置数据
@RequestMapping("/editNumberByDate")
public Result editNumberByDate(@RequestBody OrderSetting orderSetting){
try{
orderSettingService.editNumberByDate(orderSetting);
return new Result(true,MessageConstant.ORDERSETTING_SUCCESS);
}catch (Exception e){
e.printStackTrace();
return new Result(false,MessageConstant.ORDERSETTING_FAIL);
}
}
}
4.完善OrderSettingService接口
package com.oracle.service;
import com.oracle.pojo.OrderSetting;
import java.util.List;
import java.util.Map;
public interface OrderSettingService {
//数据批量导入到数据库
void addFileData(List<OrderSetting> list);
//根据月份查询对应的预约设置数据
List<Map> getOrderSettingByMonth(String date);
//根据日期设置对应的预约设置数据
void editNumberByDate(OrderSetting orderSetting);
}
5.完善OrderSettingServiceImpl实现类
package com.oracle.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.oracle.dao.OrderSettingDao;
import com.oracle.pojo.OrderSetting;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
@Service(interfaceClass = OrderSettingService.class)
public class OrderSettingServiceImpl implements OrderSettingService{
@Autowired
OrderSettingDao orderSettingDao;
@Override
public void addFileData(List<OrderSetting> list) {
if(list!=null && list.size()>0){
for (OrderSetting orderSetting : list) {
//判断当前日期是否已经进行了预约设置
long countByOrderDate = orderSettingDao.findCountByOrderDate(orderSetting.getOrderDate());
if(countByOrderDate > 0){
//已经进行了预约设置,执行更新操作
orderSettingDao.editNumberByOrderDate(orderSetting);
}else{
//没有进行预约设置,执行插入操作
orderSettingDao.addFileData(orderSetting);
}
}
}
}
@Override
//根据月份查询对应的预约设置数据
public List<Map> getOrderSettingByMonth(String date) {//格式:yyyy-MM
String begin = date + "-1";//2019-6-1
String end = date + "-31";//2019-6-31
Map<String,String> map = new HashMap<>();
map.put("begin",begin);
map.put("end",end);
//调用DAO,根据日期范围查询预约设置数据
List<OrderSetting> list = orderSettingDao.getOrderSettingByMonth(map);
List<Map> result = new ArrayList<>();
if(list != null && list.size() > 0){
for (OrderSetting orderSetting : list) {
Map<String,Object> m = new HashMap<>();
m.put("date",orderSetting.getOrderDate().getDate());//获取日期数字(几号)
m.put("number",orderSetting.getNumber());
m.put("reservations",orderSetting.getReservations());
result.add(m);
}
}
return result;
}
@Override
//根据日期设置对应的预约设置数据
public void editNumberByDate(OrderSetting orderSetting) {
Date orderDate = orderSetting.getOrderDate();
//根据日期查询是否已经进行了预约设置
long count = orderSettingDao.findCountByOrderDate(orderDate);
if(count > 0){
//当前日期已经进行了预约设置,需要执行更新操作
orderSettingDao.editNumberByOrderDate(orderSetting);
}else{
//当前日期没有就那些预约设置,需要执行插入操作
orderSettingDao.addFileData(orderSetting);
}
}
}
6.OrderSettingDao和对应的映射文件不用改
7.启动测试