提交内容:PPP项目报表代码

时间:2025-10-21 11:06
提交人:邹江涛
This commit is contained in:
zoujiangtao 2025-10-21 11:08:17 +08:00
parent 7f86952b8a
commit 20ab7e37cb
2 changed files with 466 additions and 0 deletions

View File

@ -0,0 +1,197 @@
package shkd.sys.sys.plugin.form;
import dm.jdbc.util.StringUtil;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.cache.CacheFactory;
import kd.bos.cache.TempFileCache;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IMetadata;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.NumberFormatProvider;
import kd.bos.entity.ValueMapItem;
import kd.bos.entity.datamodel.FmtField;
import kd.bos.entity.report.*;
import kd.bos.form.control.Toolbar;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.report.ReportList;
import kd.bos.report.proxy.ReportListProxy;
import kd.sdk.plugin.Plugin;
import shkd.sys.sys.plugin.report.AccountbankReportFormPlugin;
import shkd.sys.sys.plugin.report.util.CsvExportUtil;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import static shkd.sys.sys.plugin.report.util.ReportUtils.processFieldValue;
/**
* 单据界面插件
*/
public class PPPReportBillPlugin extends AbstractBillPlugIn implements Plugin {
private static final Log logger = LogFactory.getLog(AccountbankReportFormPlugin.class);
@Override
public void registerListener(EventObject e) {
super.registerListener(e);
// 获取工具栏监听整个工具栏
Toolbar export = this.getView().getControl("toolbarap");
// 监听工具栏这个按钮的点击事件
export.addItemClickListener(this);
export.addClickListener(this);
}
/**
* 处理列表项点击事件当点击的项为 "shkd_exportcsv" 执行导出 CSV 文件的操作
*
* @param evt 列表项点击事件对象包含被点击项的相关信息
*/
@Override
public void itemClick(ItemClickEvent evt) {
super.itemClick(evt);
String itemKey = evt.getItemKey();
if (StringUtil.equals("shkd_exportcsv", itemKey)) {
// 获取数据实体类型及其属性集合
MainEntityType dataEntityType = this.getModel().getDataEntityType();
DataEntityPropertyCollection properties = dataEntityType.getProperties();
String reportName = dataEntityType.getDisplayName().getLocaleValue();
// 获取报表列表控件及模型并取得行数和列信息
ReportList reportList = this.getControl("reportlistap");
IReportListModel reportListModel = reportList.getReportModel();
int rowCount = reportListModel.getRowCount();
ReportListProxy reportListProxy = new ReportListProxy(reportList);
List<AbstractReportColumn> columns = reportListProxy.getColumnList(reportListModel);
List<ReportColumn> cols = reportListProxy.getReportColumnList(columns, true);
// 获取所有行数据并初始化数字格式化提供器
DynamicObjectCollection rowData = reportListModel.getRowData(0, rowCount, false);
NumberFormatProvider numberFormatProvider = ReportColumn.initNumberFormatProvider(rowData, cols);
// 提取需要导出的字段名排除 fseq 字段
List<String> headerKeys = numberFormatProvider.getFmtFields().stream()
.map(FmtField::getFieldName)
.filter(fieldName -> !Objects.equals(fieldName, "fseq"))
.collect(Collectors.toList());
// 构建属性名到显示名称的映射表便于快速查找
Map<String, String> nameToDisplay =
properties.stream()
.filter(Objects::nonNull)
.filter(p -> p.getDisplayName() != null)
.collect(Collectors.toMap(
IMetadata::getName,
p -> p.getDisplayName().getLocaleValue(),
(v1, v2) -> v1));
// 按照字段顺序获取对应的显示名称缺失则使用空字符串
List<String> headers = headerKeys.stream()
.map(k -> nameToDisplay.getOrDefault(k, ""))
.collect(Collectors.toList());
// 构造每一行的数据列表处理复杂对象的name属性及本地化
List<List<?>> rows2 = rowData.stream()
.map(obj -> headerKeys.stream()
.map(key -> processFieldValue(obj.get(key)))
.collect(Collectors.toList()))
.collect(Collectors.toList());
// 获取日期值
Date dateValue = (Date) this.getModel().getValue("shkd_sjrqfilter");
// 转换为 LocalDate 并格式化
LocalDate localDate = dateValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
String formattedDate = localDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
try {
String customFileName = "四川能源发展集团有限责任公司_PPP项目_18_" + formattedDate + ".csv";
Path tempDir = Files.createTempDirectory("csv_export");
Path tempFile = tempDir.resolve(customFileName);
CsvExportUtil.writeCsvToFile(tempFile, headers, rows2);
// 上传到临时文件服务器 获取压缩包下载地址
TempFileCache tempFileCache = CacheFactory.getCommonCacheFactory().getTempFileCache();
String url = tempFileCache.saveAsUrl(tempFile.getFileName().toString(), Files.newInputStream(tempFile), 3 * 60);
// 下载压缩包
this.getView().download(url);
Files.delete(tempFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* 处理字段值支持简单值和复杂对象如含name属性的对象
*
* @param value 原始字段值
* @return 处理后的字符串值
*/
public static Object processFieldValue(Object value) {
if (value == null) {
return "";
}
// 添加日期类型处理 - 处理 Date 对象
if (value instanceof java.util.Date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format((java.util.Date) value);
}
// 如果是DynamicObject或类似结构尝试获取name属性
try {
// 尝试调用get("name")方法获取name属性
Object nameValue = value.getClass().getMethod("get", String.class).invoke(value, "name");
if (nameValue != null) {
// 如果name是一个本地化对象则进一步处理
return processLocalizedValue(nameValue);
}
// 如果没有name属性直接返回原值的toString()
return value.toString();
} catch (Exception e) {
// 如果调用失败说明不是复杂对象直接返回toString()
return value.toString();
}
}
/**
* 处理本地化值对象优先获取ZH_TW其次ZH_CN
*
* @param localizedObj 本地化对象
* @return 对应语言的值
*/
public static String processLocalizedValue(Object localizedObj) {
if (localizedObj == null) {
return "";
}
try {
// 尝试获取ZH_CN本地化值
Object zhCnValue = localizedObj.getClass().getMethod("get", String.class).invoke(localizedObj, "zh_CN");
if (zhCnValue != null) {
return zhCnValue.toString();
}
// 都没有则返回默认toString()
return localizedObj.toString();
} catch (Exception e) {
// 异常情况下返回toString()
return localizedObj.toString();
}
}
}

View File

@ -0,0 +1,269 @@
package shkd.sys.sys.plugin.report;
import com.grapecity.documents.excel.Q;
import kd.bos.algo.*;
import kd.bos.algo.input.CollectionInput;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FastFilter;
import kd.bos.entity.report.FilterItemInfo;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.krpc.common.utils.CollectionUtils;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.sdk.plugin.Plugin;
import shkd.sys.sys.plugin.form.PaymentProcessingBillPlugin;
import shkd.sys.sys.plugin.report.util.ReportUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
* 描述PPP项目报表
* 报表取数插件
*/
public class PPPProjectReportPlugin extends AbstractReportListDataPlugin implements Plugin {
private static final Log logger = LogFactory.getLog(PPPProjectReportPlugin.class);
@Override
public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
//获取筛选器的值
List<QFilter> listQFilter = getListQFilter(reportQueryParam);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateValue = null;
for (QFilter filter : listQFilter) {
if ("shkd_sjrqfilter".equals(filter.getProperty())) {
Object value = filter.getValue();
// 判断并转换为Date类型
if (value instanceof Date) {
dateValue = (Date) value;
} else if (value instanceof String) {
// 如果是字符串先解析为Date
dateValue = sdf.parse((String) value);
}
}
}
DataSet finish = null;
DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load("shkd_pppproject",
"id,shkd_ssjtbm,shkd_ssjtmc,shkd_xm.shkd_lcxmbm,shkd_xm.name,shkd_xm.shkd_xmdwbm," +
"shkd_xm.shkd_xmdwmc,shkd_entryentity.shkd_xmdwcdztze,shkd_entryentity.shkd_xmhtsxr," +
"shkd_entryentity.shkd_yjxmxjljlrhjs,shkd_entryentity.shkd_sjjzdtbyfxjljlrhjs,shkd_entryentity.shkd_xmhzqx," +
"shkd_entryentity.shkd_snxjljlr,shkd_entryentity.shkd_yjxnxjljlr,shkd_entryentity.shkd_sjrq",
new QFilter("id", QCP.not_equals, 0L).toArray());
logger.info("查询数据长度{}{}", dynamicObjects.length, dynamicObjects[0]);
// 创建一个空的DataSet 将DynamicObjectCollection转化为DataSet
Collection<Object[]> coll = new ArrayList<>();//报表展示数据
// 遍历修改后的数据的所有字段
List<String> displayFields = new ArrayList<>();//列标识
displayFields.add("shkd_ssjtbm");// 所属集团编码
displayFields.add("shkd_ssjtmc");// 所属集团名称
displayFields.add("shkd_xmdwbm");// 项目单位编码
displayFields.add("shkd_xmdwmc");// 项目单位名称
displayFields.add("shkd_xmbm");// 项目编码
displayFields.add("shkd_xmmc");// 项目名称
displayFields.add("shkd_xmdwcdztze");// 项目单位承担总投资额
displayFields.add("shkd_xmhtsxr");// 项目合同生效日
displayFields.add("shkd_yjxmxjljlrhjs");// 预计项目现金流净流入合计数
displayFields.add("shkd_sjjzdtbyfxjljlrhjs");// 实际截止到填报月份现金流净流入合计数
displayFields.add("shkd_xmhzqx");// 项目合作期限
displayFields.add("shkd_snxjljlr");// 上年现金流净流入
displayFields.add("shkd_yjxnxjljlr");// 预计下年现金流净流入
displayFields.add("shkd_sjrq");// 数据日期
for (DynamicObject dataRow : dynamicObjects) {
DynamicObject shkd_xm = dataRow.getDynamicObject("shkd_xm");
DynamicObjectCollection dynamicObjectCollection = dataRow.getDynamicObjectCollection("shkd_entryentity");
for (DynamicObject dynamicObject : dynamicObjectCollection) {
Date shkdSjrq = dynamicObject.getDate("shkd_sjrq");
if (dateValue == null || shkdSjrq.compareTo(dateValue) <= 0) {
Object[] objects = new Object[displayFields.size()];
for (int i = 0; i < displayFields.size(); i++) {
switch (displayFields.get(i)) {
case "shkd_ssjtbm":
objects[i] = dataRow.get("shkd_ssjtbm");
break;
case "shkd_ssjtmc":
objects[i] = dataRow.get("shkd_ssjtmc");
break;
case "shkd_xmdwbm":
objects[i] = shkd_xm.get("shkd_xmdwbm");
break;
case "shkd_xmdwmc":
objects[i] = shkd_xm.get("shkd_xmdwmc");
break;
case "shkd_xmbm":
objects[i] = shkd_xm.get("shkd_lcxmbm");
break;
case "shkd_xmmc":
objects[i] = shkd_xm.get("name");
break;
case "shkd_xmdwcdztze":
Object shkd_xmdwcdztze = dynamicObject.get("shkd_xmdwcdztze");
if (shkd_xmdwcdztze != null) {
BigDecimal bd = new BigDecimal(shkd_xmdwcdztze.toString());
objects[i] = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
} else {
objects[i] = shkd_xmdwcdztze;
}
break;
case "shkd_xmhtsxr":
objects[i] = dynamicObject.getDate("shkd_xmhtsxr");
break;
case "shkd_yjxmxjljlrhjs":
Object shkd_yjxmxjljlrhjs = dynamicObject.get("shkd_yjxmxjljlrhjs");
if (shkd_yjxmxjljlrhjs != null) {
BigDecimal bd = new BigDecimal(shkd_yjxmxjljlrhjs.toString());
objects[i] = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
} else {
objects[i] = shkd_yjxmxjljlrhjs;
}
break;
case "shkd_sjjzdtbyfxjljlrhjs":
Object shkd_sjjzdtbyfxjljlrhjs = dynamicObject.get("shkd_sjjzdtbyfxjljlrhjs");
if (shkd_sjjzdtbyfxjljlrhjs != null) {
BigDecimal bd = new BigDecimal(shkd_sjjzdtbyfxjljlrhjs.toString());
objects[i] = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
} else {
objects[i] = shkd_sjjzdtbyfxjljlrhjs;
}
break;
case "shkd_xmhzqx":
objects[i] = dynamicObject.get("shkd_xmhzqx");
break;
case "shkd_snxjljlr":
Object shkd_snxjljlr = dynamicObject.get("shkd_snxjljlr");
if (shkd_snxjljlr != null) {
BigDecimal bd = new BigDecimal(shkd_snxjljlr.toString());
objects[i] = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
} else {
objects[i] = shkd_snxjljlr;
}
break;
case "shkd_yjxnxjljlr":
Object shkd_yjxnxjljlr = dynamicObject.get("shkd_yjxnxjljlr");
if (shkd_yjxnxjljlr != null) {
BigDecimal bd = new BigDecimal(shkd_yjxnxjljlr.toString());
objects[i] = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
} else {
objects[i] = shkd_yjxnxjljlr;
}
break;
case "shkd_sjrq":
objects[i] = dynamicObject.getDate("shkd_sjrq");
break;
}
}
coll.add(objects);
}
}
}
DataType stringType = DataType.StringType;//字符串
DataType dateType = DataType.DateType;//日期
DataType integerType = DataType.IntegerType;//整数
List<DataType> dataTypes = new ArrayList<>();//列类型
for (String field : displayFields) {
switch (field) {
case "shkd_ssjtbm":
dataTypes.add(stringType);
break;
case "shkd_ssjtmc":
dataTypes.add(stringType);
break;
case "shkd_xmdwbm":
dataTypes.add(stringType);
break;
case "shkd_xmdwmc":
dataTypes.add(stringType);
break;
case "shkd_xmbm":
dataTypes.add(stringType);
break;
case "shkd_xmmc":
dataTypes.add(stringType);
break;
case "shkd_xmdwcdztze":
dataTypes.add(stringType);
break;
case "shkd_xmhtsxr":
dataTypes.add(dateType);
break;
case "shkd_yjxmxjljlrhjs":
dataTypes.add(stringType);
break;
case "shkd_sjjzdtbyfxjljlrhjs":
dataTypes.add(stringType);
break;
case "shkd_xmhzqx":
dataTypes.add(integerType);
break;
case "shkd_snxjljlr":
dataTypes.add(stringType);
break;
case "shkd_yjxnxjljlr":
dataTypes.add(stringType);
break;
case "shkd_sjrq":
dataTypes.add(dateType);
break;
}
}
RowMeta rowMeta = RowMetaFactory.createRowMeta(displayFields.toArray(new String[0]), dataTypes.toArray(new DataType[0]));
CollectionInput inputs = new CollectionInput(rowMeta, coll);
try {
finish = Algo.create(this.getClass().getName()).createDataSet(inputs);
} catch (Exception e) {
logger.error("数据集创建失败:{}", e.getMessage());
}
return finish;
}
/**
* 获取报表所有过滤条件
*
* @param reportQueryParam
* @return
*/
public List<QFilter> getListQFilter(ReportQueryParam reportQueryParam) {
//过滤条件数组
List<QFilter> qFilters = new ArrayList<>();
//初始化过滤数据
List<FilterItemInfo> filterItems = reportQueryParam.getFilter().getFilterItems();
if (CollectionUtils.isNotEmpty(filterItems)) {
for (FilterItemInfo info : filterItems) {
//获取过滤字段名 获取比较符 获取过滤比较值
qFilters.add(new QFilter(info.getPropName(), QCP.equals, info.getValue()));
}
}
//快速过滤
FastFilter fastFilter = reportQueryParam.getFilter().getFastFilter();
if (fastFilter != null) {
List<QFilter> qFilters1 = fastFilter.getQFilters();
if (CollectionUtils.isNotEmpty(qFilters1)) {
qFilters.addAll(qFilters1);
}
}
return qFilters;
}
}