Java调用飞书api, 读取公式,合并单元格问题?

项目场景:

需要读取飞书云文档的电子表格,但是表格有公式计算的值,以及合并单元格。

问题显示:调用api可以读取表格。1.公式不自动计算,直接返回公式。2.读取合并的单元格,只有第一行有数据,其余合并的无数据。

直接看读取表格的代码:

java 复制代码
public SpreadsheetData getSheet(String token, String sheetId) {  
// 发起请求  
try {  
String url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/" + token + "/values_batch_get?ranges=" + sheetId;  
RawResponse resp = client.get(url, null, AccessTokenType.Tenant);  
if (resp.getStatusCode() == 200) {  
//LarkResult<SpreadsheetData>用来封装api响应体
Type type = new TypeToken<LarkResult<SpreadsheetData>>() {}.getType(); 
LarkResult<SpreadsheetData> result = Jsons.DEFAULT.fromJson(new String(resp.getBody()), type);  
return result.getData();  
}  
throw new AIGCBusinessExceptions(ResultCodeEnum.HTTP_REQUEST_FAILED.getCode(), Arrays.toString(resp.getBody()));  
} catch (Exception e) {  
throw new AIGCBusinessExceptions(Result.HTTP_REQUEST_FAILED.getCode(), "读取电子表格报错" + e.getMessage());  
}  
}

打断点看一下api返回的东西:

重点对比一下第三行和四五行的数据,因为从第三行开始合并的单元格以及公式计算

现在需要解决这两个问题:

1.显示数据,不显示公式。

2.合并的单元格也要显示数据

问题1:公式计算

飞书api官方文档

读取多个范围 - 服务端 API - 开发文档 - 飞书开放平台 (feishu.cn) 根据项目需求,我调用的是这个api。这个问题好解决,加一个查询参数valueRenderOption=FormattedValue 计算并格式化单元格;

java 复制代码
String url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/" + token + "/values_batch_get?ranges=" + sheetId+"&valueRenderOption=FormattedValue";

okk, 公式计算的问题解决了,现在显示结果了。下次要认真阅读api文档,官方文档写了.....查询参数那列valueRenderOption

问题2:读取合并单元格

这个问题官方文档好像是没写,翻阅了官方文档没找到。需求在那也只能硬着头皮写了。 以下是我自己的方法,感觉不是很好用,有大佬知道这个问题请多多指教。

1.调用api查询出表合并单元格的相关信息

查询工作表 - 服务端 API - 开发文档 - 飞书开放平台 (feishu.cn) 响应体中的merges会返回表合并单元格的相关信息。

java 复制代码
public List<Merges> getSheetDetail(String token, String sheetId){  
try {  
    String substring = sheetId.substring(0, sheetId.indexOf('!'));  
    String url="https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/"+ token +"/sheets/"+substring;  
    RawResponse resp = client.get(url, null, AccessTokenType.Tenant);  
    if (resp.getStatusCode() == 200) {  
        Type type = new TypeToken<LarkResult<Spreadsheet>>() {}.getType();  
        LarkResult<Spreadsheet> result = Jsons.DEFAULT.fromJson(new String(resp.getBody()), type);  
        Spreadsheet spreadsheet = result.getData();  
        List<Merges> merges = spreadsheet.getSheet().getMerges();  
        return merges;  
}  
    throw new AIGCBusinessExceptions(ResultCodeEnum.HTTP_REQUEST_FAILED.getCode(), Arrays.toString(resp.getBody()));  
} catch (Exception e) {  
    throw new AIGCBusinessExceptions(Result.HTTP_REQUEST_FAILED.getCode(), "读取电子表格报错" + e.getMessage());  
}  
}

注意:这里返回的行列index都是,第n行列-1。start_row_index=2实际上是第三行

2.给合并单元格赋值

现在只取游戏图那一列合并单元格的数据

java 复制代码
/**
* spreadsheetData 表数据
* mergesList 合并单元格的信息
*/

public void mergeCell(SpreadsheetData spreadsheetData,List<Merges> mergesList){  
    //获取游戏图所在的列,get(0)是表头
    SpreadsheetData.ValueRange head = spreadsheetData.getValueRanges().get(0);  
    List<List<Object>> headValues = head.getValues();  
    List<Object> headObjects = headValues.get(0);  
    Integer index=0;  
    for (int i = 0; i < headObjects.size(); i++) {  
        if (headObjects.get(i).equals("游戏图")){  
            index=i;  
            break;  
        }  
    }  
    //取合并单元格的行号
    List<Integer> indexList=new ArrayList<>();  
    for (Merges merges : mergesList) {  
        if (merges.getStart_column_index().equals(index) && merges.getEnd_column_index().equals(index)){  
            Integer startRowIndex = merges.getStart_row_index();  
            Integer endRowIndex = merges.getEnd_row_index();  
            for (int i=startRowIndex;i<=endRowIndex;i++){  
                indexList.add(i);  
            }  
         }  
    }  
    //get(1)取表内的数据
    SpreadsheetData.ValueRange valueRange = spreadsheetData.getValueRanges().get(1);  
    String range = valueRange.getRange();  
    //取开始行号 ,计算每行数据在表格内的行号,与indexList进行对比
    int startRow = Integer.parseInt(range.substring(range.indexOf('!') + 2, range.indexOf(':')));  
    List<List<Object>> values = valueRange.getValues();  
    Object temp=null;  
    for (int i = 0; i < values.size(); i++) {  
        Object o = values.get(i).get(index);  
        if (o!=null){  
            temp= o;  
        }  
        if (o ==null && indexList.contains(i+startRow-1) ){  
            values.get(i).set(index,temp);  
        }  
    }  
}

3.最后

java 复制代码
public SpreadsheetData getSheet(String token, String sheetId) {  
// 发起请求  
try {  
String url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/" + token + "/values_batch_get?ranges=" + sheetId+"&valueRenderOption=FormattedValue";  
RawResponse resp = client.get(url, null, AccessTokenType.Tenant);  
if (resp.getStatusCode() == 200) {  
Type type = new TypeToken<LarkResult<SpreadsheetData>>() {}.getType();  
LarkResult<SpreadsheetData> result = Jsons.DEFAULT.fromJson(new String(resp.getBody()), type);  
SpreadsheetData spreadsheetData = result.getData();  
//获取合并的单元格,下标从0开始  
List<Merges> mergesList = getSheetDetail(token, sheetId);  
mergeCell(spreadsheetData,mergesList);  
return result.getData();  
}  
throw new AIGCBusinessExceptions(ResultCodeEnum.HTTP_REQUEST_FAILED.getCode(), Arrays.toString(resp.getBody()));  
} catch (Exception e) {  
throw new AIGCBusinessExceptions(Result.HTTP_REQUEST_FAILED.getCode(), "读取电子表格报错" + e.getMessage());  
}  
  
}

结果:"游戏图"那列的合并单元格,不止第三行,第四五行都有了数据。

最后:如果有大佬有更好的方法,请多多指教

相关推荐
Yan.love40 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶44 分钟前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥44 分钟前
java提高正则处理效率
java·开发语言
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm101342 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob2 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13142 小时前
常用的缓存技术都有哪些
java
AiFlutter3 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A3 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea