7.1 KiB
7.1 KiB
腾讯文档 API Range 格式说明
问题发现
在调用腾讯文档 V3 API 时,使用 Excel 格式的 range(如 A3:Z203)会返回错误:
{
"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列 → 索引 25(A=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列 → 索引 12(A=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 转换方法
/**
* 将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);
}
使用示例
// 读取表头(第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行 |
🔧 修改记录
修改文件
-
✅
TencentDocApiUtil.java- 更新
readSheetData方法的注释 - 说明 range 格式为索引格式
- 更新
-
✅
TencentDocController.java- 将 range 构建从 Excel 格式改为索引格式
- 添加详细的转换日志
-
✅
TencentDocServiceImpl.java- 添加 API 错误响应检查
- 当 code != 0 时抛出异常
🎯 测试验证
测试参数
{
"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
成功响应
{
"gridData": {
"startRow": 1,
"startColumn": 0,
"rows": [
{
"values": [
{"cellValue": {"text": "日期"}},
{"cellValue": {"text": "公司"}},
{"cellValue": {"text": "草号"}},
...
]
}
]
}
}
📚 参考文档
根据实际API测试结果和错误提示总结的格式规范。
关键要点:
- ✅ Range 使用索引格式:
startRow,startColumn,endRow,endColumn - ✅ 所有索引从 0 开始
- ✅ 顺序:行在前,列在后
- ✅ Excel行号需要减1转换为索引
文档版本:1.0
创建时间:2025-11-05
修改原因:修复 "invalid param error: 'range' invalid" 错误