parent
bbb8917039
commit
7e8eb690cb
|
@ -1,4 +1,4 @@
|
|||
package shkd.sys.sys.plugin.report.util;
|
||||
package shkd.sys.sys.plugin.report;
|
||||
|
||||
import dm.jdbc.util.StringUtil;
|
||||
import kd.bos.cache.CacheFactory;
|
||||
|
@ -7,12 +7,17 @@ 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.datamodel.FmtField;
|
||||
import kd.bos.entity.report.AbstractReportColumn;
|
||||
import kd.bos.entity.report.IReportListModel;
|
||||
import kd.bos.entity.report.ReportColumn;
|
||||
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 org.apache.commons.io.FileUtils;
|
||||
import kd.bos.report.proxy.ReportListProxy;
|
||||
import shkd.sys.sys.plugin.report.util.CsvExportUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -22,9 +27,10 @@ import java.time.format.DateTimeFormatter;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ExportCSV extends AbstractReportFormPlugin {
|
||||
import static shkd.sys.sys.plugin.report.util.ReportUtils.processFieldValue;
|
||||
|
||||
public class ExportCSVReportFormPlugin extends AbstractReportFormPlugin {
|
||||
|
||||
@Override
|
||||
public void registerListener(EventObject e) {
|
||||
|
@ -34,45 +40,69 @@ public class ExportCSV extends AbstractReportFormPlugin {
|
|||
// 监听工具栏这个按钮的点击事件
|
||||
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();
|
||||
|
||||
List<String> keyHeaders = properties.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(IMetadata::getName)
|
||||
.collect(Collectors.toList());
|
||||
List<String> headers = properties.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(o -> Objects.nonNull(o.getDisplayName()))
|
||||
.map(o -> o.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()
|
||||
.filter(o -> !Objects.equals(o.getFieldName(), "fseq"))
|
||||
.map(FmtField::getFieldName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String timestamp = LocalDateTime.now()
|
||||
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
|
||||
// 构建属性名到显示名称的映射表,便于快速查找
|
||||
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));
|
||||
|
||||
int random = ThreadLocalRandom.current().nextInt(100, 1000); // 3 位随机数
|
||||
|
||||
String reportNameExt = timestamp + random;
|
||||
|
||||
IReportListModel reportList = ((ReportList) this.getControl("reportlistap")).getReportModel();
|
||||
int rowCount = reportList.getRowCount();
|
||||
|
||||
DynamicObjectCollection rowData = reportList.getRowData(0, rowCount, false);
|
||||
// 按照字段顺序获取对应的显示名称,缺失则使用空字符串
|
||||
List<String> headers = headerKeys.stream()
|
||||
.map(k -> nameToDisplay.getOrDefault(k, ""))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 构造每一行的数据列表,处理复杂对象的name属性及本地化
|
||||
List<List<?>> rows2 = rowData.stream()
|
||||
.map(obj -> keyHeaders.stream()
|
||||
.map(obj::get) // 使用 DynamicObject 的 get 方法获取属性值
|
||||
.map(obj -> headerKeys.stream()
|
||||
.map(key -> processFieldValue(obj.get(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 {
|
||||
// 定义本地测试目录和完整文件路径
|
||||
|
@ -84,8 +114,8 @@ public class ExportCSV extends AbstractReportFormPlugin {
|
|||
//
|
||||
// Path tempFile = dirPath.resolve(reportName + reportNameExt + ".csv");
|
||||
// CsvExportUtil.writeCsvToFile(tempFile, headers, rows2);
|
||||
//
|
||||
// // 打印文件路径用于本地验证
|
||||
|
||||
// 打印文件路径用于本地验证
|
||||
// System.out.println("CSV 文件已保存至: " + tempFile.toAbsolutePath());
|
||||
|
||||
Path tempFile = Files.createTempFile(reportName + reportNameExt, ".csv");
|
|
@ -49,4 +49,63 @@ public class ReportUtils {
|
|||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理字段值,支持简单值和复杂对象(如含name属性的对象)
|
||||
*
|
||||
* @param value 原始字段值
|
||||
* @return 处理后的字符串值
|
||||
*/
|
||||
public static Object processFieldValue(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 如果是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();
|
||||
}
|
||||
// // 尝试获取ZH_TW本地化值
|
||||
// Object zhTwValue = localizedObj.getClass().getMethod("get", String.class).invoke(localizedObj, "zh_TW");
|
||||
// if (zhTwValue != null) {
|
||||
// return zhTwValue.toString();
|
||||
// }
|
||||
|
||||
// 都没有则返回默认toString()
|
||||
return localizedObj.toString();
|
||||
} catch (Exception e) {
|
||||
// 异常情况下返回toString()
|
||||
return localizedObj.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue