# Excel数据导入功能使用说明

## 功能概述

本系统提供了Excel数据导入功能，可以将包含T1、T2、T3、T4、T5、T6、T7、T8、T10和T11工作表的Excel文件数据导入到十四个数据库表中：

### 红球数据（T1 Sheet）：
- `history_all` - 红球全部历史数据表
- `history_100` - 红球最近100期数据表  
- `history_top` - 红球历史数据排行表
- `history_top_100` - 红球100期数据排行表

### 蓝球数据（T2 Sheet）：
- `blue_history_all` - 蓝球全部历史数据表
- `blue_history_100` - 蓝球最近100期数据表  
- `blue_history_top` - 蓝球历史数据排行表
- `blue_history_top_100` - 蓝球100期数据排行表

### 红球线系数数据（T3 Sheet）：
- `t3` - 红球组红球的线系数表

### 蓝球组红球线系数数据（T4 Sheet）：
- `t4` - 蓝球组红球的线系数表

### 蓝球组蓝球线系数数据（T5 Sheet）：
- `t5` - 蓝球组蓝球的线系数表

### 红球组蓝球线系数数据（T6 Sheet）：
- `t6` - 红球组蓝球的线系数表

### 红球组红球面系数数据（T7 Sheet）：
- `t7` - 红球组红球的面系数表

### 红球组蓝球面系数数据（T8 Sheet）：
- `t8` - 红球组蓝球的面系数表

### 彩票开奖信息数据（T10 Sheet）：
- `lottery_draws` - 彩票开奖信息表

### 蓝球组红球面系数数据（T11 Sheet）：
- `t11` - 蓝球组红球的面系数表

## Excel文件格式要求

### 文件要求
- **文件格式**：必须是`.xlsx`格式
- **工作表名称**：必须包含名为`T1`、`T2`、`T3`、`T4`、`T5`、`T6`、`T7`、`T8`、`T10`和`T11`的工作表
- **编码**：支持中文

### 数据结构要求

**T1工作表（红球数据）**的数据结构如下：

| 列位置 | 列名 | 对应表 | 字段说明 |
|--------|------|--------|----------|
| A-G | 全部历史数据 | history_all | 球号、出现频次、出现频率%、平均隐现期次、最长隐现期次、最多连出期次、点系数 |
| H-M | 最近100期数据 | history_100 | 出现频次、出现频率%、平均隐现期、当前隐现期、最多连出期次、点系数 |
| N-P | 历史数据排行 | history_top | 排行、球号、点系数 |
| Q-S | 100期数据排行 | history_top_100 | 排行、球号、点系数 |

**T2工作表（蓝球数据）**的数据结构如下：

| 列位置 | 列名 | 对应表 | 字段说明 |
|--------|------|--------|----------|
| A-G | 全部历史数据 | blue_history_all | 球号、出现频次、出现频率%、平均隐现期次、最长隐现期次、最多连出期次、点系数 |
| H-M | 最近100期数据 | blue_history_100 | 出现频次、出现频率%、平均隐现期、当前隐现期、最多连出期次、点系数 |
| N-P | 历史数据排行 | blue_history_top | 排行、球号、点系数 |
| Q-S | 100期数据排行 | blue_history_top_100 | 排行、球号、点系数 |

**T3工作表（红球线系数数据）**的数据结构如下：

| 列位置 | 数据组织 | 对应表 | 字段说明 |
|--------|----------|--------|----------|
| C | 1号组线系数 | t3 | 主球=1，从球=1-33，线系数=C列 |
| F | 2号组线系数 | t3 | 主球=2，从球=1-33，线系数=F列 |
| I | 3号组线系数 | t3 | 主球=3，从球=1-33，线系数=I列 |
| ... | 依此类推 | t3 | 每三列为一组，组号即主球号 |

**说明**：T3工作表每三列为一组数据，每组有33行数据，从球号固定为1-33（行号），线系数在C、F、I、L...列。

**T4工作表（蓝球组红球线系数数据）**的数据结构如下：

| 列位置 | 数据组织 | 对应表 | 字段说明 |
|--------|----------|--------|----------|
| C | 蓝球1号线系数 | t4 | 主球=1，从球=1-33，线系数=C列 |
| F | 蓝球2号线系数 | t4 | 主球=2，从球=1-33，线系数=F列 |
| I | 蓝球3号线系数 | t4 | 主球=3，从球=1-33，线系数=I列 |
| ... | 依此类推 | t4 | 每三列为一组，最多16组 |

**说明**：T4工作表每三列为一组数据，每组有33行数据，蓝球号码1-16（主球），红球号码1-33（从球，行号），线系数在C、F、I、L...列。

**T5工作表（蓝球组蓝球线系数数据）**的数据结构如下：

| 列位置 | 数据组织 | 对应表 | 字段说明 |
|--------|----------|--------|----------|
| C | 蓝球1号线系数 | t5 | 主球=1，从球=1-16，线系数=C列 |
| F | 蓝球2号线系数 | t5 | 主球=2，从球=1-16，线系数=F列 |
| I | 蓝球3号线系数 | t5 | 主球=3，从球=1-16，线系数=I列 |
| ... | 依此类推 | t5 | 每三列为一组，最多16组 |

**说明**：T5工作表每三列为一组数据，每组有16行数据，蓝球号码1-16（主球和从球），线系数在C、F、I、L...列。

**T6工作表（红球组蓝球线系数数据）**的数据结构如下：

| 列位置 | 数据组织 | 对应表 | 字段说明 |
|--------|----------|--------|----------|
| C | 红球1号线系数 | t6 | 主球=1，从球=1-16，线系数=C列 |
| F | 红球2号线系数 | t6 | 主球=2，从球=1-16，线系数=F列 |
| I | 红球3号线系数 | t6 | 主球=3，从球=1-16，线系数=I列 |
| ... | 依此类推 | t6 | 每三列为一组，最多33组 |

**说明**：T6工作表每三列为一组数据，每组有16行数据，红球号码1-33（主球），蓝球号码1-16（从球，行号），线系数在C、F、I、L...列。

**T7工作表（红球组红球面系数数据）**的数据结构如下：

| 列位置 | 数据组织 | 对应表 | 字段说明 |
|--------|----------|--------|----------|
| C | 红球1号面系数 | t7 | 主球=1，从球=2-33，面系数=C列 |
| F | 红球2号面系数 | t7 | 主球=2，从球=1,3-33，面系数=F列 |
| I | 红球3号面系数 | t7 | 主球=3，从球=1-2,4-33，面系数=I列 |
| ... | 依此类推 | t7 | 每三列为一组，最多33组 |

**说明**：T7工作表每三列为一组数据，每组有33行数据，红球号码1-33（主球和从球），面系数在C、F、I、L...列。**特殊处理**：排除自己和自己组合的情况。

**Excel数据结构**：
- **第1行**：标题行（1号组、面系数、2号组、面系数...）
- **第2行**：从球1号的数据（对应所有主球的面系数）
- **第3行**：从球2号的数据（对应所有主球的面系数）
- **...**
- **第34行**：从球33号的数据（对应所有主球的面系数）

**处理逻辑**：
- **1号组（主球1）**：
  - 球号列：B列，面系数列：C列
  - 读取所有行，从B列获取从球号，从C列获取面系数
  - 排除对角线（主球1=从球1的情况）
- **2号组（主球2）**：
  - 球号列：E列，面系数列：F列
  - 读取所有行，从E列获取从球号，从F列获取面系数
  - 排除对角线（主球2=从球2的情况）
- **依此类推...**

**关键改进**：
- **动态读取球号**：从Excel的球号列（B、E、H...）读取实际球号，不依赖行号
- **完整数据覆盖**：读取到Excel的最后一行，确保包含33号球数据
- **不排除对角线**：读取到什么数据就插入什么数据，包括主球=从球的情况
- **最终生成**：33×33=1089条记录

### 具体列映射

#### 红球表映射（T1 Sheet）

**history_all 表 (列A-G)**
- A列：球号 (ballNumber)
- B列：出现频次 (frequencyCount)  
- C列：出现频率% (frequencyPercentage)
- D列：平均隐现期次 (averageInterval)
- E列：最长隐现期次 (maxHiddenInterval)
- F列：最多连出期次 (maxConsecutiveCount)
- G列：点系数 (pointCoefficient)

**history_100 表 (列H-M，球号使用A列)**
- A列：球号 (ballNumber)
- H列：出现频次 (frequencyCount)
- J列：平均隐现期 (averageInterval)
- K列：当前隐现期 (nowInterval)
- L列：最多连出期次 (maxConsecutiveCount)
- M列：点系数 (pointCoefficient)

**history_top 表 (列N-P)**
- N列：排行 (no)
- O列：球号 (ballNumber)
- P列：点系数 (pointCoefficient)

**history_top_100 表 (列Q-S)**
- Q列：排行 (no)
- R列：球号 (ballNumber)
- S列：点系数 (pointCoefficient)

#### 蓝球表映射（T2 Sheet）

**blue_history_all 表 (列A-G)**
- A列：球号 (ballNumber)
- B列：出现频次 (frequencyCount)  
- C列：出现频率% (frequencyPercentage)
- D列：平均隐现期次 (averageInterval)
- E列：最长隐现期次 (maxHiddenInterval)
- F列：最多连出期次 (maxConsecutiveCount)
- G列：点系数 (pointCoefficient)

**blue_history_100 表 (列H-M，球号使用A列)**
- A列：球号 (ballNumber)
- H列：出现频次 (frequencyCount)
- J列：平均隐现期 (averageInterval)
- K列：当前隐现期 (nowInterval)
- L列：最多连出期次 (maxConsecutiveCount)
- M列：点系数 (pointCoefficient)

**blue_history_top 表 (列N-P)**
- N列：排行 (no)
- O列：球号 (ballNumber)
- P列：点系数 (pointCoefficient)

**blue_history_top_100 表 (列Q-S)**
- Q列：排行 (no)
- R列：球号 (ballNumber)
- S列：点系数 (pointCoefficient)

#### T3表映射（T3 Sheet）

**t3 表（红球线系数数据）**
- 数据组织：每三列为一组，每组33行数据
- 红球号码范围：1-33（主球和从球都是）
- 线系数位置：C、F、I、L...列

**数据映射**：
- C列：红球1号线系数（主球=1，从球=1-33，线系数=C列）
- F列：红球2号线系数（主球=2，从球=1-33，线系数=F列）
- I列：红球3号线系数（主球=3，从球=1-33，线系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主红球号码（1-33）
- slaveBallNumber：从红球号码（固定1-33，对应行号）
- lineCoefficient：线系数（每组第三列，保留两位小数）

#### T4表映射（T4 Sheet）

**t4 表（蓝球组红球的线系数）**
- 数据组织：每三列为一组，每组33行数据
- 蓝球号码范围：1-16（主球）
- 红球号码范围：1-33（从球，对应行号）
- 线系数位置：C、F、I、L...列

**数据映射**：
- C列：蓝球1号线系数（主球=1，从球=1-33，线系数=C列）
- F列：蓝球2号线系数（主球=2，从球=1-33，线系数=F列）
- I列：蓝球3号线系数（主球=3，从球=1-33，线系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：蓝球号码（1-16）
- slaveBallNumber：红球号码（固定1-33，对应行号）
- lineCoefficient：线系数（每组第三列，保留两位小数）

#### T5表映射（T5 Sheet）

**t5 表（蓝球组蓝球的线系数）**
- 数据组织：每三列为一组，每组16行数据
- 蓝球号码范围：1-16（主球和从球都是）
- 线系数位置：C、F、I、L...列

**数据映射**：
- C列：蓝球1号线系数（主球=1，从球=1-16，线系数=C列）
- F列：蓝球2号线系数（主球=2，从球=1-16，线系数=F列）
- I列：蓝球3号线系数（主球=3，从球=1-16，线系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主蓝球号码（1-16）
- slaveBallNumber：从蓝球号码（固定1-16，对应行号）
- lineCoefficient：线系数（每组第三列，保留两位小数）

#### T6表映射（T6 Sheet）

**t6 表（红球组蓝球的线系数）**
- 数据组织：每三列为一组，每组16行数据
- 红球号码范围：1-33（主球）
- 蓝球号码范围：1-16（从球）
- 线系数位置：C、F、I、L...列

**数据映射**：
- C列：红球1号线系数（主球=1，从球=1-16，线系数=C列）
- F列：红球2号线系数（主球=2，从球=1-16，线系数=F列）
- I列：红球3号线系数（主球=3，从球=1-16，线系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主红球号码（1-33）
- slaveBallNumber：从蓝球号码（固定1-16，对应行号）
- lineCoefficient：线系数（每组第三列，保留两位小数）

#### T7表映射（T7 Sheet）

**t7 表（红球组红球的面系数）**
- 数据组织：每三列为一组，每组33行数据
- 红球号码范围：1-33（主球和从球都是）
- 面系数位置：C、F、I、L...列
- 特殊处理：读取到什么数据就插入什么数据，包括对角线

**数据映射**：
- C列：红球1号面系数（主球=1，从球=1-33，面系数=C列）
- F列：红球2号面系数（主球=2，从球=1-33，面系数=F列）
- I列：红球3号面系数（主球=3，从球=1-33，面系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主红球号码（1-33）
- slaveBallNumber：从红球号码（1-33，包括与主球相同的号码）
- faceCoefficient：面系数（每组第三列，保留两位小数）

#### T8表映射（T8 Sheet）

**t8 表（红球组蓝球的面系数）**
- 数据组织：每三列为一组，每组16行数据
- 红球号码范围：1-33（主球）
- 蓝球号码范围：1-16（从球）
- 面系数位置：C、F、I、L...列

**数据映射**：
- C列：红球1号面系数（主球=1，从球=1-16，面系数=C列）
- F列：红球2号面系数（主球=2，从球=1-16，面系数=F列）
- I列：红球3号面系数（主球=3，从球=1-16，面系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主红球号码（1-33）
- slaveBallNumber：从蓝球号码（固定1-16，对应行号）
- faceCoefficient：面系数（每组第三列，保留两位小数）

#### T10表映射（T10 Sheet）

**lottery_draws 表（彩票开奖信息）**
- 数据组织：标准表格结构，每行一条开奖记录
- 开奖期号：Long类型主键
- 开奖日期：Date类型，支持多种格式
- 红球1-6：Integer类型
- 蓝球：Integer类型

**数据映射**：
- A列：开奖期号（drawId）
- B列：开奖日期（drawDate）
- C列：红球1（redBall1）
- D列：红球2（redBall2）
- E列：红球3（redBall3）
- F列：红球4（redBall4）
- G列：红球5（redBall5）
- H列：红球6（redBall6）
- I列：蓝球（blueBall）

**字段映射**：
- drawId：开奖期号（Long类型，主键）
- drawDate：开奖日期（Date类型，支持yyyy-MM-dd、yyyy/MM/dd等格式）
- redBall1-redBall6：红球1-6（Integer类型）
- blueBall：蓝球（Integer类型）

**数据特性**：
- 所有字段均为必填项
- 开奖期号为主键，不能重复
- 日期格式自动识别和转换
- 数据完整性验证

#### T11表映射（T11 Sheet）

**t11 表（蓝球组红球的面系数）**
- 数据组织：每三列为一组，每组33行数据
- 蓝球号码范围：1-16（主球）
- 红球号码范围：1-33（从球）
- 面系数位置：C、F、I、L...列

**数据映射**：
- C列：蓝球1号面系数（主球=1，从球=1-33，面系数=C列）
- F列：蓝球2号面系数（主球=2，从球=1-33，面系数=F列）
- I列：蓝球3号面系数（主球=3，从球=1-33，面系数=I列）
- 依此类推...

**字段映射**：
- masterBallNumber：主蓝球号码（1-16）
- slaveBallNumber：从红球号码（固定1-33，对应行号）
- faceCoefficient：面系数（每组第三列，保留两位小数）

