打印模板实现动态列的介绍(以差旅报销场景为例)

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

打印模板实现动态列的介绍(以差旅报销场景为例)

1. 案例介绍

    在打印差旅报销单时,因为“差旅项目名称”的数据是不确定的,根据出差行程不同差旅项目也不同,如飞机、住宿费市内交通费在内的费用项目我们希望“差旅项目名称”分录行的数据转为新的列,新增的列展示对应项目的报销金额,从而我们可以直观的看到各类差旅项目对应的报销金额

2. 适用版本

金蝶云苍穹 V5.0.002及以上版本

3. 模板配置

3.模板设计

    添加数据表格绑定“行程信息”单据体字段,“差旅项目名称”一列宽度设置为30mm且数据表格右边为新增列预留一定宽度

3.注册插件

    创建插件类Row2ColPlugin并继承AbstractPrintPlugin打印插件基类。(基类全路径kd.bos.print.core.plugin.AbstractPrintPlugin),随后在打印模板中注册该插件。

4. 插件开发

Java

 

public class Row2ColPlugin extends AbstractPrintPlugin {


   //需动态添加的列的标题

   private List<String> addCols = new ArrayList<>(10);


   //单据体(行程信息)

   private static final String ENTRY_ENTITY = "entryentity";


   //子单据体(费用项目)

   private static final String SUB_ENTRY_ENTITY = "subentryentity";


   //差旅项目名称

   private static final String EXPENSE_ITEM_NAME = "expenseitem.name";


   //报销金额

   private static final String TRIP_AMOUNT = "tripamount";


   //子单据体数据源标识

   private static final String DS_SUB_ENTRY = "er_tripreimbursebill2.subentryentity";


   //字段拼接符

   private static final String FIELD_JOIN_MARK = "_";


   //被转换的行所在列的列下标

   private static final int deleteColIndex = 3;


   //被转换的行所在列的宽度 300 = 30mm

   private static final int deletedColWidth = 300;



   @Override

   public void afterLoadData(AfterLoadDataEvent evt) {

       //获取子单据体记录

       List<DataRowSet> subRows = evt.getDataRowSets().stream()

               .flatMap(fMap -> fMap.getCollectionField(ENTRY_ENTITY).getValue().stream())

               .flatMap(fMap -> fMap.getCollectionField(SUB_ENTRY_ENTITY).getValue().stream())

               .collect(Collectors.toList());

       //获取需动态添加的列的标题

       addCols = subRows.stream()

               .map(m -> m.getField(EXPENSE_ITEM_NAME).getValue().toString())

               .distinct()

               .collect(Collectors.toList());

       for (DataRowSet subRow : subRows) {

           //为新加入的列添加字段绑定

           Field tripAmount = subRow.getField(TRIP_AMOUNT);

           for (String col : addCols) {

               if (col.equals(subRow.getField(EXPENSE_ITEM_NAME).getValue().toString())) {

                   subRow.put(EXPENSE_ITEM_NAME + FIELD_JOIN_MARK + col, tripAmount);

               } else {

                   //当前行没有该差旅项目,则报销金额为0

                   final Field copyField = tripAmount.copy();

                   copyField.setValue(BigDecimal.ZERO);

                   subRow.put(EXPENSE_ITEM_NAME + FIELD_JOIN_MARK + col, copyField);

               }

           }

       }


   }


   @Override

   public void beforeOutputWidget(BeforeOutputWidgetEvent evt) {

       if (evt instanceof BeforeOutputGridEvent) {

           BeforeOutputGridEvent gridEvent = (BeforeOutputGridEvent) evt;

           //计算新增列的列宽,新增列宽 = (空余范围宽度 + 被删除列宽度)/ 新增列数

           int avgWidth = (gridEvent.getRightSpace() + deletedColWidth) / addCols.size();

           //删除差旅项目名称列

           gridEvent.delColumn(deleteColIndex);

           //新增的列从被删除列位置开始插入

           int index = deleteColIndex;

           for (String addCol : addCols) {

               final List<PWGridCellBo> cellBos = gridEvent.insertColumn(index++, avgWidth);

               //获取新增列的标题行对应单元格,赋值为列标题名称

               cellBos.get(0).setCellValue(addCol);

               //获取新增列数据行对应的单元格,并绑定afterLoadData中添加的字段

               cellBos.get(1).setCellValue(DS_SUB_ENTRY, EXPENSE_ITEM_NAME + FIELD_JOIN_MARK + addCol);

           }

       }

   }

}

5. 效果预览

5.1 开发前效果

    未开发前,每行展示差旅项目和报销金额

5.2 开发后效果

    开发后,实现了行转列,“差旅项目名称”列中的值“飞机”、“住宿费”和“市内交通费”被转为新增列,每列展示该项目下的报销金额,没有则不展示

5.3 拓展:结合合并汇总功能

    数据表格如果配置了合并汇总,则可以更直观的看到每趟行程每条项目的费用信息,以及总费用金额。合并汇总也可以根据业务场景不同,选择不同的合并汇总字段,将多行数据合并为一行展示。


打印模板实现动态列的介绍(以差旅报销场景为例)

1. 案例介绍 在打印差旅报销单时,因为“差旅项目名称”的数据是不确定的,根据出差行程不同差旅项目也不同,如飞机、住宿费和市内交通...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息