diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java index 1356c839b2..d63d32694a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaWeDocService.java @@ -78,4 +78,53 @@ public interface WxCpOaWeDocService { * @throws WxErrorException the wx error exception */ WxCpDocShare docShare(@NonNull String docId) throws WxErrorException; + + /** + * 编辑表格内容 + * 该接口可以对一个在线表格批量执行多个更新操作 + *

+ * 注意: + * 1.批量更新请求中的各个操作会逐个按顺序执行,直到全部执行完成则请求返回,或者其中一个操作报错则不再继续执行后续的操作 + * 2.每一个更新操作在执行之前都会做请求校验(包括权限校验、参数校验等等),如果校验未通过则该更新操作会报错并返回,不再执行后续操作 + * 3.单次批量更新请求的操作数量 <= 5 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/batch_update?access_token=ACCESS_TOKEN + * + * @param request 编辑表格内容请求参数 + * @return 编辑表格内容批量更新的响应结果 + * @throws WxErrorException the wx error exception + */ + WxCpDocSheetBatchUpdateResponse docBatchUpdate(@NonNull WxCpDocSheetBatchUpdateRequest request) throws WxErrorException; + + /** + * 获取表格行列信息 + * 该接口用于获取在线表格的工作表、行数、列数等。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/get_sheet_properties?access_token=ACCESS_TOKEN + * + * @param docId 在线表格的docid + * @return 返回表格行列信息 + * @throws WxErrorException + */ + WxCpDocSheetProperties getSheetProperties(@NonNull String docId) throws WxErrorException; + + + /** + * 本接口用于获取指定范围内的在线表格信息,单次查询的范围大小需满足以下限制: + *

+ * 查询范围行数 <=1000 + * 查询范围列数 <=200 + * 范围内的总单元格数量 <=10000 + *

+ * 请求方式:POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/wedoc/spreadsheet/get_sheet_range_data?access_token=ACCESS_TOKEN + * + * @param request 获取指定范围内的在线表格信息请求参数 + * @return 返回指定范围内的在线表格信息 + * @throws WxErrorException + */ + WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest request) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java index 81de32453d..fc5379dc73 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaWeDocServiceImpl.java @@ -63,4 +63,27 @@ public WxCpDocShare docShare(@NonNull String docId) throws WxErrorException { String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); return WxCpDocShare.fromJson(responseContent); } + + @Override + public WxCpDocSheetBatchUpdateResponse docBatchUpdate(@NonNull WxCpDocSheetBatchUpdateRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_BATCH_UPDATE); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSheetBatchUpdateResponse.fromJson(responseContent); + } + + @Override + public WxCpDocSheetProperties getSheetProperties(@NonNull String docId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("docid", docId); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpDocSheetProperties.fromJson(responseContent); + } + + @Override + public WxCpDocSheetData getSheetRangeData(@NonNull WxCpDocSheetGetDataRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpDocSheetData.fromJson(responseContent); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java new file mode 100644 index 0000000000..37c42717e7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateRequest.java @@ -0,0 +1,199 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.bean.oa.doc.WxCpDocSheetData.GridData; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 编辑表格内容请求 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSheetBatchUpdateRequest implements Serializable { + private static final long serialVersionUID = 584565591133421347L; + + /** + * 文档的docid.必填 + */ + @SerializedName("docid") + private String docId; + + /** + * 更新操作列表.必填 + */ + @SerializedName("requests") + private List requests; + + /** + * From json wx cp doc sheet batch update request. + * + * @param json the json + * @return the wx cp doc sheet batch update request + */ + public static WxCpDocSheetBatchUpdateRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetBatchUpdateRequest.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 更新操作 + */ + @Getter + @Setter + public static class Request implements Serializable { + private static final long serialVersionUID = 253933038745894628L; + + /** + * 新增工作表 + */ + @SerializedName("add_sheet_request") + private AddSheetRequest addSheetRequest; + + /** + * 删除工作表请求 + */ + @SerializedName("delete_sheet_request") + private DeleteSheetRequest deleteSheetRequest; + + /** + * 更新范围内单元格内容 + */ + @SerializedName("update_range_request") + private UpdateRangeRequest updateRangeRequest; + + /** + * 删除表格连续的行或列 + */ + @SerializedName("delete_dimension_request") + private DeleteDimensionRequest deleteDimensionRequest; + + /** + * 新增工作表,新增需满足以下限制 + * 范围列数 <=200 + * 范围内的总单元格数量 <=10000 + */ + @Getter + @Setter + public static class AddSheetRequest implements Serializable { + private static final long serialVersionUID = 523704967699486288L; + + /** + * 工作表名称 + */ + @SerializedName("title") + private String title; + + /** + * 新增工作表的初始行数 + */ + @SerializedName("row_count") + private int rowCount; + + /** + * 新增工作表的初始列数 + */ + @SerializedName("column_count") + private int columnCount; + } + + /** + * 删除工作表请求 + */ + @Getter + @Setter + public static class DeleteSheetRequest implements Serializable { + private static final long serialVersionUID = 767974765396168274L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + } + + /** + * 更新范围内单元格内容 + */ + @Getter + @Setter + public static class UpdateRangeRequest implements Serializable { + private static final long serialVersionUID = 433859595039061888L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 表格数据 + */ + @SerializedName("grid_data") + private GridData gridData; + } + + /** + * 删除表格连续的行或列 + * 注意: + * 1.该操作会导致表格缩表 + * 2.删除的范围遵循 左闭右开 ———— [start_index,end_index) ,如果 end_index <= start_index + * 则该请求报错。 + */ + @Getter + @Setter + public static class DeleteDimensionRequest implements Serializable { + private static final long serialVersionUID = 107245521502978033L; + + /** + * 工作表唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 删除的维度类型. + * ROW:行 + * COLUMN:列 + */ + @SerializedName("dimension") + private String dimension; + + /** + * 删除行列的起始序号(从1开始) + */ + @SerializedName("start_index") + private int startIndex; + + /** + * 删除行列的终止序号(从1开始) + */ + @SerializedName("end_index") + private int endIndex; + } + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java new file mode 100644 index 0000000000..8e31e9022f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetBatchUpdateResponse.java @@ -0,0 +1,126 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.oa.doc.WxCpDocSheetProperties.Properties; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 更新操作(UpdateRequest])对应的响应结构体类型 + * + * @author zhongying + * @since 2026-01-08 + */ +@Data +public class WxCpDocSheetBatchUpdateResponse implements Serializable { + private static final long serialVersionUID = 781694717017131015L; + + /** + * 新增工作表响应 + */ + @SerializedName("add_sheet_response") + private AddSheetResponse addSheetResponse; + + /** + * 删除工作表响应 + */ + @SerializedName("delete_sheet_response") + private DeleteSheetResponse deleteSheetResponse; + + /** + * 更新范围内单元格内容响应 + */ + @SerializedName("update_range_response") + private UpdateRangeResponse updateRangeResponse; + + /** + * 删除表格连续的行或列响应 + */ + @SerializedName("delete_dimension_response") + private DeleteDimensionResponse deleteDimensionResponse; + + /** + * 从 JSON 字符串反序列化为 WxCpDocSheetBatchUpdateResponse 对象。 + * + * @param json the json + * @return 反序列化得到的 WxCpDocSheetBatchUpdateResponse 对象 + */ + public static WxCpDocSheetBatchUpdateResponse fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetBatchUpdateResponse.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 新增工作表响应 + */ + @Getter + @Setter + public static class AddSheetResponse implements Serializable { + private static final long serialVersionUID = 618814209485621336L; + + /** + * 新增子表的属性 + */ + @SerializedName("properties") + private Properties properties; + } + + /** + * 删除工作表响应 + */ + @Getter + @Setter + public static class DeleteSheetResponse implements Serializable { + private static final long serialVersionUID = 625927337093938411L; + + /** + * 被删除的工作表的唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + } + + /** + * 更新范围内单元格内容响应 + */ + @Getter + @Setter + public static class UpdateRangeResponse implements Serializable { + private static final long serialVersionUID = 180842641209787414L; + + /** + * 数据更新的成功的单元格数量 + */ + @SerializedName("updated_cells") + private int updatedCells; + } + + /** + * 删除表格连续的行(或列),请求响应体结构 + */ + @Getter + @Setter + public static class DeleteDimensionResponse implements Serializable { + private static final long serialVersionUID = 107245521502978033L; + + /** + * 被删除的行数(或列数) + */ + @SerializedName("deleted") + private int deleted; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java new file mode 100644 index 0000000000..15e76430b7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetData.java @@ -0,0 +1,260 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格数据 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +public class WxCpDocSheetData extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 498054945993671723L; + + /** + * 返回data + */ + @SerializedName("grid_data") + private GridData gridData; + + /** + * From json sheet data. + * + * @param json the json + * @return the sheet data + */ + public static WxCpDocSheetData fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetData.class); + } + + /** + * To json string. + * + * @return the string + */ + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 表格数据 + */ + @Getter + @Setter + public static class GridData implements Serializable { + private static final long serialVersionUID = 389887488098521821L; + + /** + * 起始行编号 (从0开始计算) + */ + @SerializedName("start_row") + private int startRow; + + /** + * 起始列编号 (从0开始计算) + */ + @SerializedName("start_column") + private int startColumn; + + /** + * 各行的数据 + */ + @SerializedName("rows") + private List rows; + + /** + * 行数据 + */ + @Getter + @Setter + public static class RowData implements Serializable { + private static final long serialVersionUID = 225648868492722337L; + + /** + * 各个单元格的数据内容 + */ + @SerializedName("values") + private List values; + + /** + * 单元格的信息 + */ + @Getter + @Setter + public static class CellData implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 单元格的数据内容 + */ + @SerializedName("cell_value") + private CellValue cellValue; + + /** + * 单元格的样式信息 + */ + @SerializedName("cell_format") + private CellFormat cellFormat; + + /** + * 单元格的数据内容,暂时只支持文本、链接,一个CellValue中只能选填一个字段 + */ + @Getter + @Setter + public static class CellValue implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 文本 + */ + @SerializedName("text") + private String text; + + /** + * 链接 + */ + @SerializedName("link") + private Link link; + + /** + * 链接 + */ + @Getter + @Setter + public static class Link implements Serializable { + private static final long serialVersionUID = 912896452879347178L; + + /** + * 链接url + */ + @SerializedName("url") + private String url; + + /** + * 链接标题 + */ + @SerializedName("text") + private String text; + } + } + + /** + * 单元格的样式信息 + */ + @Getter + @Setter + public static class CellFormat implements Serializable { + private static final long serialVersionUID = 656471192719707304L; + + /** + * 文字样式 + */ + + @SerializedName("text_format") + private TextFormat textFormat; + + /** + * 文字样式 + */ + @Getter + @Setter + public static class TextFormat implements Serializable { + private static final long serialVersionUID = 184358104921122206L; + + /** + * 字体 + */ + @SerializedName("font") + private String font; + + /** + * 字体大小,最大72 + */ + @SerializedName("font_size") + private int fontSize; + + /** + * 字体加粗 + */ + @SerializedName("bold") + private boolean bold; + + /** + * 斜体 + */ + @SerializedName("italic") + private boolean italic; + + /** + * 字体删除线 + */ + @SerializedName("strikethrough") + private boolean strikethrough; + + /** + * 字体下划线 + */ + @SerializedName("underline") + private boolean underline; + + /** + * 字体颜色 + */ + @SerializedName("color") + private Color color; + + /** + * 字体颜色 + */ + @Getter + @Setter + public static class Color implements Serializable { + private static final long serialVersionUID = 140418085882147315L; + + /** + * 红色,取值范围:[0,255] + */ + @SerializedName("red") + private int red; + + /** + * 绿色,取值范围:[0,255] + */ + @SerializedName("green") + private int green; + + /** + * 蓝色,取值范围:[0,255] + */ + @SerializedName("blue") + private int blue; + + /** + * alpha通道,取值范围:[0,255],默认值为255完全不透明 + */ + @SerializedName("alpha") + private int alpha; + + } + + } + } + + } + + } + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java new file mode 100644 index 0000000000..df2907aa31 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetGetDataRequest.java @@ -0,0 +1,64 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格数据请求 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpDocSheetGetDataRequest implements Serializable { + private static final long serialVersionUID = 827718590347822812L; + + /** + * 在线表格唯一标识.必填 + */ + @SerializedName("docid") + private String docId; + + /** + * 工作表ID,工作表的唯一标识.必填 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 查询的范围,格式为"A1:B2",表示获取A1到B2单元格的数据.必填 + */ + @SerializedName("range") + private String range; + + /** + * From json to {@link WxCpDocSheetGetDataRequest}. + * + * @param json the json string representing {@link WxCpDocSheetGetDataRequest} + * @return the {@link WxCpDocSheetGetDataRequest} object + */ + public static WxCpDocSheetGetDataRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetGetDataRequest.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java new file mode 100644 index 0000000000..6e67965fe0 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/doc/WxCpDocSheetProperties.java @@ -0,0 +1,79 @@ +package me.chanjar.weixin.cp.bean.oa.doc; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 获取表格行列信息 + * + * @author zhongying + * @since 2026-01-07 + */ +@Data +public class WxCpDocSheetProperties extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = 666707252457243065L; + + @SerializedName("properties") + private List properties; + + /** + * From json sheet properties. + * + * @param json the json + * @return the sheet properties + */ + public static WxCpDocSheetProperties fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpDocSheetProperties.class); + } + + /** + * To json string. + * + * @return the string + */ + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 工作表属性 + */ + @Getter + @Setter + public static class Properties implements Serializable { + private static final long serialVersionUID = 640301090538839892L; + + /** + * 工作表ID,工作表的唯一标识 + */ + @SerializedName("sheet_id") + private String sheetId; + + /** + * 工作表名称 + */ + @SerializedName("title") + private String title; + + /** + * 表格的总行数 + */ + @SerializedName("row_count") + private int rowCount; + + /** + * 表格的总列数 + */ + @SerializedName("column_count") + private int columnCount; + + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index ade813ef5c..82bb811b3c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -575,6 +575,21 @@ interface Oa { */ String WEDOC_DOC_SHARE = "/cgi-bin/wedoc/doc_share"; + /** + * The constant WEDOC_SPREADSHEET_BATCH_UPDATE. + */ + String WEDOC_SPREADSHEET_BATCH_UPDATE = "/cgi-bin/wedoc/spreadsheet/batch_update"; + + /** + * The constant WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES. + */ + String WEDOC_SPREADSHEET_GET_SHEET_PROPERTIES = "/cgi-bin/wedoc/spreadsheet/get_sheet_properties"; + + /** + * The constant WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA. + */ + String WEDOC_SPREADSHEET_GET_SHEET_RANGE_DATA = "/cgi-bin/wedoc/spreadsheet/get_sheet_range_data"; + /** * 邮件 * https://developer.work.weixin.qq.com/document/path/95486