Files
ruoyi-java/doc/腾讯文档API快速参考.md
2025-11-06 10:26:40 +08:00

9.0 KiB
Raw Blame History

腾讯文档 API V3 快速参考指南

API 配置

基础 URL

https://docs.qq.com/openapi/spreadsheet/v3

配置文件位置

  • 开发环境:ruoyi-admin/src/main/resources/application-dev.yml
  • 生产环境:ruoyi-admin/src/main/resources/application-prod.yml
  • Java 配置:ruoyi-system/src/main/java/com/ruoyi/jarvis/config/TencentDocConfig.java

鉴权方式

V3 API 请求头Spreadsheet 操作)

Access-Token: {access_token}
Client-Id: {app_id}
Open-Id: {open_id}
Content-Type: application/json

OAuth2 用户信息请求头

Authorization: Bearer {access_token}

主要 API 端点

1. 读取表格数据

GET /files/{fileId}/{sheetId}/{range}

示例

JSONObject result = TencentDocApiUtil.readSheetData(
    accessToken,
    appId,
    openId,
    fileId,
    sheetId,
    "A1:Z100",
    apiBaseUrl
);

2. 写入表格数据

PUT /files/{fileId}/batchUpdate

示例

Object[][] values = {
    {"姓名", "年龄", "城市"},
    {"张三", "25", "北京"}
};

JSONObject result = TencentDocApiUtil.writeSheetData(
    accessToken,
    appId,
    openId,
    fileId,
    sheetId,
    "A1",
    values,
    apiBaseUrl
);

3. 追加表格数据

自动计算位置 + PUT /files/{fileId}/batchUpdate

示例

Object[][] values = {
    {"李四", "30", "上海"}
};

JSONObject result = TencentDocApiUtil.appendSheetData(
    accessToken,
    appId,
    openId,
    fileId,
    sheetId,
    values,
    apiBaseUrl
);

4. 获取文件信息

GET /files/{fileId}

示例

JSONObject result = TencentDocApiUtil.getFileInfo(
    accessToken,
    appId,
    openId,
    fileId,
    apiBaseUrl
);

5. 获取工作表列表

GET /files/{fileId}

示例

JSONObject result = TencentDocApiUtil.getSheetList(
    accessToken,
    appId,
    openId,
    fileId,
    apiBaseUrl
);

6. 获取用户信息(含 Open-Id

GET https://docs.qq.com/oauth/v2/userinfo

示例

JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
String openId = userInfo.getString("openId");

Service 层使用示例

读取表格数据

@Autowired
private ITencentDocService tencentDocService;

public void readData() {
    String accessToken = "..."; // 从授权流程获取
    String fileId = "...";      // 表格文件ID
    String sheetId = "...";     // 工作表ID
    String range = "A1:Z100";   // 读取范围
    
    JSONObject result = tencentDocService.readSheetData(
        accessToken, fileId, sheetId, range
    );
    
    JSONArray values = result.getJSONArray("values");
    // 处理数据...
}

写入表格数据

public void writeData() {
    String accessToken = "...";
    String fileId = "...";
    String sheetId = "...";
    String range = "A1";
    
    Object[][] values = {
        {"列1", "列2", "列3"},
        {"数据1", "数据2", "数据3"}
    };
    
    JSONObject result = tencentDocService.writeSheetData(
        accessToken, fileId, sheetId, range, values
    );
}

追加订单数据

public void appendOrder(JDOrder order) {
    String accessToken = "...";
    String fileId = "...";
    String sheetId = "...";
    
    JSONObject result = tencentDocService.appendLogisticsToSheet(
        accessToken, fileId, sheetId, order
    );
}

常见参数说明

fileId文件ID

  • 从腾讯文档 URL 中获取
  • 示例 URLhttps://docs.qq.com/sheet/DQXxxxxxxxxxxxxxx?tab=BB08J2
  • fileIdDQXxxxxxxxxxxxxxx

sheetId工作表ID

  • 从腾讯文档 URL 的 tab 参数中获取
  • 示例 URLhttps://docs.qq.com/sheet/DQXxxxxxxxxxxxxxx?tab=BB08J2
  • sheetIdBB08J2

range单元格范围

  • 格式:起始列字母 + 起始行号 : 结束列字母 + 结束行号
  • 示例:
    • A1:Z100 - 从 A1 到 Z100 的矩形区域
    • A1 - 单个单元格
    • A:A - 整个 A 列
    • 1:1 - 整个第 1 行

values数据值

  • 二维数组格式
  • 示例:
// Java 数组
Object[][] values = {
    {"行1列1", "行1列2", "行1列3"},
    {"行2列1", "行2列2", "行2列3"}
};

// JSONArray
JSONArray values = new JSONArray();
JSONArray row1 = new JSONArray();
row1.add("行1列1");
row1.add("行1列2");
values.add(row1);

OAuth2 授权流程

1. 获取授权 URL

String authUrl = tencentDocService.getAuthUrl();
// 重定向用户到 authUrl 进行授权

2. 处理回调获取 Access Token

@GetMapping("/callback")
public String callback(@RequestParam String code) {
    JSONObject tokenResponse = tencentDocService.getAccessTokenByCode(code);
    String accessToken = tokenResponse.getString("access_token");
    String refreshToken = tokenResponse.getString("refresh_token");
    Integer expiresIn = tokenResponse.getInteger("expires_in");
    
    // 保存 tokens...
    return "授权成功";
}

3. 刷新 Access Token

public void refreshToken(String refreshToken) {
    JSONObject tokenResponse = tencentDocService.refreshAccessToken(refreshToken);
    String newAccessToken = tokenResponse.getString("access_token");
    String newRefreshToken = tokenResponse.getString("refresh_token");
    
    // 更新保存的 tokens...
}

错误处理

常见错误码

401 Unauthorized

  • 原因Access Token 无效或过期
  • 解决:使用 Refresh Token 刷新 Access Token

403 Forbidden

  • 原因:用户没有访问该文档的权限
  • 解决:检查文档权限设置,确保授权用户有访问权限

404 Not Found

  • 原因文件ID或工作表ID不存在或 API 路径错误
  • 解决
    1. 检查 fileId 和 sheetId 是否正确
    2. 检查 API 基础路径配置是否为 https://docs.qq.com/openapi/spreadsheet/v3

429 Too Many Requests

  • 原因API 调用频率超过限制
  • 解决:实现请求限流和重试机制

异常捕获示例

try {
    JSONObject result = tencentDocService.readSheetData(
        accessToken, fileId, sheetId, range
    );
} catch (RuntimeException e) {
    if (e.getMessage().contains("401")) {
        // Token 过期,刷新 token
        refreshToken(savedRefreshToken);
    } else if (e.getMessage().contains("404")) {
        // 文件不存在
        log.error("文件不存在: fileId={}", fileId);
    } else if (e.getMessage().contains("无法获取Open-Id")) {
        // Access Token 无效
        log.error("Access Token 无效,需要重新授权");
    } else {
        // 其他错误
        log.error("API调用失败", e);
    }
}

性能优化建议

1. Open-Id 缓存

当前实现在每次调用 API 前都会获取 Open-Id建议添加缓存

// 使用 Spring Cache
@Cacheable(value = "openIdCache", key = "#accessToken")
public String getOpenId(String accessToken) {
    JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
    return userInfo.getString("openId");
}

2. Access Token 缓存和自动刷新

// 在数据库或 Redis 中存储 token 及过期时间
public String getValidAccessToken(String userId) {
    TokenInfo tokenInfo = tokenRepository.findByUserId(userId);
    
    if (tokenInfo.isExpired()) {
        // 自动刷新
        JSONObject newTokens = tencentDocService.refreshAccessToken(
            tokenInfo.getRefreshToken()
        );
        tokenInfo.update(newTokens);
        tokenRepository.save(tokenInfo);
    }
    
    return tokenInfo.getAccessToken();
}

3. 批量操作

对于多次写入,优先使用 batchUpdate API 一次性提交多个操作。

调试技巧

1. 启用详细日志

application-dev.yml 中设置:

logging:
  level:
    com.ruoyi.jarvis.util.TencentDocApiUtil: DEBUG
    com.ruoyi.jarvis.service.impl.TencentDocServiceImpl: DEBUG

2. 查看完整请求和响应

TencentDocApiUtil 已包含详细的日志记录:

  • 请求 URL
  • 请求方法
  • 请求体
  • 响应状态码
  • 响应内容

3. 测试 API 连接

@Test
public void testConnection() {
    String accessToken = "your_test_token";
    
    // 1. 测试获取用户信息
    JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
    System.out.println("User Info: " + userInfo);
    
    // 2. 测试获取文件信息
    String fileId = "your_test_file_id";
    JSONObject fileInfo = tencentDocService.getFileInfo(accessToken, fileId);
    System.out.println("File Info: " + fileInfo);
}

官方文档链接

技术支持

如遇到问题,请查看:

  1. 项目文档目录下的 腾讯文档API完整修复总结.md
  2. 项目日志文件(位于 logs/ 目录)
  3. 腾讯文档开放平台官方文档

最后更新时间2025-11-05