Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
Y
yifu-mvp
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fangxinjiang
yifu-mvp
Commits
412436e5
Commit
412436e5
authored
Oct 09, 2025
by
fangxinjiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
企微智能表格开发(目前只支持文本数据查询,具体格式未开发)-fxj
parent
574abf10
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
800 additions
and
90 deletions
+800
-90
QwExcelApiController.java
...fu/cloud/plus/v1/ekp/controller/QwExcelApiController.java
+21
-5
QwExcelApiServiceImpl.java
...lus/v1/ekp/service/impl/QwExce/QwExcelApiServiceImpl.java
+62
-26
SmartSheetDebugService.java
...m/yifu/cloud/plus/v1/ekp/util/SmartSheetDebugService.java
+51
-0
WeComSmartSheetDebugger.java
.../yifu/cloud/plus/v1/ekp/util/WeComSmartSheetDebugger.java
+155
-10
WeComSmartSheetManager.java
...m/yifu/cloud/plus/v1/ekp/util/WeComSmartSheetManager.java
+495
-45
EkpQwExcelApiMapper.xml
...ekp-biz/src/main/resources/mapper/EkpQwExcelApiMapper.xml
+5
-4
EkpTask.java
...main/java/com/yifu/cloud/plus/v1/job/compont/EkpTask.java
+11
-0
No files found.
yifu-ekp/yifu-ekp-biz/src/main/java/com/yifu/cloud/plus/v1/ekp/controller/QwExcelApiController.java
View file @
412436e5
...
...
@@ -13,14 +13,16 @@ import org.springframework.web.bind.annotation.RequestParam;
import
org.springframework.web.bind.annotation.RestController
;
/**
* 招行卡相关控制器
* @author hgw
* @date 2025-9-9 11:24:36
*/
* @Author fxj
* @Description 企微智能表格API调用
* @Date 17:44 2025/9/29
* @Param
* @return
**/
@RestController
@RequiredArgsConstructor
@RequestMapping
(
"/qwExcelApi"
)
@Tag
(
name
=
"
招行卡相关控制器
"
)
@Tag
(
name
=
"
企微智能表格API调用
"
)
public
class
QwExcelApiController
{
private
final
QwExcelApiService
qwExcelApiService
;
...
...
@@ -38,4 +40,18 @@ public class QwExcelApiController {
}
/**
* @Author fxj
* @Description 企业微信智能表格API定时任务
* @Date 15:56 2025/9/26
* @Param
* @return
**/
@Inner
@PostMapping
(
"/inner/wxExcelApi"
)
public
void
wxExcelApi
()
{
qwExcelApiService
.
wxExcelApi
();
}
}
yifu-ekp/yifu-ekp-biz/src/main/java/com/yifu/cloud/plus/v1/ekp/service/impl/QwExce/QwExcelApiServiceImpl.java
View file @
412436e5
...
...
@@ -2,17 +2,17 @@ package com.yifu.cloud.plus.v1.ekp.service.impl.QwExce;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.yifu.cloud.plus.v1.ekp.config.WxConfig
;
import
com.yifu.cloud.plus.v1.ekp.entity.EkpBankAtta
;
import
com.yifu.cloud.plus.v1.ekp.entity.EkpInvoiceInfo
;
import
com.yifu.cloud.plus.v1.ekp.mapper.EkpBankAttaMapper
;
import
com.yifu.cloud.plus.v1.ekp.mapper.QwExcelApiMapper
;
import
com.yifu.cloud.plus.v1.ekp.service.QwExcelApiService
;
import
com.yifu.cloud.plus.v1.ekp.util.SmartSheetDebugService
;
import
com.yifu.cloud.plus.v1.ekp.util.WeComSmartSheetManager
;
import
com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants
;
import
com.yifu.cloud.plus.v1.yifu.common.core.util.MonthCalculationUtils
;
import
lombok.extern.log4j.Log4j2
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.client.RestTemplate
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -31,47 +31,83 @@ public class QwExcelApiServiceImpl extends ServiceImpl<QwExcelApiMapper, EkpInvo
private
SmartSheetDebugService
debugService
;
@Autowired
private
WxConfig
wxConfig
;
@Autowired
WeComSmartSheetManager
weComSmartSheetManager
;
@Override
public
void
wxExcelApi
()
{
//获取accessToken
String
corpId
=
"wwbcb090af0dfe50e5"
;
//HR审批应用 agentid: 1000009,corpSecret:R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524
String
corpSecret
=
"16kqEL_eU-ARwYyqLgEBWHgxm8gXVnkzv_eJMLy9NpU"
;
String
docId
=
"dcTSMCj4lWV9MEP7lquZacOY8WS4g-iHxP_jVYA02tdYwb2YYc3BpDR8NrFWkEngHUg8abET4eTIpo9Zv-571NEA"
;
//智能表格发票数据表ID
String
sheetId
=
"q979lj"
;
String
accessToken
=
weComSmartSheetManager
.
getAccessToken
(
corpId
,
corpSecret
);
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
;
}
int
batchSize
=
1000
;
int
batchCount
=
0
;
log
.
info
(
"微信智能表格发票数据插入开始..."
);
//获取最近24个月的发票信息,按月去插入到智能表格中
String
[]
monthRange
=
null
;
List
<
Map
<
String
,
Object
>>
records
=
new
ArrayList
<>();
List
<
Map
<
String
,
Object
>>
tempRecords
=
null
;
for
(
int
i
=
0
;
i
<
24
;
i
++){
monthRange
=
MonthCalculationUtils
.
calculateMonthRange
(
i
);
//List<String> strings = new ArrayList<>();
//strings.add("FeiTaiLang_Fang");
//strings.add("ZhangQianQian");
//weComSmartSheetManager.addSheet(accessToken,docId,"合同基础信息表");
log
.
info
(
"微信智能表格发票数据删除开始..."
);
weComSmartSheetManager
.
deleteAllRows
(
accessToken
,
docId
,
sheetId
);
log
.
info
(
"微信智能表格发票数据删除完成"
);
log
.
info
(
"微信智能表格发票数据插入开始..."
);
//获取最近24个月的发票信息,按月去插入到智能表格中
monthRange
=
MonthCalculationUtils
.
calculateMonthRange
(
0
);
if
(
null
!=
monthRange
&&
monthRange
.
length
==
CommonConstants
.
dingleDigitIntArray
[
2
]){
tempRecords
=
baseMapper
.
selectInvoiceList
(
monthRange
[
0
],
monthRange
[
1
]);
}
if
(
tempRecords
!=
null
)
{
records
.
addAll
(
tempRecords
);
records
=
baseMapper
.
selectInvoiceList
(
monthRange
[
0
],
monthRange
[
1
]);
}
//分批插入
if
(
null
!=
records
&&
!
records
.
isEmpty
()){
batchCount
=
records
.
size
()
/
batchSize
;
for
(
int
j
=
0
;
j
<
batchCount
;
j
++)
{
tempRecords
=
records
.
subList
(
j
*
batchSize
,
(
j
+
1
)
*
batchSize
);
debugService
.
debugInsertIssue
(
wxConfig
,
tempRecords
)
;
//如果记录数不能被batchSize整除,需要增加一个批次
if
(
records
.
size
()
%
batchSize
!=
0
)
{
batchCount
++
;
}
for
(
int
j
=
0
;
j
<
batchCount
;
j
++)
{
tempRecords
=
records
.
subList
(
j
*
batchSize
,
Math
.
min
((
j
+
1
)
*
batchSize
,
records
.
size
()));
debugService
.
debugInsertIssueAsso
(
accessToken
,
tempRecords
,
docId
,
sheetId
);
break
;
}
}
log
.
info
(
"微信智能表格发票数据插入完成"
);
//智能表格合同数据表ID
/*sheetId = "EuVt8X";
log.info("微信智能表格合同数据删除开始...");
weComSmartSheetManager.deleteAllRows(accessToken,docId,sheetId);
log.info("微信智能表格合同数据删除完成");
log.info("微信智能表格合同数据插入开始...");
//开始处理合同信息,先获取合同数,然后分批次插入数据,每批次1000条
int contractCount = baseMapper.selectContractListCount();
if (contractCount != 0) {
batchCount = contractCount / batchSize;
if
(
contractCount
%
batchSize
!=
0
)
{
batchCount
++;
batchSize
=
contractCount
/
batchCount
;
for
(
int
i
=
0
;
i
<
batchCount
;
i
++)
{
tempRecords
=
baseMapper
.
selectContractList
(
i
*
batchSize
,
(
i
+
1
)
*
batchSize
);
if (batchCount != 0){
for (int i = 0; i <= batchCount; i++) {
tempRecords = baseMapper.selectContractList(i * batchSize, batchSize);
if (tempRecords != null) {
debugService
.
debugInsertIssue
(
wxConfig
,
tempRecords
);
debugService.debugInsertIssueAsso(accessToken,tempRecords,docId,sheetId
);
}
}
}else {
tempRecords = baseMapper.selectContractList(0, batchSize);
if (tempRecords != null) {
debugService.debugInsertIssueAsso(accessToken,tempRecords,docId,sheetId);
}
}
log
.
info
(
"微信智能表格合同数据插入完成"
);
}
log.info("微信智能表格合同数据插入完成");*/
}
}
yifu-ekp/yifu-ekp-biz/src/main/java/com/yifu/cloud/plus/v1/ekp/util/SmartSheetDebugService.java
View file @
412436e5
...
...
@@ -77,4 +77,55 @@ public class SmartSheetDebugService {
log
.
info
(
"\n=== 调试完成 ==="
);
}
/**
* 调试企业微信智能表格记录添加问题
*
*/
public
void
debugInsertIssueAsso
(
String
accessToken
,
List
<
Map
<
String
,
Object
>>
records
,
String
docId
,
String
sheetId
)
{
if
(
Common
.
isEmpty
(
accessToken
)){
log
.
error
(
"accessToken为空"
);
return
;
}
if
(
Common
.
isEmpty
(
records
)){
log
.
error
(
"数据为空"
);
return
;
}
log
.
info
(
"=== 开始调试企业微信智能表格记录添加问题 ==="
);
// 1. 获取并打印表格字段信息
log
.
info
(
"=== 表格字段信息 ==="
);
List
<
WeComSmartSheetDebugger
.
FieldInfo
>
fields
=
debugger
.
getSheetFields
(
accessToken
,
docId
,
sheetId
);
if
(
fields
.
isEmpty
())
{
log
.
info
(
"未能获取到表格字段信息,请检查参数是否正确"
);
return
;
}
Map
<
String
,
String
>
fieldMap
=
new
HashMap
<>();
for
(
WeComSmartSheetDebugger
.
FieldInfo
field
:
fields
)
{
fieldMap
.
put
(
field
.
getTitle
(),
field
.
getType
());
log
.
info
(
"字段ID: "
+
field
.
getFieldId
()
+
", 字段标题: '"
+
field
.
getTitle
()
+
"'"
+
", 字段类型: "
+
field
.
getType
());
}
// 3. 验证字段匹配性
/*log.info("\n=== 字段匹配性验证 ===");
List<String> mismatches = debugger.validateFields(accessToken, docId, sheetId, records);
if (mismatches.isEmpty()) {
log.info("所有字段都匹配");
} else {
log.info("以下字段不匹配:");
for (String mismatch : mismatches) {
log.info("- " + mismatch);
}
log.info("请根据以上信息修正数据后重试");
return;
}*/
// 4. 测试插入数据并查看详细响应
log
.
info
(
"\n=== 数据插入 ==="
);
String
response
=
debugger
.
insertData
(
accessToken
,
docId
,
sheetId
,
records
,
fieldMap
);
//log.info("API响应: " + response);
log
.
info
(
"\n=== 调试完成 ==="
);
}
}
\ No newline at end of file
yifu-ekp/yifu-ekp-biz/src/main/java/com/yifu/cloud/plus/v1/ekp/util/WeComSmartSheetDebugger.java
View file @
412436e5
...
...
@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yifu.cloud.plus.v1.ekp.config.WxConfig
;
import
com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil
;
import
lombok.extern.log4j.Log4j2
;
import
org.springframework.http.*
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.client.RestTemplate
;
...
...
@@ -17,6 +19,7 @@ import java.util.Map;
* 企业微信智能表格调试工具类
* 用于诊断和解决企业微信智能表格记录添加后不显示的问题
*/
@Log4j2
@Component
public
class
WeComSmartSheetDebugger
{
...
...
@@ -61,19 +64,42 @@ public class WeComSmartSheetDebugger {
// 1. 获取access_token
String
accessToken
=
getAccessToken
(
corpId
,
corpSecret
);
//wxConfig.getAccessToken(restTemplate);
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
System
.
err
.
println
(
"获取access_token失败"
);
log
.
error
(
"获取access_token失败"
);
return
fieldInfos
;
}
// 2. 获取字段信息
fieldInfos
=
fetchFields
(
accessToken
,
docId
,
sheetId
);
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取表格字段信息时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取表格字段信息时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
fieldInfos
;
}
/**
* 获取表格字段信息
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @return 字段信息列表
*/
public
List
<
FieldInfo
>
getSheetFields
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
List
<
FieldInfo
>
fieldInfos
=
new
ArrayList
<>();
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
fieldInfos
;
}
// 2. 获取字段信息
fieldInfos
=
fetchFields
(
accessToken
,
docId
,
sheetId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取表格字段信息时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
fieldInfos
;
}
/**
* 验证字段匹配性
*
...
...
@@ -120,12 +146,61 @@ public class WeComSmartSheetDebugger {
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"验证字段匹配性时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"验证字段匹配性时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
mismatches
;
}
/**
* 验证字段匹配性
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @param records 要插入的记录列表
* @return 不匹配的字段列表
*/
public
List
<
String
>
validateFields
(
String
accessToken
,
String
docId
,
String
sheetId
,
List
<
Map
<
String
,
Object
>>
records
)
{
List
<
String
>
mismatches
=
new
ArrayList
<>();
try
{
// 1. 获取表格字段信息
List
<
FieldInfo
>
fieldInfos
=
getSheetFields
(
accessToken
,
docId
,
sheetId
);
Map
<
String
,
FieldInfo
>
fieldMap
=
new
HashMap
<>();
for
(
FieldInfo
fieldInfo
:
fieldInfos
)
{
fieldMap
.
put
(
fieldInfo
.
getTitle
(),
fieldInfo
);
}
// 2. 检查记录中的字段
for
(
Map
<
String
,
Object
>
record
:
records
)
{
Map
<
String
,
Object
>
values
=
(
Map
<
String
,
Object
>)
record
.
get
(
"values"
);
if
(
values
!=
null
)
{
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
values
.
entrySet
())
{
String
fieldName
=
entry
.
getKey
();
Object
fieldValue
=
entry
.
getValue
();
// 检查字段是否存在
if
(!
fieldMap
.
containsKey
(
fieldName
))
{
mismatches
.
add
(
"字段 '"
+
fieldName
+
"' 在表格中不存在"
);
continue
;
}
// 检查字段类型是否匹配
FieldInfo
fieldInfo
=
fieldMap
.
get
(
fieldName
);
String
fieldType
=
fieldInfo
.
getType
();
if
(!
isFieldTypeMatch
(
fieldType
,
fieldValue
))
{
mismatches
.
add
(
"字段 '"
+
fieldName
+
"' 类型不匹配,表格中为 "
+
fieldType
+
" 类型,但传入的是 "
+
fieldValue
.
getClass
().
getSimpleName
()
+
" 类型"
);
}
}
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"验证字段匹配性时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
mismatches
;
}
/**
* 测试插入数据
*
...
...
@@ -183,12 +258,82 @@ public class WeComSmartSheetDebugger {
// 3. 发送请求
return
insertRecords
(
accessToken
,
requestBody
);
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"测试插入数据时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"测试插入数据时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
"测试插入数据时发生异常: "
+
e
.
getMessage
();
}
}
/**
* 插入数据
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @param records 要插入的记录列表
* @return API响应结果
*/
public
String
insertData
(
String
accessToken
,
String
docId
,
String
sheetId
,
List
<
Map
<
String
,
Object
>>
records
,
Map
<
String
,
String
>
fieldMap
)
{
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
return
"获取access_token失败"
;
}
// 2. 构造请求体
JSONObject
requestBody
=
new
JSONObject
();
requestBody
.
put
(
"docid"
,
docId
);
requestBody
.
put
(
"sheet_id"
,
sheetId
);
requestBody
.
put
(
"key_type"
,
"CELL_VALUE_KEY_TYPE_FIELD_TITLE"
);
// 构造records数组
// 格式化
JSONArray
recordsArray
=
new
JSONArray
();
for
(
Map
<
String
,
Object
>
fieldData
:
records
)
{
JSONObject
recordObj
=
new
JSONObject
();
JSONObject
values
=
new
JSONObject
();
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
fieldData
.
entrySet
())
{
String
fieldName
=
entry
.
getKey
();
String
fieldValue
=
entry
.
getValue
().
toString
();
// 构造字段值格式[{"type": "text", "text": "文本内容"}]
JSONArray
fieldValueArray
=
new
JSONArray
();
JSONObject
textObject
=
new
JSONObject
();
//根据fieldMap 对应的字段类型 初始化对应的企业微信的字段
if
(
fieldMap
.
containsKey
(
fieldName
)){
/* if (fieldMap.get(fieldName).equals("FIELD_TYPE_DATE_TIME")){
textObject.put("type", "Date");
textObject.put("text", fieldValue);
}else if (fieldMap.get(fieldName).equals("FIELD_TYPE_NUMBER")){
textObject.put("type", "double");
textObject.put("text", 11111.00);
}else {
textObject.put("type", "text");
textObject.put("text", fieldValue);
}*/
textObject
.
put
(
"type"
,
"text"
);
textObject
.
put
(
"text"
,
fieldValue
);
}
fieldValueArray
.
add
(
textObject
);
values
.
put
(
fieldName
,
fieldValueArray
);
}
recordObj
.
put
(
"values"
,
values
);
recordsArray
.
add
(
recordObj
);
}
requestBody
.
put
(
"records"
,
recordsArray
);
// 3. 发送请求
return
insertRecords
(
accessToken
,
requestBody
);
}
catch
(
Exception
e
)
{
log
.
error
(
"测试插入数据时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
"测试插入数据时发生异常: "
+
e
.
getMessage
();
}
}
/**
* 检查字段类型是否匹配
*
...
...
@@ -229,13 +374,13 @@ public class WeComSmartSheetDebugger {
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
return
jsonObject
.
getString
(
"access_token"
);
}
else
{
System
.
err
.
println
(
"获取access_token失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"获取access_token失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
return
null
;
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取access_token时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取access_token时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
null
;
...
...
@@ -282,12 +427,12 @@ public class WeComSmartSheetDebugger {
}
}
}
else
{
System
.
err
.
println
(
"获取字段信息失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"获取字段信息失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取字段信息时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取字段信息时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
fieldInfos
;
...
...
@@ -310,12 +455,12 @@ public class WeComSmartSheetDebugger {
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
requestBody
.
toJSONString
(),
headers
);
System
.
err
.
println
(
"插入数据的JSON:"
+
request
.
getBody
());
//log.info
("插入数据的JSON:" + request.getBody());
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
url
,
request
,
String
.
class
);
return
response
.
getBody
();
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"插入记录时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"插入记录时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
"插入记录时发生异常: "
+
e
.
getMessage
();
}
...
...
yifu-ekp/yifu-ekp-biz/src/main/java/com/yifu/cloud/plus/v1/ekp/util/WeComSmartSheetManager.java
View file @
412436e5
...
...
@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSON;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yifu.cloud.plus.v1.ekp.config.WxConfig
;
import
lombok.extern.log4j.Log4j2
;
import
org.springframework.http.*
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.client.RestTemplate
;
...
...
@@ -15,7 +17,8 @@ import java.util.*;
* 企业微信智能表格管理工具类
* 实现创建智能表格、创建工作表、清空工作表数据和插入数据的功能
*/
@Component
@Log4j2
@Service
public
class
WeComSmartSheetManager
{
/**
...
...
@@ -58,6 +61,27 @@ public class WeComSmartSheetManager {
*/
private
static
final
String
GET_FIELDS_PATH
=
"/wedoc/smartsheet/get_fields"
;
/**
* 添加子表的接口路径
*/
private
static
final
String
ADD_SHEET_PATH
=
"/wedoc/smartsheet/add_sheet"
;
/**
* 获取表格行列信息的接口路径
*/
private
static
final
String
GET_SHEET_PROPERTIES_PATH
=
"/wedoc/spreadsheet/get_sheet_properties"
;
/**
* 更新表格内容的接口路径
*/
private
static
final
String
UPDATE_SPREADSHEET_PATH
=
"/wedoc/spreadsheet/update"
;
/**
* 获取记录的接口路径
*/
private
static
final
String
GET_RECORDS_PATH
=
"/wedoc/smartsheet/get_records"
;
/**
* 创建智能表格
*
...
...
@@ -72,7 +96,7 @@ public class WeComSmartSheetManager {
String
accessToken
=
wxConfig
.
getAccessToken
(
restTemplate
);
//getAccessToken(corpId, corpSecret);
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
System
.
err
.
println
(
"获取access_token失败"
);
log
.
error
(
"获取access_token失败"
);
return
null
;
}
...
...
@@ -87,16 +111,49 @@ public class WeComSmartSheetManager {
if
(
docId
!=
null
)
{
System
.
out
.
println
(
"智能表格创建成功,文档ID: "
+
docId
);
}
else
{
System
.
err
.
println
(
"智能表格创建失败"
);
log
.
error
(
"智能表格创建失败"
);
}
return
docId
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"创建智能表格时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"创建智能表格时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
null
;
}
}
/**
* 创建智能表格
*
* @param docName 文档名称
* @param adminUsers 管理员用户列表
* @return 文档ID
*/
public
String
createSmartSheet
(
String
accessToken
,
String
docName
,
List
<
String
>
adminUsers
)
{
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
null
;
}
// 2. 构造请求体
JSONObject
requestBody
=
new
JSONObject
();
requestBody
.
put
(
"doc_type"
,
10
);
// 10: 智能表格
requestBody
.
put
(
"doc_name"
,
docName
);
requestBody
.
put
(
"admin_users"
,
adminUsers
);
// 3. 发送请求创建智能表格
String
docId
=
createDoc
(
accessToken
,
requestBody
);
if
(
docId
!=
null
)
{
System
.
out
.
println
(
"智能表格创建成功,文档ID: "
+
docId
);
}
else
{
log
.
error
(
"智能表格创建失败"
);
}
return
docId
;
}
catch
(
Exception
e
)
{
log
.
error
(
"创建智能表格时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
null
;
}
}
/**
* 获取指定智能表格下的所有工作表ID列表
* 注意:根据企业微信API文档,创建智能表格时会自动创建一个默认的子表
...
...
@@ -111,18 +168,39 @@ public class WeComSmartSheetManager {
// 1. 获取access_token
String
accessToken
=
wxConfig
.
getAccessToken
(
restTemplate
);
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
System
.
err
.
println
(
"获取access_token失败"
);
log
.
error
(
"获取access_token失败"
);
return
new
ArrayList
<>();
}
return
getSheetIds
(
accessToken
,
docId
);
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取工作表ID时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取工作表ID时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
new
ArrayList
<>();
}
}
/**
* 获取指定智能表格下的所有工作表ID列表
* 注意:根据企业微信API文档,创建智能表格时会自动创建一个默认的子表
* 该方法用于查询这些已存在的子表。
*
* @param docId 文档ID
* @return 工作表ID列表
*/
public
List
<
String
>
createWorkSheets
(
String
accessToken
,
String
docId
)
{
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
new
ArrayList
<>();
}
return
getSheetIds
(
accessToken
,
docId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取工作表ID时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
new
ArrayList
<>();
}
}
/**
* 使用access_token获取智能表格下的工作表ID列表
*
...
...
@@ -130,9 +208,15 @@ public class WeComSmartSheetManager {
* @param docId 文档ID
* @return 工作表ID列表
*/
p
rivate
List
<
String
>
getSheetIds
(
String
accessToken
,
String
docId
)
{
p
ublic
List
<
String
>
getSheetIds
(
String
accessToken
,
String
docId
)
{
List
<
String
>
sheetIds
=
new
ArrayList
<>();
try
{
// 检查参数是否为空
if
(
docId
==
null
||
docId
.
isEmpty
())
{
log
.
error
(
"docId不能为空"
);
return
sheetIds
;
}
String
url
=
WE_COM_API_BASE_URL
+
GET_SHEET_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
...
...
@@ -149,7 +233,8 @@ public class WeComSmartSheetManager {
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
JSONArray
sheets
=
jsonObject
.
getJSONArray
(
"sheet_list"
);
if
(
sheets
!=
null
&&
!
sheets
.
isEmpty
())
{
for
(
int
i
=
0
;
i
<
sheets
.
size
();
i
++)
{
...
...
@@ -157,16 +242,31 @@ public class WeComSmartSheetManager {
sheetIds
.
add
(
sheet
.
getString
(
"sheet_id"
));
}
}
else
{
System
.
err
.
printl
n
(
"未找到任何工作表"
);
log
.
war
n
(
"未找到任何工作表"
);
}
}
else
{
System
.
err
.
println
(
"查询工作表失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"查询工作表失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
// 特别处理一些常见的错误代码
switch
(
errCode
)
{
case
404
:
log
.
error
(
"请求的文档未找到,请检查docId是否正确,并确保是通过API创建的智能表格"
);
break
;
case
400
:
log
.
error
(
"请求参数错误,请检查docId格式是否正确"
);
break
;
case
48002
:
log
.
error
(
"应用没有权限访问该文档,请检查应用权限配置"
);
break
;
default
:
log
.
error
(
"未知错误,请参考企业微信API文档"
);
}
}
}
else
{
log
.
error
(
"查询工作表时HTTP状态码错误: "
+
response
.
getStatusCode
());
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"查询工作表时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
log
.
error
(
"查询工作表时发生异常: "
+
e
.
getMessage
(),
e
);
}
return
sheetIds
;
}
...
...
@@ -186,32 +286,32 @@ public class WeComSmartSheetManager {
// 1. 获取access_token
String
accessToken
=
wxConfig
.
getAccessToken
(
restTemplate
);
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
System
.
err
.
println
(
"获取access_token失败"
);
log
.
error
(
"获取access_token失败"
);
return
false
;
}
// 2. 验证字段是否存在
if
(!
validateFields
(
accessToken
,
docId
,
sheetId
,
records
))
{
System
.
err
.
println
(
"字段验证失败,请检查字段名称是否正确"
);
log
.
error
(
"字段验证失败,请检查字段名称是否正确"
);
return
false
;
}
// 3. 清空工作表数据
if
(!
clearSheetData
(
accessToken
,
docId
,
sheetId
))
{
System
.
err
.
println
(
"清空工作表数据失败"
);
log
.
error
(
"清空工作表数据失败"
);
return
false
;
}
// 4. 插入新数据(分批处理,避免接口限制)
if
(!
insertDataInBatches
(
accessToken
,
docId
,
sheetId
,
records
))
{
System
.
err
.
println
(
"插入数据失败"
);
log
.
error
(
"插入数据失败"
);
return
false
;
}
System
.
out
.
println
(
"清空并插入数据成功"
);
return
true
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"清空并插入数据时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"清空并插入数据时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
false
;
}
...
...
@@ -224,7 +324,7 @@ public class WeComSmartSheetManager {
* @param corpSecret 应用密钥
* @return access_token
*/
p
rivate
String
getAccessToken
(
String
corpId
,
String
corpSecret
)
{
p
ublic
String
getAccessToken
(
String
corpId
,
String
corpSecret
)
{
try
{
String
url
=
WE_COM_API_BASE_URL
+
GET_TOKEN_PATH
+
"?corpid="
+
corpId
+
"&corpsecret="
+
corpSecret
;
...
...
@@ -236,13 +336,13 @@ public class WeComSmartSheetManager {
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
return
jsonObject
.
getString
(
"access_token"
);
}
else
{
System
.
err
.
println
(
"获取access_token失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"获取access_token失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
return
null
;
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取access_token时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取access_token时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
null
;
...
...
@@ -272,13 +372,13 @@ public class WeComSmartSheetManager {
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
return
jsonObject
.
getString
(
"docid"
);
}
else
{
System
.
err
.
println
(
"创建文档失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"创建文档失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
return
null
;
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"创建文档时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"创建文档时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
null
;
...
...
@@ -308,7 +408,7 @@ public class WeComSmartSheetManager {
if
(
values
!=
null
)
{
for
(
String
fieldName
:
values
.
keySet
())
{
if
(!
fieldTitles
.
contains
(
fieldName
))
{
System
.
err
.
println
(
"字段 '"
+
fieldName
+
"' 在表格中不存在,请检查字段名称是否正确"
);
log
.
error
(
"字段 '"
+
fieldName
+
"' 在表格中不存在,请检查字段名称是否正确"
);
return
false
;
}
}
...
...
@@ -317,7 +417,7 @@ public class WeComSmartSheetManager {
return
true
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"验证字段时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"验证字段时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
false
;
}
...
...
@@ -365,12 +465,12 @@ public class WeComSmartSheetManager {
}
}
}
else
{
System
.
err
.
println
(
"获取字段信息失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"获取字段信息失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"获取字段信息时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"获取字段信息时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
fieldInfos
;
...
...
@@ -384,12 +484,19 @@ public class WeComSmartSheetManager {
* @param sheetId 工作表ID
* @return 是否成功
*/
p
rivate
boolean
clearSheetData
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
p
ublic
boolean
clearSheetData
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
try
{
// 检查参数是否为空
if
(
docId
==
null
||
sheetId
==
null
||
docId
.
isEmpty
()
||
sheetId
.
isEmpty
())
{
log
.
error
(
"docId或sheetId不能为空"
);
return
false
;
}
// 1. 查询所有记录ID
List
<
String
>
recordIds
=
queryAllRecordIds
(
accessToken
,
docId
,
sheetId
);
if
(
recordIds
.
isEmpty
())
{
// 没有记录需要删除
log
.
info
(
"没有记录需要删除"
);
return
true
;
}
...
...
@@ -406,8 +513,7 @@ public class WeComSmartSheetManager {
return
true
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"清空工作表数据时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
log
.
error
(
"清空工作表数据时发生异常: "
+
e
.
getMessage
(),
e
);
return
false
;
}
}
...
...
@@ -423,6 +529,12 @@ public class WeComSmartSheetManager {
private
List
<
String
>
queryAllRecordIds
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
List
<
String
>
recordIds
=
new
ArrayList
<>();
try
{
// 检查参数是否为空
if
(
docId
==
null
||
sheetId
==
null
||
docId
.
isEmpty
()
||
sheetId
.
isEmpty
())
{
log
.
error
(
"docId或sheetId不能为空"
);
return
recordIds
;
}
String
url
=
WE_COM_API_BASE_URL
+
QUERY_RECORDS_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
...
...
@@ -441,7 +553,8 @@ public class WeComSmartSheetManager {
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
JSONArray
records
=
jsonObject
.
getJSONArray
(
"records"
);
if
(
records
!=
null
&&
!
records
.
isEmpty
())
{
for
(
int
i
=
0
;
i
<
records
.
size
();
i
++)
{
...
...
@@ -450,13 +563,28 @@ public class WeComSmartSheetManager {
}
}
}
else
{
System
.
err
.
println
(
"查询记录失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"查询记录失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
// 特别处理一些常见的错误代码
switch
(
errCode
)
{
case
404
:
log
.
error
(
"请求的文档或表格未找到,请检查docId和sheetId是否正确,并确保是通过API创建的智能表格"
);
break
;
case
400
:
log
.
error
(
"请求参数错误,请检查docId和sheetId格式是否正确"
);
break
;
case
48002
:
log
.
error
(
"应用没有权限访问该文档,请检查应用权限配置"
);
break
;
default
:
log
.
error
(
"未知错误,请参考企业微信API文档"
);
}
}
}
else
{
log
.
error
(
"查询记录时HTTP状态码错误: "
+
response
.
getStatusCode
());
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"查询记录时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
log
.
error
(
"查询记录时发生异常: "
+
e
.
getMessage
(),
e
);
}
return
recordIds
;
}
...
...
@@ -472,6 +600,17 @@ public class WeComSmartSheetManager {
*/
private
boolean
deleteRecords
(
String
accessToken
,
String
docId
,
String
sheetId
,
List
<
String
>
recordIds
)
{
try
{
// 检查参数是否为空
if
(
docId
==
null
||
sheetId
==
null
||
docId
.
isEmpty
()
||
sheetId
.
isEmpty
())
{
log
.
error
(
"docId或sheetId不能为空"
);
return
false
;
}
if
(
recordIds
==
null
||
recordIds
.
isEmpty
())
{
log
.
info
(
"没有记录需要删除"
);
return
true
;
}
String
url
=
WE_COM_API_BASE_URL
+
DELETE_RECORDS_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
...
...
@@ -490,20 +629,37 @@ public class WeComSmartSheetManager {
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
return
true
;
}
else
{
System
.
err
.
println
(
"删除记录失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"删除记录失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
// 特别处理一些常见的错误代码
switch
(
errCode
)
{
case
404
:
log
.
error
(
"请求的文档或表格未找到,请检查docId和sheetId是否正确"
);
break
;
case
400
:
log
.
error
(
"请求参数错误,请检查参数格式是否正确"
);
break
;
case
48002
:
log
.
error
(
"应用没有权限访问该文档,请检查应用权限配置"
);
break
;
default
:
log
.
error
(
"未知错误,请参考企业微信API文档"
);
}
return
false
;
}
}
else
{
log
.
error
(
"删除记录时HTTP状态码错误: "
+
response
.
getStatusCode
());
return
false
;
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"删除记录时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
log
.
error
(
"删除记录时发生异常: "
+
e
.
getMessage
(),
e
);
return
false
;
}
}
/**
* 分批插入数据
...
...
@@ -529,7 +685,7 @@ public class WeComSmartSheetManager {
return
true
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"分批插入数据时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"分批插入数据时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
return
false
;
}
...
...
@@ -574,17 +730,17 @@ public class WeComSmartSheetManager {
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
0
)
{
return
true
;
}
else
{
System
.
err
.
println
(
"添加记录失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
log
.
error
(
"添加记录失败,错误代码:"
+
jsonObject
.
getInteger
(
"errcode"
)
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
// 特别处理字段不存在的错误
if
(
jsonObject
.
getInteger
(
"errcode"
)
==
2022004
)
{
System
.
err
.
println
(
"请检查您要插入的字段名称是否与表格中的字段完全匹配"
);
log
.
error
(
"请检查您要插入的字段名称是否与表格中的字段完全匹配"
);
}
return
false
;
}
}
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"添加记录时发生异常: "
+
e
.
getMessage
());
log
.
error
(
"添加记录时发生异常: "
+
e
.
getMessage
());
e
.
printStackTrace
();
}
return
false
;
...
...
@@ -651,6 +807,300 @@ public class WeComSmartSheetManager {
}
/**
* 通过文档ID和标题创建子表
*
* @param accessToken 访问令牌
* @param docId 文档ID
* @param title 子表标题
* @return 子表ID
*/
public
String
addSheet
(
String
accessToken
,
String
docId
,
String
title
)
{
try
{
String
url
=
WE_COM_API_BASE_URL
+
ADD_SHEET_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
// 构造请求体
JSONObject
requestBody
=
new
JSONObject
();
requestBody
.
put
(
"docid"
,
docId
);
JSONObject
properties
=
new
JSONObject
();
properties
.
put
(
"title"
,
title
);
requestBody
.
put
(
"properties"
,
properties
);
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
requestBody
.
toJSONString
(),
headers
);
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
url
,
request
,
String
.
class
);
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
JSONObject
sheetProperties
=
jsonObject
.
getJSONObject
(
"properties"
);
if
(
sheetProperties
!=
null
)
{
String
sheetId
=
sheetProperties
.
getString
(
"sheet_id"
);
log
.
info
(
"成功创建子表,子表ID: "
+
sheetId
);
return
sheetId
;
}
}
else
{
log
.
error
(
"创建子表失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
return
null
;
}
}
else
{
log
.
error
(
"创建子表时HTTP状态码错误: "
+
response
.
getStatusCode
());
return
null
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"创建子表时发生异常: "
+
e
.
getMessage
(),
e
);
return
null
;
}
return
null
;
}
/**
* 获取表格行数
*
* @param docId 文档ID
* @param sheetId 工作表ID
* @return 表格行数
*/
public
int
getRowCount
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
-
1
;
}
// 2. 获取表格行列信息
WeComSmartSheetManager
.
SheetProperties
properties
=
this
.
getSheetProperties
(
accessToken
,
docId
,
sheetId
);
if
(
properties
==
null
)
{
log
.
error
(
"获取表格信息失败,请检查docId和sheetId是否正确,以及应用是否有足够权限访问该文件"
);
log
.
error
(
"注意:根据企业微信API限制,只有通过API创建的智能表格才能通过API进行操作"
);
return
-
1
;
}
log
.
info
(
"文档ID: "
+
docId
+
", 工作表ID: "
+
sheetId
+
", 表格信息: "
+
properties
);
return
properties
.
getRowCount
();
}
catch
(
Exception
e
)
{
log
.
error
(
"获取表格行数时发生异常: "
+
e
.
getMessage
(),
e
);
return
-
1
;
}
}
/**
* 获取表格行列信息
*
* @param accessToken 访问令牌
* @param docId 文档ID
* @param sheetId 工作表ID
* @return 表格行列信息
*/
public
WeComSmartSheetManager
.
SheetProperties
getSheetProperties
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
try
{
String
url
=
WE_COM_API_BASE_URL
+
GET_SHEET_PROPERTIES_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
// 构造请求体
JSONObject
requestBody
=
new
JSONObject
();
requestBody
.
put
(
"docid"
,
docId
);
//requestBody.put("sheet_id", sheetId);
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
requestBody
.
toJSONString
(),
headers
);
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
url
,
request
,
String
.
class
);
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
JSONObject
properties
=
jsonObject
.
getJSONObject
(
"properties"
);
if
(
properties
!=
null
)
{
WeComSmartSheetManager
.
SheetProperties
sheetProperties
=
new
WeComSmartSheetManager
.
SheetProperties
();
sheetProperties
.
setRowCount
(
properties
.
getInteger
(
"row_count"
));
sheetProperties
.
setColumnCount
(
properties
.
getInteger
(
"column_count"
));
return
sheetProperties
;
}
}
else
{
log
.
error
(
"获取表格行列信息失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
}
}
else
{
log
.
error
(
"获取表格行列信息时HTTP状态码错误: "
+
response
.
getStatusCode
());
}
}
catch
(
Exception
e
)
{
log
.
error
(
"获取表格行列信息时发生异常: "
+
e
.
getMessage
(),
e
);
}
return
null
;
}
/**
* 删除所有行数据
*
* @param accessToken 访问令牌
* @param docId 文档ID
* @param sheetId 工作表ID
* @return 是否成功
*/
public
boolean
deleteAllRows
(
String
accessToken
,
String
docId
,
String
sheetId
)
{
try
{
if
(
accessToken
==
null
||
accessToken
.
isEmpty
())
{
log
.
error
(
"获取access_token失败"
);
return
false
;
}
// 2. 循环获取并删除记录,直到没有记录为止
int
totalDeleted
=
0
;
while
(
true
)
{
// 获取记录
List
<
WeComSmartSheetManager
.
RecordInfo
>
records
=
getRecords
(
accessToken
,
docId
,
sheetId
,
1000
);
if
(
records
.
isEmpty
())
{
log
.
info
(
"没有更多记录需要删除,已完成清理任务"
);
break
;
}
log
.
info
(
"获取到 {} 条记录,准备删除"
,
records
.
size
());
// 提取记录ID
List
<
String
>
recordIds
=
new
ArrayList
<>();
for
(
WeComSmartSheetManager
.
RecordInfo
record
:
records
)
{
recordIds
.
add
(
record
.
getRecordId
());
}
// 删除记录
boolean
deleted
=
deleteRecords
(
accessToken
,
docId
,
sheetId
,
recordIds
);
if
(
deleted
)
{
totalDeleted
+=
records
.
size
();
log
.
info
(
"成功删除 {} 条记录,当前总计已删除 {} 条记录"
,
records
.
size
(),
totalDeleted
);
}
else
{
log
.
error
(
"删除记录失败"
);
return
false
;
}
}
log
.
info
(
"任务完成,总共删除 {} 条记录"
,
totalDeleted
);
return
true
;
}
catch
(
Exception
e
)
{
log
.
error
(
"获取并删除记录时发生异常: "
+
e
.
getMessage
(),
e
);
return
false
;
}
}
/**
* 获取记录
*
* @param accessToken 访问令牌
* @param docId 文档ID
* @param sheetId 工作表ID
* @param limit 限制条数
* @return 记录列表
*/
private
List
<
WeComSmartSheetManager
.
RecordInfo
>
getRecords
(
String
accessToken
,
String
docId
,
String
sheetId
,
int
limit
)
{
List
<
WeComSmartSheetManager
.
RecordInfo
>
records
=
new
ArrayList
<>();
try
{
String
url
=
WE_COM_API_BASE_URL
+
GET_RECORDS_PATH
+
"?access_token="
+
accessToken
;
RestTemplate
restTemplate
=
new
RestTemplate
();
// 构造请求体
JSONObject
requestBody
=
new
JSONObject
();
requestBody
.
put
(
"docid"
,
docId
);
requestBody
.
put
(
"sheet_id"
,
sheetId
);
requestBody
.
put
(
"limit"
,
limit
);
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
requestBody
.
toJSONString
(),
headers
);
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
url
,
request
,
String
.
class
);
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
response
.
getBody
());
Integer
errCode
=
jsonObject
.
getInteger
(
"errcode"
);
if
(
errCode
==
null
||
errCode
==
0
)
{
JSONArray
recordArray
=
jsonObject
.
getJSONArray
(
"records"
);
if
(
recordArray
!=
null
&&
!
recordArray
.
isEmpty
())
{
for
(
int
i
=
0
;
i
<
recordArray
.
size
();
i
++)
{
JSONObject
recordObj
=
recordArray
.
getJSONObject
(
i
);
WeComSmartSheetManager
.
RecordInfo
recordInfo
=
new
WeComSmartSheetManager
.
RecordInfo
();
recordInfo
.
setRecordId
(
recordObj
.
getString
(
"record_id"
));
records
.
add
(
recordInfo
);
}
}
}
else
{
log
.
error
(
"获取记录失败,错误代码:"
+
errCode
+
",错误信息:"
+
jsonObject
.
getString
(
"errmsg"
));
}
}
else
{
log
.
error
(
"获取记录时HTTP状态码错误: "
+
response
.
getStatusCode
());
}
}
catch
(
Exception
e
)
{
log
.
error
(
"获取记录时发生异常: "
+
e
.
getMessage
(),
e
);
}
return
records
;
}
/**
* 记录信息内部类
*/
public
static
class
RecordInfo
{
private
String
recordId
;
public
String
getRecordId
()
{
return
recordId
;
}
public
void
setRecordId
(
String
recordId
)
{
this
.
recordId
=
recordId
;
}
@Override
public
String
toString
()
{
return
"RecordInfo{"
+
"recordId='"
+
recordId
+
'\''
+
'}'
;
}
}
/**
* 表格属性信息类
*/
public
static
class
SheetProperties
{
/**
* 行数
*/
private
int
rowCount
;
/**
* 列数
*/
private
int
columnCount
;
public
int
getRowCount
()
{
return
rowCount
;
}
public
void
setRowCount
(
int
rowCount
)
{
this
.
rowCount
=
rowCount
;
}
public
int
getColumnCount
()
{
return
columnCount
;
}
public
void
setColumnCount
(
int
columnCount
)
{
this
.
columnCount
=
columnCount
;
}
@Override
public
String
toString
()
{
return
"SheetProperties{"
+
"rowCount="
+
rowCount
+
", columnCount="
+
columnCount
+
'}'
;
}
}
}
\ No newline at end of file
yifu-ekp/yifu-ekp-biz/src/main/resources/mapper/EkpQwExcelApiMapper.xml
View file @
412436e5
...
...
@@ -30,7 +30,7 @@
a.fd_3b05ade863b120 AS "开票金额",
date_format(a.fd_3afa7c1b153ff8, '%Y-%m-%d') AS "开票时间",
date_format(a.fd_3afa7c1b153ff8, '%Y-%m') AS "开票月份",
a.fd_3afac373e38ec4 AS "购买名称",
a.fd_3afac373e38ec4 AS "购买
方
名称",
a.fd_3b0f037ecc0ed0 AS "发票状态",
a.fd_3b1bb0ccc14760 AS "红冲状态",
concat(
...
...
@@ -39,7 +39,8 @@
ifnull(a.fd_3afac373e38ec4, ''),
'
&
',
ifnull(date_format(a.fd_3afa7c1b153ff8, '%Y-%m'), '')
) AS "发票号
&
购买方名称
&
开票月份组合"
) AS "发票号
&
购买方名称
&
开票月份组合",
date_format(b.doc_create_time, '%Y-%m-%d') AS "创建时间"
FROM ekp_bacdf3a32d242279ceb6 a
LEFT JOIN modeling_simple_main b ON a.fd_id = b.fd_id
<where>
...
...
@@ -72,12 +73,12 @@
FROM
ekp_0103c453b2848c3bb31c a
LEFT JOIN sys_org_element b ON a.fd_3b1141597b4894 = b.fd_id
<where>
<where>
1=1 ORDER BY a.fd_3ade33763baa0e DESC
<if
test=
"limitStart != null and limitEnd != null"
>
limit #{limitStart},#{limitEnd}
</if>
</where>
ORDER BY a.fd_3ade33763baa0e DESC
</select>
<select
id=
"selectContractListCount"
resultType=
"java.lang.Integer"
>
SELECT
...
...
yifu-job/yifu-job-api/src/main/java/com/yifu/cloud/plus/v1/job/compont/EkpTask.java
View file @
412436e5
...
...
@@ -105,4 +105,15 @@ public class EkpTask {
,
"/zhaoHang/inner/doGetZhaoHangInfo"
,
""
,
Object
.
class
,
SecurityConstants
.
FROM_IN
);
log
.
info
(
"------------每天获取招行卡流水-定时任务结束------------"
);
}
/**
* @Author fxj
* @Description 微智能表格数据-定时任务
* @Date 9:41 2025/10/9
**/
public
void
wxExcelApi
()
{
log
.
info
(
"------------定时生成企微智能表格数据-定时任务开始------------"
);
HttpDaprUtil
.
invokeMethodPost
(
daprEkpProperties
.
getAppUrl
(),
daprEkpProperties
.
getAppId
(),
"/qwExcelApi/inner/wxExcelApi"
,
""
,
Object
.
class
,
SecurityConstants
.
FROM_IN
);
log
.
info
(
"------------定时生成企微智能表格数据-定时任务结束------------"
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment