本文介绍了两种情况下如何在数据表格中输出动态内容的方法。第一种是针对列数固定但不同用户对应不同字段权限的场景,通过套打干预数据包动态绑定字段。第二种是针对列数不固定的情况,如根据物料的辅助属性生成动态列,并通过数据表格动态列接口处理,包括配置套打模板、调整动态列、干预数据包等步骤。文章还提到动态列的一些限制和注意事项,如不支持自定义列宽调整,提供了示例代码实现动态列和干预数据包的逻辑。
针对数据表格输出动态内容包括两种情况:
<1>数据表格列数是固定的,只是不同场景下对应的取值字段不一样,如
单据上有采购数量A和采购数量B两个字段,用户1仅对采购数量A有权,用户B仅对采购数量B有权,他们想在一个模板上打印采购数量字段,这个时候就可以通过套打干预数据包,绑定一个动态字段,判断当前上下文的用户是否对字段有权从而填入套打数据包中;又或者是账表中业务实现的动态列——多栏式明细账,也可以通过这个处理。参考【套打】python插件加二开字段实现自定义功能
<2>数据表格列数是非固定的,可多可少,根据不同数据列数不一样,如
单据的分录上的物料有辅助属性尺码,针对同一个物料的尺码有不同的采购数量,打印想将同一个物料下的放在同一行,如下图所示。
针对第二种输出动态内容的场景,我们提供的方案是使用数据表格动态列。
<0>数据准备
<1>配置套打模板
<2>表单插件
表单插件的处理逻辑
①套打动态列调整接口:首先针对物料分组,然后计算尺码下的数量,根据尺码的类型生成动态列的数量
②套打数据包干预接口:根据调整的动态列字段以及准备好的物料-尺码-数量字典,生成新的数据包实体以及填充数量
以上实现关联的辅助属性数据包参考获取辅助属性内容;套打数据包干预套打数据包干预
<3>效果
注意事项:
<1>动态列为对当前列宽平分到所有子列上,目前还不支持自定义列宽调整(考虑到不支持超出模板外部导致打印时的打印机异常问题)
<2>支持设置统计字段,参考属性,示例后续补充
<3>当数据表格位于布局表格容器内,需要设置标识(考虑兼容问题)
代码:
[Kingdee.BOS.Util.HotUpdate]
public class NotePrintDynamicColumnEdit : AbstractDynamicFormPlugIn
{
/// <summary>
/// 数据源标识
/// </summary>
private string DataSoruecId = "FPOOrderEntry";
/// <summary>
/// 数据表格标识
/// </summary>
private string DataGridId = "dataGrid1";
/// <summary>
/// 动态列标识
/// </summary>
private string DynamicColumnId = "column3";
/// <summary>
/// 套打动态列干预接口
/// </summary>
/// <param name="e"></param>
public override void OnQueryDynamicColumns(QueryDynamicColumnsEventArgs e)
{
base.OnQueryDynamicColumns(e);
if (e.DataGridId == DataGridId && e.DynamicColumnId == DynamicColumnId && e.DataSourceId == DataSoruecId)
{
InitMaterialSizeCntMap();
if (sizeSet.Count == 0)
return;
var orderSizeList = sizeSet.ToList();
orderSizeList.Sort();
List<DynamicColumn> dynamicCols = new List<DynamicColumn>();
//创建以"NotePrint_Size"的自定义取值标识,用作绑定数据包显示
foreach (var sizeItem in orderSizeList)
{
var dyanmicColumn = new DynamicColumn()
{
Caption = sizeItem == -1 ? "未定义" : string.Format("尺码{0}", sizeItem),
FieldKey = string.Format("NotePrint_{0}", sizeItem),
IsStatistic = false
};
dynamicCols.Add(dyanmicColumn);
}
e.DynamicColumns = dynamicCols;
}
}
private string OrmKey_MaterialId = "MaterialId_Id";
private string OrmKey_Flex = "AuxPropId";
private string OrmKey_Size = "F100004";
private string OrmKey_Qty = "Qty";
private HashSet<int> sizeSet = new HashSet<int>();
private Dictionary<int, Dictionary<int, int>> idSizeCntMap = new Dictionary<int, Dictionary<int, int>>();
/// <summary>
/// 以表单插件为例,初始化物料-尺寸-采购数量字典
/// </summary>
private void InitMaterialSizeCntMap()
{
sizeSet = new HashSet<int>();
idSizeCntMap = new Dictionary<int, Dictionary<int, int>>();
Entity entity = this.View.BillBusinessInfo.GetEntryEntity(DataSoruecId);
if (entity == null)
return;
DynamicObjectCollection entityObjectCollection = this.View.Model.GetEntityDataObject(entity);
foreach (var entityRow in entityObjectCollection)
{
int materialId = ObjectUtils.Object2Int(entityRow[OrmKey_MaterialId]);
int qty = ObjectUtils.Object2Int(entityRow[OrmKey_Qty]);
int size = -1;
DynamicObject flexDynamicObject = entityRow[OrmKey_Flex] as DynamicObject;
if (flexDynamicObject != null)
{
size = ObjectUtils.Object2Int(flexDynamicObject[OrmKey_Size], -1);
}
if (!idSizeCntMap.ContainsKey(materialId))
{
idSizeCntMap[materialId] = new Dictionary<int, int>();
}
if (!idSizeCntMap[materialId].ContainsKey(size))
{
idSizeCntMap[materialId][size] = 0;
}
idSizeCntMap[materialId][size] += qty;
sizeSet.Add(size);
}
}
private string FieldKey_MaterialId = "FMaterialId_Id";
/// <summary>
/// 套打干预数据包接口
/// </summary>
/// <param name="e"></param>
public override void OnPrepareNotePrintData(PreparePrintDataEventArgs e)
{
base.OnPrepareNotePrintData(e);
if (!e.DataSourceId.EqualsIgnoreCase(DataSoruecId) || e.DataObjects.Length == 0)
return;
if (sizeSet.Count == 0 || idSizeCntMap.Count == 0)
return;
var objectType = e.DynamicObjectType;
foreach (var sizeItem in sizeSet)
{
var key = string.Format("NotePrint_{0}", sizeItem);
objectType.RegisterProperty(key, typeof(string));
}
List<DynamicObject> displayData = new List<DynamicObject>();
HashSet<int> fillMaterialSet = new HashSet<int>();
foreach (var dataRow in e.DataObjects)
{
var material = Convert.ToInt32(dataRow[FieldKey_MaterialId]);
if (fillMaterialSet.Contains(material))
continue;
fillMaterialSet.Add(material);
var newRow = new DynamicObject(objectType);
foreach (var prop in dataRow.DynamicObjectType.Properties)
{
newRow[prop] = dataRow[prop];
}
if (idSizeCntMap.ContainsKey(material))
{
foreach (var sizeQtyItem in idSizeCntMap[material])
{
var key = string.Format("NotePrint_{0}", sizeQtyItem.Key);
newRow[key] = sizeQtyItem.Value;
}
}
displayData.Add(newRow);
}
e.DataObjects = displayData.ToArray();
}
}
推荐阅读