提交人:陈绍鑫

日期:2025/9/28 12:00
内容:报表导出优化
This commit is contained in:
陈绍鑫 2025-09-28 12:03:41 +08:00
parent 0185778b1b
commit d68bebb440
1 changed files with 234 additions and 0 deletions

View File

@ -0,0 +1,234 @@
package shkd.sys.sys.plugin.report;
import dm.jdbc.util.StringUtil;
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.report.ReportList;
import kd.bos.report.plugin.AbstractReportFormPlugin;
import kd.bos.report.proxy.ReportListProxy;
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.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
public class AccountbankReportFormPlugin extends AbstractReportFormPlugin {
@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);
Map<String, Map<String, Object>> type = getType(reportListModel);
// 提取需要导出的字段名排除 fseq 字段
List<String> headerKeys = numberFormatProvider.getFmtFields().stream()
.filter(o -> !Objects.equals(o.getFieldName(), "fseq"))
.map(FmtField::getFieldName)
.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 -> this.processFieldValue(obj.get(key),type,key))
.collect(Collectors.toList()))
.collect(Collectors.toList());
// 生成时间戳和随机数作为文件名的一部分
String timestamp = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
int random = ThreadLocalRandom.current().nextInt(100, 1000); // 3 位随机数
String reportNameExt = timestamp + random;
try {
Path tempFile = Files.createTempFile(reportName + reportNameExt, ".csv");
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 Object processFieldValue(Object value,Map<String, Map<String, Object>> type,String key) {
if (value == null) {
return "";
}
String disString="";//展示的文本
//获取配置
Map<String, Object> stringObjectMap = type.get(key);
System.out.println(stringObjectMap);
String Stringtype = (String) stringObjectMap.get("type");
switch (Stringtype) {
case "DecimalReportColumn"://数值
int Scale= (int) stringObjectMap.get("value");
// 设置小数点后保留两位
BigDecimal roundedValue = ((BigDecimal)value).setScale(Scale, BigDecimal.ROUND_HALF_UP);
// 转换为字符串
disString= roundedValue.toString();
break;
case "ComboReportColumn"://下拉框
Map<String,String> Combomap= (Map<String, String>) stringObjectMap.get("value");
disString=Combomap.get(value);
break;
case "DateTimeReportColumn"://时间
// 获取当前日期
String Mask= (String) stringObjectMap.get("value");
if (Mask==null){
Mask="yyyy-MM-dd";
}
// 指定日期格式
SimpleDateFormat sdf = new SimpleDateFormat(Mask);
// 格式化日期
Timestamp timestamp = ((Timestamp) value);
// 使用getTime()方法将Timestamp转换为Date
disString = sdf.format(new Date(timestamp.getTime()));
break;
case "TextColumn"://文本
disString=value.toString();
break;
case "DynamicObjectColumn"://基础资料
String getDisplayProp= (String) stringObjectMap.get("value");
disString=((DynamicObject)value).getString(getDisplayProp);
break;
default:
disString="";
break;
}
return disString;
}
private Map<String, Map<String, Object>> getType(IReportListModel reportListModel){
Map<String, Map<String, Object>> map = new HashMap<>();
List<AbstractReportColumn> columnstype = reportListModel.getColumns();
for (AbstractReportColumn abstractReportColumn : columnstype) {
if (abstractReportColumn instanceof DecimalReportColumn) {
DecimalReportColumn reportColumn=(DecimalReportColumn)abstractReportColumn;
String fieldKey = reportColumn.getFieldKey();
Map<String,Object> map1 = new HashMap<>();
map1.put("type","DecimalReportColumn");
map1.put("value",reportColumn.getScale());
map.put(fieldKey,map1);
} else if (abstractReportColumn instanceof ComboReportColumn) {
ComboReportColumn reportColumn=(ComboReportColumn)abstractReportColumn;
String fieldKey = reportColumn.getFieldKey();
Map<String,String> column = new HashMap<>();
List<ValueMapItem> comboItems = reportColumn.getComboItems();
for (ValueMapItem comboItem : comboItems) {
column.put(comboItem.getValue(),comboItem.getName().getLocaleValue_zh_CN());
}
Map<String,Object> map1 = new HashMap<>();
map1.put("type","ComboReportColumn");
map1.put("value",column);
map.put(fieldKey,map1);
}else if (abstractReportColumn instanceof DateTimeReportColumn) {
DateTimeReportColumn reportColumn=(DateTimeReportColumn)abstractReportColumn;
String fieldKey = reportColumn.getFieldKey();
Map<String,Object> map1 = new HashMap<>();
map1.put("type","DateTimeReportColumn");
map1.put("value",reportColumn.getMask());
map.put(fieldKey,map1);
}else {
ReportColumn reportColumn=(ReportColumn)abstractReportColumn;
if ("text".equals(reportColumn.getFieldType())||"integer".equals(reportColumn.getFieldType())){
//文本
String fieldKey = reportColumn.getFieldKey();
Map<String,Object> map1 = new HashMap<>();
map1.put("type","TextColumn");
map1.put("value","TextColumn");
map.put(fieldKey,map1);
}else {
//基础资料
String fieldKey = reportColumn.getFieldKey();
Map<String,Object> map1 = new HashMap<>();
map1.put("type","DynamicObjectColumn");
map1.put("value",reportColumn.getDisplayProp());
map.put(fieldKey,map1);
}
}
}
return map;
}
}