美年旅游_预约管理_预约设置_批量导入预约设置信息POI

本文介绍了如何使用Apache POI库从Excel文件读取数据,包括创建工作簿对象、获取工作表和单元格,以及向Excel文件写入数据。通过批量导入功能,将预约设置信息批量导入到数据库,涉及前后台代码实现,包括模板文件下载、文件上传和后台服务处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

美年旅游_预约管理_预约设置

1.预约设置需求分析
前面我们已经完成了自由行管理、跟团游管理、套餐管理等。接下来我们需要进行预约设置,其实就是设置每一天的旅游预约最大数量。客户可以通过微信端在线预约,在线预约时需要选择旅游的时间,使得选择旅游时间的已预约人数加1,如果客户选择的时间已经预约满则无法进行预约。
2.t_ordersetting表结构:
在这里插入图片描述
orderDate:预约日期
number:最多可预约人数
reservations:已预约人数
导入mysql数据

DROP TABLE IF EXISTS `t_ordersetting`;
CREATE TABLE `t_ordersetting` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orderDate` date DEFAULT NULL COMMENT '约预日期',
  `number` int(11) DEFAULT NULL COMMENT '可预约人数',
  `reservations` int(11) DEFAULT NULL COMMENT '已预约人数',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8;

第二章. Apache POI

2.1. POI介绍

2.1.1 简介

开发中经常会涉及到excel的处理,如导出Excel,导入Excel到数据库中,操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel
Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能。
官方主页: http://poi.apache.org/index.html
API文档: http://poi.apache.org/apidocs/index.html
maven坐标:

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.14</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.14</version>
</dependency>

2.1.2 Apache POI常用的类

POI结构:

HSSF - 提供读写Microsoft Excel XLS格式档案的功能
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能(我们使用)
HWPF - 提供读写Microsoft Word DOC格式档案的功能
HSLF - 提供读写Microsoft PowerPoint格式档案的功能
HDGF - 提供读Microsoft Visio格式档案的功能
HPBF - 提供读Microsoft Publisher格式档案的功能
HSMF - 提供读Microsoft Outlook格式档案的功能

我们使用:XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能

2.2. 入门案例

2.2.1. 从Excel文件读取数据

【需求】
使用POI可以从一个已经存在的Excel文件中读取数据
【路径】
1:创建工作簿对象
2:获得工作表对象
3:遍历工作表对象 获得行对象
4:遍历行对象 获得单元格(列)对象
5:获得数据
6:关闭

【讲解】

  1. 实现
    使用POI可以从一个已经存在的Excel文件中读取数据
    在meinian_common中建立测试类,TestPoi.java
package com.atguigu;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;

// 读取excel
public class TestPoi {
        @Test
        public void readExcel() throws IOException {
            //创建工作簿
            XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx");
            //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取
            XSSFSheet sheet = workbook.getSheetAt(0);
            //遍历工作表获得行对象
            for (Row row : sheet) {
                //遍历行对象获取单元格对象
                for (Cell cell : row) {
                    //获得单元格中的值
                    String value = cell.getStringCellValue(); //注意:数字类型,需要修改excel单元格的类型,否则报错。
                    System.out.println(value);// new String(value.getBytes("UTF-8"),"GBK"));

                }
            }
            workbook.close();
        }

【小结】
通过上面的入门案例可以看到,POI操作Excel表格封装了几个核心对象:

XSSFWorkbook:工作簿
XSSFSheet:工作表
XSSFRow:行
XSSFCell:单元格

上面案例是通过遍历工作表获得行,遍历行获得单元格,最终获取单元格中的值。
错误
在这里插入图片描述
解决方案

在这里插入图片描述
还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象,代码如下:

public class TestPoi {
    // 导出excel,获取最后一行
    @Test
    public void exportExcel_lastRow() throws IOException {
        //创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx");
        //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取
        XSSFSheet sheet = workbook.getSheetAt(0);
        //获取当前工作表最后一行的行号,行号从0开始
        int lastRowNum = sheet.getLastRowNum();
        for(int i=0;i<=lastRowNum;i++){
            //根据行号获取行对象
            XSSFRow row = sheet.getRow(i);
             // 再获取单元格对象
            short lastCellNum = row.getLastCellNum();
            for(short j=0;j<lastCellNum;j++){
                 // 获取单元格对象的值
                String value = row.getCell(j).getStringCellValue();
                System.out.println(value);
            }
        }
        workbook.close();
    }

2.2.2. 向Excel文件写入数据

【需求】
使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘
【路径】

1.创建工作簿对象
2.创建工作表对象
3.创建行对象
4.创建列(单元格)对象, 设置内容
5.通过输出流将workbook对象下载到磁盘

【实现】
使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘

// 导入excel
@Test
public void importExcel() throws IOException {
    //在内存中创建一个Excel文件
    XSSFWorkbook workbook = new XSSFWorkbook();
    //创建工作表,指定工作表名称
    XSSFSheet sheet = workbook.createSheet("尚硅谷");

    //创建行,0表示第一行
    XSSFRow row = sheet.createRow(0);
    //创建单元格,0表示第一个单元格
    row.createCell(0).setCellValue("编号");
    row.createCell(1).setCellValue("姓名");
    row.createCell(2).setCellValue("年龄");

    XSSFRow row1 = sheet.createRow(1);
    row1.createCell(0).setCellValue("1");
    row1.createCell(1).setCellValue("小明");
    row1.createCell(2).setCellValue("10");

    XSSFRow row2 = sheet.createRow(2);
    row2.createCell(0).setCellValue("2");
    row2.createCell(1).setCellValue("小王");
    row2.createCell(2).setCellValue("20");

    //通过输出流将workbook对象下载到磁盘
    FileOutputStream out = new FileOutputStream("D:\\atguigu.xlsx");
    workbook.write(out);
    out.flush();//刷新
    out.close();//关闭
    workbook.close();
}

在这里插入图片描述
小结:POI技术
• 创建工作簿的时候, 不需要传入参数(excel不存在的)
• 使用输出流,输出excel
应用场景:
1:从excel中读取数据,写入到数据库(导入);
2:从数据库查询数据,写入到excel文件(导出)

2.2.3.POI工具类的介绍

将资料中的POIUtils工具类复制到 meinian_common 工程

在这里插入图片描述
1.POI介绍
POI就是一个工具类库, 用来操作Office, 我们主要用来操作Excel
2.POI入门案例
(1)从Excel文件读取数据
(2)向Excel文件写入数据
3.POI工具类的介绍
使用工具类, 读取Excel, 每一行读取到了String[] 里面, 多行就是多个String[] , 最终封装到List

第三章. 批量导入预约设置信息

1:前台代码
(1)提供模板文件
(2)实现模板文件下载
(3)文件上传
2:后台代码
业务:
• 从excel中读取预约设置信息,批量导入到数据库
(1)OrderSettingController.java(Controller)
(2)OrderSettingService.java(服务接口)
(3)OrderSettingServiceImpl.java(服务实现类)
(4)OrderSettingDao.java(Dao接口)
(5)OrderSettingDao.xml(Mapper映射文件)

【讲解】

【需求】

从Excel读取预约设置的数据,批量导入到数据库
在这里插入图片描述
【设计】
预约设置信息对应的数据表为t_ordersetting,预约设置操作对应的页面为ordersetting.html
1:t_ordersetting表结构:

在这里插入图片描述
rderDate:预约日期
number:可预约人数
reservations:已预约人数
【路径】
批量导入预约设置信息操作过程:
第一步、点击模板下载按钮下载Excel模板文件【文件下载】
第二步、将预约设置信息录入到模板文件中
第三步、点击上传文件按钮将录入完信息的模板文件上传到服务器【文件上传】
第四步、通过POI读取上传文件的数据并保存到数据库【poi导入】
2:将 ordersetting.html 放置到 meinian_web\src\main\webapp\pages 中
在这里插入图片描述

3.1. 前台代码

3.1.1. 提供模板文件

资料中已经提供了Excel模板文件ordersetting_template.xlsx,将文件放在meinian_web工程的template目录下

在这里插入图片描述

3.1.2. 实现模板文件下载

(1)为模板下载按钮绑定事件实现模板文件下载

<el-button style="margin-bottom: 20px;margin-right: 20px" type="primary" @click="downloadTemplate()">模板下载</el-button>

(2)downloadTemplate()

//下载模板文件
downloadTemplate(){
    window.location.href="../../template/ordersetting_template.xlsx";
},

3.1.3. 文件上传

(1)使用ElementUI的上传组件实现文件上传并绑定相关事件

<el-upload action="/ordersetting/upload.do"
           name="excelFile"
           :show-file-list="false"
           :on-success="handleSuccess"
           :before-upload="beforeUpload">
    <el-button type="primary">上传文件</el-button>
</el-upload>

(2)handleSuccess方法:用于显示上传成功或者失败信息。

//上传成功提示
handleSuccess(response, file) {
    if(response.flag){
         this.$message({
              message: response.message,
              type: 'success'
         });
    }else{
         this.$message.error(response.message);
    }
},

(3)beforeUpload方法:用于校验上传的文件是否是excel文件

//上传之前进行文件格式校验
beforeUpload(file){
    //alert("文件名:" + file.name);
	//alert("文件类型:" + file.type);
	var f_index = file.name.lastIndexOf(".");

	if(f_index != -1){
        var f_type = file.name.substring(f_index+1, file.name.length).toLowerCase();

        if(f_type == 'xls' || f_type == 'xlsx'){
            return true;
        }
	}
    const isXLS = file.type === 'application/vnd.ms-excel';
    if(isXLS){
        return true;
    }
    const isXLSX = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    if (isXLSX) {
        return true;
    }
    this.$message.error('上传文件只能是xls或者xlsx格式!');
    return false;
},

3.2. 后台代码

3.2.1. Controller

【路径】
1.点击上传文件, 把编写好的Excel上传到OrderSettingController
2.创建OrderSettingController, 创建upload()方法

//1.使用POI解析文件 得到List<String[]> list
//2.把List<String[]> list转成 List<OrderSetting> list
//3.调用业务 进行保存

3.创建OrderSettingService

//1.遍历List<OrderSetting> list
//2.判断当前的日期之前是否设置过
//	2.1 设置过, 更新数量
//	2.2 没有设置过, 保存

4.创建OrderSettingDao

//根据日期查询
//根据日期更新number
//保存OrderSetting

在 meinian_web 工程创建 OrderSettingController 并提供upload方法

package com.atguigu.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.atguigu.constant.MessageConstant;
import com.atguigu.entity.Result;
import com.atguigu.pojo.OrderSetting;
import com.atguigu.service.OrdersettingService;
import com.atguigu.utils.POIUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/ordersetting")
public class OrdersettingController {

    @Reference
    private OrdersettingService ordersettingService;

    @RequestMapping("/upload")
    public Result upload(MultipartFile excelFile){
        try {
            // 使用poi工具类解析excel文件,读取里面的内容
            List<String[]> lists = POIUtils.readExcel(excelFile);
            // 把List<String[]> 数据转换成 List<OrderSetting>数据
            List<OrderSetting> orderSettings = new ArrayList<>();
            //  迭代里面的每一行数据,进行封装到集合里面
            for (String[] str : lists) {
                // 获取到一行里面,每个表格数据,进行封装
                OrderSetting orderSetting = new OrderSetting(new Date(str[0]),Integer.parseInt(str[1]));
                orderSettings.add(orderSetting);
            }
            /*
 							for (String[] arrStrings : lists) {
                //获取第一个字符串类型的日期
               String dateStr =  arrStrings[0];
               //获取第一个字符串类型的人数
               String numberStr = arrStrings[1];
               //new一个 orderSetting对象
               OrderSetting orderSetting = new OrderSetting();
               //为这个对象set数据
               orderSetting.setOrderDate(new Date(dateStr));
               orderSetting.setNumber(Integer.parseInt(numberStr));
               //往List集合例添加数据
                orderSettings.add(orderSetting);
               
            }

            */
            
            // 调用业务进行保存
            ordersettingService.add(orderSettings);
            return new Result(true, MessageConstant.IMPORT_ORDERSETTING_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(true, MessageConstant.IMPORT_ORDERSETTING_FAIL);
        }

    }
}

3.2.2. 服务接口

创建OrderSettingService服务接口并提供新增方法

package com.atguigu.service;

import com.atguigu.pojo.OrderSetting;
import java.util.List;

public interface OrdersettingService {
    void add(List<OrderSetting> orderSettings);
}

3.2.3. 服务实现类

创建服务实现类OrderSettingServiceImpl并实现新增方法

package com.atguigu.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.dao.OrdersettingDao;
import com.atguigu.pojo.OrderSetting;
import com.atguigu.service.OrdersettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service(interfaceClass = OrdersettingService.class)
@Transactional
public class OrdersettingServiceImpl implements OrdersettingService {

    @Autowired
    private OrdersettingDao ordersettingDao;

    @Override
    public void add(List<OrderSetting> orderSettings) {
        // 1:遍历List<OrderSetting>
        for (OrderSetting orderSetting : orderSettings) {
            // 判断当前的日期之前是否已经被设置过预约日期,使用当前时间作为条件查询数量
            long count = ordersettingDao.findCountByOrderDate(orderSetting.getOrderDate());
            // 如果设置过预约日期,更新number数量
            if (count>0){
                ordersettingDao.editNumberByOrderDate(orderSetting);
            }else {
                // 如果没有设置过预约日期,执行保存
                ordersettingDao.add(orderSetting);
            }
        }
    }
}

3.2.4. Dao接口

创建Dao接口OrderSettingDao并提供更新和新增方法

package com.atguigu.dao;

import com.atguigu.pojo.OrderSetting;
import java.util.Date;

public interface OrdersettingDao {
    void add(OrderSetting orderSetting);
    long findCountByOrderDate(Date orderDate);
    void editNumberByOrderDate(OrderSetting orderSetting);
}

3.2.5. Mapper映射文件

创建Mapper映射文件OrderSettingDao.xml并提供相关SQL

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.dao.OrdersettingDao">
    <!--根据预约日期查询-->
    <select id="findCountByOrderDate" parameterType="java.util.Date" resultType="long">
        select count(*) from t_ordersetting where orderDate = #{orderDate}
    </select>
  
    <!--新增-->
    <insert id="add" parameterType="ordersetting">
        insert into t_ordersetting(orderDate,number) values (#{orderDate},#{number})
    </insert>
  
    <!--根据日期更新预约人数-->
    <update id="editNumberByOrderDate" parameterType="orderSetting">
        update t_ordersetting set number = #{number} where orderDate = #{orderDate}
    </update>
    
</mapper>

查看t_ordersetting表

在这里插入图片描述
【小结】
1:前台代码
(1)提供模板文件
(2)实现模板文件下载
(3)文件上传
2:后台代码
• 从excel中读取预约设置信息,批量导入到数据库
(1)OrderSettingController.java(Controller)
(2)OrderSettingService.java(服务接口)
(3)OrderSettingServiceImpl.java(服务实现类)
(4)OrderSettingDao.java(Dao接口)
(5)OrderSettingDao.xml(Mapper映射文件)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月常新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值