套打.二开案例.使用临时单据数据包套打打印
【场景】使用临时数据包进行套打打印
系统中基本所有的套打打印都是使用的数据库访问取数实现的,包括账表、单据。
因此当单据数据没有保存的时候原则上是打印不了的,在历史场景中只能通过干预打印数据包将自己的临时数据写入到数据包;
但是二开非常繁琐,而且字段类型也比较多。
因此提供一个基于数据包打印的二开方案
【支持版本】
2021.09
【补充说明】
(1)因为不是用的真实的单据,所以单据关联的数据也不会有,如工作流、附件都是打印不了的
(2)该功能暂不支持动态字段计算
(3)不支持基础资料属性,需要将基础资料属性改为绑定基础资料中的子字段
(4)仅支持普通连续套打,不支持合并、节纸
(4)如果是案例本身的使用当前数据包打印,需要勾选菜单点击时提交数据,不然部分文本字段前端不会回传给服务端
![image.webp](/download/010021cdb350f00f40638003b7619361dd21.webp)
【案例】
![image.webp](/download/01003de7a7852b904e70b226e1697e634436.webp)
```csharp
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Const;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.NotePrint;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DynamicFormPlugIn.NotePrint
{
[Kingdee.BOS.Util.HotUpdate]
public class NotePrintPlugIn_UseCustomDataObj : AbstractBillPlugIn
{
public override void BarItemClick(BarItemClickEventArgs e)
{
if(e.BarItemKey.EqualsIgnoreCase("tb_PrintTmpDataObj"))
{
PrintTmpDataObj();
}
}
private void PrintTmpDataObj()
{
var dataObj = this.View.Model.DataObject;
string formId = this.View.BillBusinessInfo.GetForm().Id;
string templateId = "0e05e45a-1368-46fb-86a3-e65669d321ca";
var dataObjPageItem = PageItem.CreatePageItem(templateId, dataObj) as DataObjPageItem;
/// <summary>
/// 重新生成内码
/// <remarks>
/// 为数据包中的所有单据数据覆盖其内码值,默认覆盖(true)
/// 通常这个参数用来解决数据包中内码为0的问题(默认的,数据包直接实例化时内码为0),导致没有层级关系
/// 在部分场景下,当需要在套打干预数据包插件干预数据使用内码时,设置此参数为false,套打时仅对传入的数据包进行拷贝处理
/// </remarks>
/// </summary>
dataObjPageItem.RebuildPk = true;
//数据包无论怎样都进行拷贝,确保不影响内存数据
DynamicObject customData = CopyAndPreparePrintData(this.View.BillBusinessInfo, dataObjPageItem);
DynamicObjectCollection customDataCol = new DynamicObjectCollection(customData.DynamicObjectType);
customDataCol.Add(customData);
//构造使用数据包的打印任务
PrintJobItem jobItem = new PrintJobItem(ObjectUtils.Object2String(customData[0]),
dataObjPageItem.TemplateId);
List<PrintJobItem> jobItemList = new List<PrintJobItem>() { jobItem };
PrintJob printJob = new PrintJob() { PrintJobItems = jobItemList, FormId = formId, };
printJob.UserDefineData = customDataCol;//使用自定义数据包的逻辑
string printActionKey = Guid.NewGuid().ToString();
string printType = "preview";//"print"
var printJobList = new List<PrintJob> { printJob };
//生成打印页面,支持通过使用这个接口改造为异步,这个接口完成代表服务端页面生成完了
var printService = new Kingdee.BOS.Web.Printing.NotePrintService();
printService.GenerateBackgroundReport(this.View, printActionKey, printType, printJobList, null);
//通知前端获取套打页面打印
NoteTemplateOperation(printActionKey, printType);
}
/// <summary>
/// 发送套打打印指令给前端
/// </summary>
/// <param name="printJobId"></param>
/// <param name="printType"></param>
/// <param name="printer"></param>
/// <param name="printBarName"></param>
private void NoteTemplateOperation(string printJobId, string printType, object printer = null, string printBarName = null)
{
JSONObject jsonObj = new JSONObject();
jsonObj.Put("pageID", this.View.PageId);
jsonObj.Put("printJobId", printJobId);
jsonObj.Put("action", printType);
string action = string.Empty;
if (printType.EqualsIgnoreCase("preview") || printType.EqualsIgnoreCase("PrintMergePreview"))
{
action = JSAction.printPreview;
jsonObj.Put("printBarName", printBarName);
}
else if (printType.EqualsIgnoreCase("print") || printType.EqualsIgnoreCase("PrintMerge"))
{
action = JSAction.print;
}
//解决前端打印预览点击打印时缺少指定打印机问题
//修改NotePrintService.GetPrintInfo()无效,需要由该处指定
//前端对应代码,以客户端为例KDNoteReportPlugInProxyWPF.PrintNoteBatchPage,本质上是以整个服务代码的初始化打印地址进行打印,因此在这里实现
jsonObj.Put("printerAddress", printer.IsNullOrEmpty() == true ? string.Empty : Convert.ToString(printer));
this.View.AddAction(action, jsonObj);
}
internal struct EntityDataCollection
{
public Entity CurEntity;
public DynamicObjectCollection ObjCollection;
public EntityDataCollection(Entity entity, DynamicObjectCollection data)
{
CurEntity = entity;
ObjCollection = data;
}
}
/// <summary>
/// 如果数据包没有默认主键,则建议进行深拷贝并补充填入主键,以便系统更好的匹配对应的数据关系(数据关系都是通过主外键关联)
/// </summary>
/// <param name="businessInfo"></param>
/// <param name="dataObjPageItem"></param>
/// <returns></returns>
private static DynamicObject CopyAndPreparePrintData(BusinessInfo businessInfo, DataObjPageItem dataObjPageItem)
{
DynamicObject dataObj = dataObjPageItem.DataObj;
DynamicObject customData = ObjectUtils.DeepClone<DynamicObject>(dataObj);
if (!dataObjPageItem.RebuildPk)
return customData;
HeadEntity headEntity = businessInfo.Entrys.FirstOrDefault(x => x is HeadEntity) as HeadEntity;
if (headEntity == null)
return customData;
Dictionary<Entity, int> entityPkVal = new Dictionary<Entity, int>();//当前实体的主键值
Dictionary<Entity, List<Entity>> entityParEntity = new Dictionary<Entity, List<Entity>>();//当前实体和子实体
//记录实体关联关系
foreach (var entity in businessInfo.Entrys)
{
if (entity is SubEntryEntity)
{
Entity parEntity = (entity as SubEntryEntity).ParentEntity;
if (!entityParEntity.ContainsKey(parEntity))
entityParEntity[parEntity] = new List<Entity>();
entityParEntity[((SubEntryEntity)entity).ParentEntity].Add(entity);
}
else if (entity is SubHeadEntity || entity is EntryEntity)
{
if (!entityParEntity.ContainsKey(headEntity))
entityParEntity[headEntity] = new List<Entity>();
entityParEntity[headEntity].Add(entity);
}
}
List<string> billIds = new List<string>();
//数据包层级遍历,填充实体主键
Queue<EntityDataCollection> bfs = new Queue<EntityDataCollection>();
DynamicObjectCollection objColl = new DynamicObjectCollection(customData.DynamicObjectType);
objColl.Add(customData);
bfs.Enqueue(new EntityDataCollection(headEntity, objColl));
while (bfs.Count > 0)
{
EntityDataCollection entityData = bfs.Dequeue();
Entity curEntity = entityData.CurEntity;
if (!entityPkVal.ContainsKey(curEntity))
{
entityPkVal[curEntity] = 1;
}
bool stringPk = curEntity.PkFieldType == typeof(string);
foreach (DynamicObject obj in entityData.ObjCollection)
{
if (stringPk)
obj["Id"] = entityPkVal[curEntity].ToString();
else
obj["Id"] = entityPkVal[curEntity];
if (curEntity is HeadEntity)
{
billIds.Add(obj["Id"].ToString());//记录单据内码
}
++entityPkVal[curEntity];
if (!entityParEntity.ContainsKey(curEntity))
continue;
foreach (Entity childEntity in entityParEntity[curEntity])
{
if (!obj.DynamicObjectType.Properties.ContainsKey(childEntity.EntryName))
continue;
DynamicObjectCollection childObjCollection = obj[childEntity.EntryName] as DynamicObjectCollection;
if (childObjCollection == null || childObjCollection.Count <= 0)
continue;
bfs.Enqueue(new EntityDataCollection(childEntity, childObjCollection));
}
}
}
return customData;
}
}
}
```
【效果】
在新增界面使用当前界面数据包套打
![20240219 1126.webp](/download/0100ad79519174594baaa13074bea9d748e2.webp)
大佬您好,请教下在定时任务中对科目余额表的数据套打打印这个怎么做呢?
套打.二开案例.使用临时单据数据包套打打印
【场景】使用临时数据包进行套打打印系统中基本所有的套打打印都是使用的数据库访问取数实现的,包括账表、单据。因此当单据数据没有保存的...
点击下载文档
本文2024-09-16 18:11:29发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-20527.html
您需要登录后才可以发表评论, 登录登录 或者 注册
最新文档
热门文章