Files
ruoyi-java/doc/腾讯文档API_Range格式说明.md
2025-11-06 11:05:22 +08:00

352 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 腾讯文档 API Range 格式说明
## 问题发现
在调用腾讯文档 V3 API 时,使用 Excel 格式的 range`A3:Z203`)会返回错误:
```json
{
"code": 400001,
"message": "invalid param error: 'range' invalid"
}
```
## ✅ 正确的 Range 格式
腾讯文档 V3 API 使用**索引格式**,不是 Excel 的字母+数字格式。
### 格式规范
```
startRow,startColumn,endRow,endColumn
```
**说明**
- 所有索引**从 0 开始**
- 用逗号分隔四个值
- `startRow`:起始行索引
- `startColumn`:起始列索引
- `endRow`:结束行索引
- `endColumn`:结束列索引
---
## 📋 格式转换示例
### 示例 1读取表头第2行A到Z列
**Excel 格式**(错误):
```
A2:Z2
```
**索引格式**(正确):
```
1,0,1,25
```
**解释**
- 第2行 → 索引 1行从0开始
- A列 → 索引 0
- 第2行 → 索引 1
- Z列 → 索引 25A=0, B=1, ..., Z=25
---
### 示例 2读取数据行第3行到第203行A到Z列
**Excel 格式**(错误):
```
A3:Z203
```
**索引格式**(正确):
```
2,0,202,25
```
**解释**
- 第3行 → 索引 2
- A列 → 索引 0
- 第203行 → 索引 202
- Z列 → 索引 25
---
### 示例 3读取单个单元格M3
**Excel 格式**(错误):
```
M3
```
**索引格式**(正确):
```
2,12,2,12
```
**解释**
- 第3行 → 索引 2
- M列 → 索引 12A=0, ..., M=12
- 结束行也是第3行 → 索引 2
- 结束列也是M列 → 索引 12
---
## 🔢 行列索引对照表
### 行索引Excel行号 → 索引)
| Excel 行号 | 索引 |
|-----------|------|
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| ... | ... |
| 100 | 99 |
| 203 | 202 |
**转换公式**`索引 = Excel行号 - 1`
### 列索引(列字母 → 索引)
| 列字母 | 索引 |
|-------|------|
| A | 0 |
| B | 1 |
| C | 2 |
| D | 3 |
| ... | ... |
| M | 12 |
| ... | ... |
| Z | 25 |
| AA | 26 |
| AB | 27 |
**转换公式**
- 单字母:`索引 = 字母 - 'A'`A=0, B=1, ...
- 多字母:`索引 = (第一字母 - 'A' + 1) * 26 + (第二字母 - 'A')`
---
## 💻 代码实现
### Java 转换方法
```java
/**
* 将Excel行号转换为API索引
* @param excelRow Excel行号从1开始
* @return API索引从0开始
*/
public static int excelRowToIndex(int excelRow) {
return excelRow - 1;
}
/**
* 将列字母转换为索引
* @param column 列字母A, B, C, ..., Z, AA, AB, ...
* @return 列索引从0开始
*/
public static int columnLetterToIndex(String column) {
column = column.toUpperCase();
int index = 0;
for (int i = 0; i < column.length(); i++) {
index = index * 26 + (column.charAt(i) - 'A' + 1);
}
return index - 1;
}
/**
* 将Excel范围转换为API range格式
* @param excelRange Excel范围如 "A3:Z203"
* @return API range格式如 "2,0,202,25"
*/
public static String excelRangeToApiRange(String excelRange) {
// 解析 A3:Z203
String[] parts = excelRange.split(":");
String start = parts[0]; // A3
String end = parts[1]; // Z203
// 提取起始列和行
int startCol = columnLetterToIndex(start.replaceAll("\\d", "")); // A -> 0
int startRow = Integer.parseInt(start.replaceAll("[A-Z]", "")) - 1; // 3 -> 2
// 提取结束列和行
int endCol = columnLetterToIndex(end.replaceAll("\\d", "")); // Z -> 25
int endRow = Integer.parseInt(end.replaceAll("[A-Z]", "")) - 1; // 203 -> 202
return String.format("%d,%d,%d,%d", startRow, startCol, endRow, endCol);
}
```
### 使用示例
```java
// 读取表头第2行
int headerRowIndex = headerRow - 1; // 2 -> 1
String headerRange = String.format("%d,0,%d,25", headerRowIndex, headerRowIndex);
// 结果:"1,0,1,25"
// 读取数据行第3行到第203行
int startRowIndex = startRow - 1; // 3 -> 2
int endRowIndex = endRow - 1; // 203 -> 202
String dataRange = String.format("%d,0,%d,25", startRowIndex, endRowIndex);
// 结果:"2,0,202,25"
// 读取单个单元格M3
int rowIndex = 2; // 第3行 -> 索引2
int colIndex = 12; // M列 -> 索引12
String cellRange = String.format("%d,%d,%d,%d", rowIndex, colIndex, rowIndex, colIndex);
// 结果:"2,12,2,12"
```
---
## 🔍 API 调用示例
### 完整的 API URL
```
https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/{range}
```
**示例**
```
# 读取表头第2行
https://docs.qq.com/openapi/spreadsheet/v3/files/DUW50RUprWXh2TGJK/BB08J2/1,0,1,25
# 读取数据行第3行到第203行
https://docs.qq.com/openapi/spreadsheet/v3/files/DUW50RUprWXh2TGJK/BB08J2/2,0,202,25
# 读取单个单元格M3
https://docs.qq.com/openapi/spreadsheet/v3/files/DUW50RUprWXh2TGJK/BB08J2/2,12,2,12
```
---
## ⚠️ 常见错误
### 错误 1使用 Excel 格式
```
❌ https://.../ files/xxx/yyy/A3:Z203
✅ https://.../files/xxx/yyy/2,0,202,25
```
### 错误 2索引从 1 开始
```
❌ 第1行 → 索引 1
✅ 第1行 → 索引 0
❌ A列 → 索引 1
✅ A列 → 索引 0
```
### 错误 3行列顺序错误
```
❌ startColumn,startRow,endColumn,endRow
✅ startRow,startColumn,endRow,endColumn
```
正确顺序:**行在前,列在后**
---
## 📊 快速参考表
| Excel 表示 | 索引格式 | 说明 |
|-----------|---------|------|
| A1:Z1 | 0,0,0,25 | 第1行A到Z列 |
| A2:Z2 | 1,0,1,25 | 第2行A到Z列表头 |
| A3:Z203 | 2,0,202,25 | 第3行到第203行A到Z列 |
| A1:A100 | 0,0,99,0 | A列前100行 |
| M3 | 2,12,2,12 | M列第3行单个单元格 |
| A1 | 0,0,0,0 | A1单元格 |
| AA1:AZ100 | 0,26,99,51 | AA到AZ列前100行 |
---
## 🔧 修改记录
### 修改文件
1.`TencentDocApiUtil.java`
- 更新 `readSheetData` 方法的注释
- 说明 range 格式为索引格式
2.`TencentDocController.java`
- 将 range 构建从 Excel 格式改为索引格式
- 添加详细的转换日志
3.`TencentDocServiceImpl.java`
- 添加 API 错误响应检查
- 当 code != 0 时抛出异常
---
## 🎯 测试验证
### 测试参数
```json
{
"accessToken": "YOUR_ACCESS_TOKEN",
"fileId": "DUW50RUprWXh2TGJK",
"sheetId": "BB08J2",
"headerRow": 2,
"orderNoColumn": 2,
"logisticsLinkColumn": 12
}
```
### 预期日志输出
```
读取表头 - Excel行号: 2, 索引行号: 1, range: 1,0,1,25
读取数据行 - Excel行号: 3 ~ 203, 索引: 2 ~ 202, range: 2,0,202,25
```
### 成功响应
```json
{
"gridData": {
"startRow": 1,
"startColumn": 0,
"rows": [
{
"values": [
{"cellValue": {"text": "日期"}},
{"cellValue": {"text": "公司"}},
{"cellValue": {"text": "草号"}},
...
]
}
]
}
}
```
---
## 📚 参考文档
根据实际API测试结果和错误提示总结的格式规范。
**关键要点**
1. ✅ Range 使用索引格式:`startRow,startColumn,endRow,endColumn`
2. ✅ 所有索引从 0 开始
3. ✅ 顺序:行在前,列在后
4. ✅ Excel行号需要减1转换为索引
---
**文档版本**1.0
**创建时间**2025-11-05
**修改原因**:修复 "invalid param error: 'range' invalid" 错误