diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java index 56218c6..07ce9e0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java @@ -6,6 +6,7 @@ import com.ruoyi.jarvis.config.TencentDocConfig; import com.ruoyi.jarvis.domain.JDOrder; import com.ruoyi.jarvis.service.ITencentDocService; import com.ruoyi.jarvis.util.TencentDocApiUtil; +import com.ruoyi.jarvis.util.TencentDocDataParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -260,8 +261,21 @@ public class TencentDocServiceImpl implements ITencentDocService { tencentDocConfig.getApiBaseUrl() ); - log.info("API调用成功,返回结果: {}", result != null ? result.toJSONString() : "null"); - return result; + log.info("API调用成功,原始返回结果: {}", result != null ? result.toJSONString() : "null"); + + // 解析数据为统一的简单格式 + JSONArray parsedValues = TencentDocDataParser.parseToSimpleArray(result); + log.info("解析后的数据行数: {}", parsedValues != null ? parsedValues.size() : 0); + if (parsedValues != null && !parsedValues.isEmpty()) { + TencentDocDataParser.printDataStructure(result, 3); + } + + // 返回包含简化格式的响应 + JSONObject response = new JSONObject(); + response.put("values", parsedValues); + response.put("_原始数据", result); // 保留原始数据供调试 + + return response; } catch (Exception e) { log.error("读取表格数据失败 - fileId: {}, sheetId: {}, range: {}", fileId, sheetId, range, e); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/util/TencentDocDataParser.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/util/TencentDocDataParser.java new file mode 100644 index 0000000..0cb1699 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/util/TencentDocDataParser.java @@ -0,0 +1,167 @@ +package com.ruoyi.jarvis.util; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 腾讯文档数据解析工具类 + * 用于解析腾讯文档 V3 API 返回的复杂数据格式 + * + * @author system + */ +public class TencentDocDataParser { + + private static final Logger log = LoggerFactory.getLogger(TencentDocDataParser.class); + + /** + * 解析腾讯文档 V3 API 返回的数据为简单的二维数组格式 + * + * @param apiResponse API响应(可能包含 gridData 或 values 字段) + * @return 二维数组格式的数据,每行是一个JSONArray + */ + public static JSONArray parseToSimpleArray(JSONObject apiResponse) { + if (apiResponse == null) { + return new JSONArray(); + } + + // 方式1:检查是否有 gridData 字段(V3 API 新格式) + JSONObject gridData = apiResponse.getJSONObject("gridData"); + if (gridData != null) { + return parseGridData(gridData); + } + + // 方式2:检查是否有 values 字段(简单格式) + JSONArray values = apiResponse.getJSONArray("values"); + if (values != null) { + return values; + } + + // 如果都没有,返回空数组 + log.warn("API响应中既没有 gridData 也没有 values 字段,返回空数组"); + return new JSONArray(); + } + + /** + * 解析 gridData 格式的数据 + * + * @param gridData gridData 对象 + * @return 二维数组格式的数据 + */ + private static JSONArray parseGridData(JSONObject gridData) { + JSONArray result = new JSONArray(); + + // 获取 rows 数组 + JSONArray rows = gridData.getJSONArray("rows"); + if (rows == null || rows.isEmpty()) { + log.debug("gridData.rows 为空"); + return result; + } + + // 遍历每一行 + for (int i = 0; i < rows.size(); i++) { + JSONObject row = rows.getJSONObject(i); + if (row == null) { + continue; + } + + // 获取这一行的 values 数组 + JSONArray cellValues = row.getJSONArray("values"); + if (cellValues == null) { + continue; + } + + // 解析每个单元格 + JSONArray rowData = new JSONArray(); + for (int j = 0; j < cellValues.size(); j++) { + JSONObject cell = cellValues.getJSONObject(j); + String cellText = extractCellText(cell); + rowData.add(cellText); + } + + result.add(rowData); + } + + log.debug("成功解析 gridData,共 {} 行", result.size()); + return result; + } + + /** + * 从单元格对象中提取文本内容 + * + * @param cell 单元格对象 + * @return 文本内容(如果没有则返回空字符串) + */ + private static String extractCellText(JSONObject cell) { + if (cell == null) { + return ""; + } + + // 获取 cellValue + JSONObject cellValue = cell.getJSONObject("cellValue"); + if (cellValue == null) { + return ""; + } + + // 获取 text 字段 + String text = cellValue.getString("text"); + return text != null ? text : ""; + } + + /** + * 获取指定行的数据 + * + * @param apiResponse API响应 + * @param rowIndex 行索引(从0开始) + * @return 该行的数据数组,如果行不存在则返回 null + */ + public static JSONArray getRow(JSONObject apiResponse, int rowIndex) { + JSONArray allRows = parseToSimpleArray(apiResponse); + if (allRows == null || rowIndex < 0 || rowIndex >= allRows.size()) { + return null; + } + return allRows.getJSONArray(rowIndex); + } + + /** + * 获取指定单元格的文本内容 + * + * @param apiResponse API响应 + * @param rowIndex 行索引(从0开始) + * @param colIndex 列索引(从0开始) + * @return 单元格文本内容,如果不存在则返回 null + */ + public static String getCellText(JSONObject apiResponse, int rowIndex, int colIndex) { + JSONArray row = getRow(apiResponse, rowIndex); + if (row == null || colIndex < 0 || colIndex >= row.size()) { + return null; + } + return row.getString(colIndex); + } + + /** + * 打印数据结构(用于调试) + * + * @param apiResponse API响应 + * @param maxRows 最多打印多少行(0表示全部) + */ + public static void printDataStructure(JSONObject apiResponse, int maxRows) { + JSONArray rows = parseToSimpleArray(apiResponse); + if (rows == null || rows.isEmpty()) { + log.info("数据为空"); + return; + } + + int rowsToPrint = (maxRows > 0 && maxRows < rows.size()) ? maxRows : rows.size(); + log.info("数据结构(共 {} 行,显示前 {} 行):", rows.size(), rowsToPrint); + + for (int i = 0; i < rowsToPrint; i++) { + JSONArray row = rows.getJSONArray(i); + if (row != null) { + log.info(" 第 {} 行({}列): {}", i + 1, row.size(), row.toJSONString()); + } + } + } +} +