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

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

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

相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7894 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~5 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
程序媛小果5 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot