1
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.jarvis.util;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -365,20 +366,114 @@ public class TencentDocApiUtil {
|
||||
* @return 写入结果
|
||||
*/
|
||||
public static JSONObject writeSheetData(String accessToken, String appId, String openId, String fileId, String sheetId, String range, Object values, String apiBaseUrl) {
|
||||
// V3版本API路径格式:/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/{range}
|
||||
String apiUrl = String.format("%s/files/%s/%s/%s", apiBaseUrl, fileId, sheetId, range);
|
||||
// 腾讯文档 V3 API 没有直接的 PUT 写入接口
|
||||
// 必须使用 batchUpdate 接口:https://docs.qq.com/open/document/app/openapi/v3/sheet/batchupdate/update.html
|
||||
|
||||
// 构建V3 API规范的请求体
|
||||
// 根据腾讯文档V3 API文档(https://docs.qq.com/open/document/app/openapi/v3/sheet/model/spreadsheet.html)
|
||||
// 对于简单的文本数据写入,可以直接使用values二维数组
|
||||
// 对于复杂的单元格数据(包含格式、类型等),需要使用完整的CellData结构
|
||||
// 解析 A1 表示法,转换为行列索引
|
||||
// 例如:"M3" -> row=2 (索引从0开始), col=12
|
||||
int[] position = parseA1Notation(range);
|
||||
int rowIndex = position[0];
|
||||
int colIndex = position[1];
|
||||
|
||||
// 构建 updateCells 请求
|
||||
JSONObject updateCells = new JSONObject();
|
||||
|
||||
// 设置范围
|
||||
JSONObject rangeObj = new JSONObject();
|
||||
rangeObj.put("sheetId", sheetId);
|
||||
rangeObj.put("startRowIndex", rowIndex);
|
||||
rangeObj.put("endRowIndex", rowIndex + 1); // 不包含
|
||||
rangeObj.put("startColumnIndex", colIndex);
|
||||
rangeObj.put("endColumnIndex", colIndex + 1); // 不包含
|
||||
updateCells.put("range", rangeObj);
|
||||
|
||||
// 构建单元格数据
|
||||
JSONArray rows = new JSONArray();
|
||||
JSONObject rowData = new JSONObject();
|
||||
JSONArray cellValues = new JSONArray();
|
||||
|
||||
// 如果 values 是二维数组
|
||||
if (values instanceof JSONArray) {
|
||||
JSONArray valuesArray = (JSONArray) values;
|
||||
if (!valuesArray.isEmpty() && valuesArray.get(0) instanceof JSONArray) {
|
||||
JSONArray firstRow = valuesArray.getJSONArray(0);
|
||||
if (!firstRow.isEmpty()) {
|
||||
String text = firstRow.getString(0);
|
||||
JSONObject cellData = new JSONObject();
|
||||
JSONObject cellValue = new JSONObject();
|
||||
cellValue.put("text", text);
|
||||
cellData.put("cellValue", cellValue);
|
||||
cellValues.add(cellData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowData.put("values", cellValues);
|
||||
rows.add(rowData);
|
||||
updateCells.put("rows", rows);
|
||||
|
||||
// 构建 requests
|
||||
JSONArray requests = new JSONArray();
|
||||
JSONObject request = new JSONObject();
|
||||
request.put("updateCells", updateCells);
|
||||
requests.add(request);
|
||||
|
||||
// 构建完整请求体
|
||||
JSONObject requestBody = new JSONObject();
|
||||
requestBody.put("values", values);
|
||||
requestBody.put("requests", requests);
|
||||
|
||||
log.info("写入表格数据 - fileId: {}, sheetId: {}, range: {}, apiUrl: {}", fileId, sheetId, range, apiUrl);
|
||||
// 调用 batchUpdate API
|
||||
String apiUrl = String.format("%s/files/%s/batchUpdate", apiBaseUrl, fileId);
|
||||
|
||||
log.info("写入表格数据(batchUpdate)- fileId: {}, sheetId: {}, range: {}, rowIndex: {}, colIndex: {}",
|
||||
fileId, sheetId, range, rowIndex, colIndex);
|
||||
log.debug("写入表格数据 - 请求体: {}", requestBody.toJSONString());
|
||||
|
||||
return callApi(accessToken, appId, openId, apiUrl, "PUT", requestBody.toJSONString());
|
||||
return callApi(accessToken, appId, openId, apiUrl, "POST", requestBody.toJSONString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 A1 表示法为行列索引
|
||||
* 例如:
|
||||
* A1 -> [0, 0]
|
||||
* M3 -> [2, 12]
|
||||
* Z100 -> [99, 25]
|
||||
*
|
||||
* @param a1Notation A1 表示法字符串
|
||||
* @return [rowIndex, colIndex](从0开始)
|
||||
*/
|
||||
private static int[] parseA1Notation(String a1Notation) {
|
||||
if (a1Notation == null || a1Notation.isEmpty()) {
|
||||
throw new IllegalArgumentException("A1 表示法不能为空");
|
||||
}
|
||||
|
||||
// 提取列字母和行号
|
||||
StringBuilder colLetters = new StringBuilder();
|
||||
StringBuilder rowNumber = new StringBuilder();
|
||||
|
||||
for (char c : a1Notation.toCharArray()) {
|
||||
if (Character.isLetter(c)) {
|
||||
colLetters.append(Character.toUpperCase(c));
|
||||
} else if (Character.isDigit(c)) {
|
||||
rowNumber.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (colLetters.length() == 0 || rowNumber.length() == 0) {
|
||||
throw new IllegalArgumentException("无效的 A1 表示法: " + a1Notation);
|
||||
}
|
||||
|
||||
// 列字母转索引(A=0, B=1, ..., Z=25, AA=26, ...)
|
||||
int colIndex = 0;
|
||||
for (int i = 0; i < colLetters.length(); i++) {
|
||||
colIndex = colIndex * 26 + (colLetters.charAt(i) - 'A' + 1);
|
||||
}
|
||||
colIndex -= 1; // 转为从0开始的索引
|
||||
|
||||
// 行号转索引(1->0, 2->1, ...)
|
||||
int rowIndex = Integer.parseInt(rowNumber.toString()) - 1;
|
||||
|
||||
return new int[]{rowIndex, colIndex};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user