## 使用方法

### 1. API接口方式

#### 1.1 文件上传导入
```http
POST /api/excel/upload
Content-Type: multipart/form-data

参数：
- file: Excel文件 (.xlsx格式)
```

#### 1.2 文件路径导入
```http
POST /api/excel/import-by-path
Content-Type: application/x-www-form-urlencoded

参数：
- filePath: Excel文件的完整路径 (例如: D:/data/kaifa1.xlsx)
```

#### 1.3 获取导入说明
```http
GET /api/excel/import-info
```

### 2. 程序调用方式

```java
@Autowired
private ExcelImportService excelImportService;

// 方式1：通过文件路径导入
String result = excelImportService.importExcelFileByPath("D:/data/kaifa1.xlsx");

// 方式2：通过MultipartFile导入
String result = excelImportService.importExcelFile(multipartFile);
```

### 3. 测试方式

运行测试类：
```java
// 运行 ExcelImportTest 类中的测试方法
@Test
public void testImportExcelByPath() {
    // 修改文件路径为实际路径
    String filePath = "D:/code/xy-ai-cpzs/kaifa1.xlsx";
    String result = excelImportService.importExcelFileByPath(filePath);
    System.out.println("导入结果：" + result);
}
```

## 注意事项

1. **数据清空**：每次导入前会清空现有数据，请谨慎操作
2. **数据验证**：系统会验证数据的完整性，球号为空的记录会被跳过
3. **错误处理**：导入过程中如有错误会回滚操作并返回错误信息
4. **日志记录**：导入过程会记录详细日志，便于问题排查
5. **文件大小**：建议文件大小不超过10MB
6. **并发限制**：避免同时进行多个导入操作

## 常见问题

### Q1: 提示"未找到T1/T2/T3/T4/T5/T6/T7/T8/T10/T11工作表"
**A**: 请检查Excel文件是否包含名为"T1"（红球数据）、"T2"（蓝球数据）、"T3"（红球线系数）、"T4"（蓝球组红球线系数）、"T5"（蓝球组蓝球线系数）、"T6"（红球组蓝球线系数）、"T7"（红球组红球面系数）、"T8"（红球组蓝球面系数）、"T10"（彩票开奖信息）和"T11"（蓝球组红球面系数）的工作表，注意区分大小写。如果缺少某个工作表，系统会跳过该部分数据并显示警告。

### Q2: 导入后数据不完整
**A**: 请检查Excel数据格式是否正确，确保数值类型的列包含有效数字。

### Q3: 导入失败提示文件格式错误
**A**: 请确保文件是.xlsx格式，不支持.xls格式。

### Q4: 如何查看导入日志
**A**: 导入过程中的日志会输出到控制台，可以通过查看应用日志了解详细信息。

### Q5: 报错"Cannot get a NUMERIC value from a STRING cell"
**A**: 这个错误已经修复。系统现在能够自动处理字符串类型的数值单元格，会尝试将字符串转换为数值。

### Q6: Excel中有公式单元格怎么办
**A**: 系统支持公式单元格，会自动读取公式计算后的结果值。

### Q7: 单元格为空怎么处理
**A**: 空白单元格会被自动跳过，对应的字段值会设为null。

## 数据类型支持

系统支持以下类型的Excel单元格：
- **数值类型** - 直接读取数值
- **字符串类型** - 尝试转换为数值（如果包含数字）
- **公式类型** - 读取公式计算结果
- **空白类型** - 设为null
- **其他类型** - 会记录警告日志并设为null

## 数据精度处理

- **浮点数字段**：自动保留两位小数（使用四舍五入）
- **整数字段**：直接转换为整数（去除小数部分）
- **特殊值处理**：NaN和无穷大值会被设为null

示例：
- `123.456789` → `123.46`
- `12.1` → `12.10`
- `5` → `5.00`

## Swagger文档

启动应用后，可以通过以下地址访问API文档：
- Swagger UI: http://localhost:8123/api/swagger-ui.html
- Knife4j UI: http://localhost:8123/api/doc.html

在文档中可以直接测试Excel导入接口。 