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());  
}  
  
}

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

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

相关推荐
vx_BS8133015 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683615 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
达文汐43 分钟前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜44 分钟前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软1 小时前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋1 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怪兽源码2 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite2 小时前
Redis之配置只读账号
java·redis·bootstrap
梦里小白龙2 小时前
java 通过Minio上传文件
java·开发语言
人道领域2 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql