EAS套打接口生成PDF文件
一、业务场景
大部分情况下,套打服务于业务单据的打印,例如在客户端、浏览器打印费用报销单。打印之前需要先选择相应的套打模板或者是使用用户先前设定的默认模板。有些客户场景想要将套打预览的内容生成pdf文件或图片保存在EAS系统或者推送到一些企业内部集成的系统进行统一管理,这个时候我们需要灵活的使用套打相关的接口来实现这个操作。
二、实践思路
首先,我们要清楚EAS现有的打印实现。EAS在客户端和web端都支持打印,但是二者的原理存在一定的差异。如图所示:
可以得知:
客户端的打印逻辑是完全运行在客户端的本地的。客户端的打印支持打印预览、打印机的直接调用,支持导出pdf,excel两个额外功能。
浏览器的打印逻辑是运行在服务器的,浏览器的打印本质上是EAS后台生成pdf文件,然后调用浏览器本身插件渲染pdf,调用打印机打印是浏览器行为,不是由EAS发起。
因此,客户端和web端打印的数据源实现思路就不一样,如果是客户端打印,数据源由于在客户端的上下文运行,需要采用getRemoteInstance的方法调用服务端来取数,web端的打印由于是在后台Controller层面运行,需要取得web框架的上下文再取数,例如WafContext.getInstance().getContext()。以凭证打印为例,客户端打印的数据源是com.kingdee.eas.fi.gl.VoucherRowSetProvider ,可以通过凭证列表界面代码跟踪:
web打印的数据源是:com.kingdee.eas.fi.gl.web.voucher.controller.VoucherQueryDelegate,可以通过浏览器F12打开开发者工具捕获网络请求参数来跟踪:
两者实现不可复用,两个类所在的jar包的位置也不一样。
因此要实现此功能需要考虑扩展代码运行的环境:
扩展代码写在客户端或者是Controller,则可以完全利用已有的单据打印逻辑来实现,只需要改动一点参数即可实现
扩展代码写在服务端ControllerBean或者是ControllerBeanEx类,有两种方案
a.则自己实现业务的打印数据源来实现,或者是改造已有数据源
b.模拟web登录打印
三、详细设计
打印接口类:
客户端和服务端:com.kingdee.bos.ctrl.report.forapp.kdnote.client.KDNoteHelper
web端:com.kingdee.bos.ctrl.report.forapp.kdnote.webserver.KDNoteWebServerHelper
KDNoteWebServerHelper 继承 KDNoteHelper,提供了web上下文的方法覆写
导出pdf方法:
outputPdf(String,Object,OutputStream)
参数说明 | 描述 |
templatePath | 套打模板对应的全路径 |
dataProvider | 打印数据源 |
out | pdf输出流,根据场景设定流 |
详细方案原理:
运行环境 | 方案原理 |
客户端或Controller层面 | templatePath : 配置文件或写死 dataProvider: 复用业务已有数据源 out:文件或内存缓存流,可直接转byte数组 |
服务端ControllerBean或者是ControllerBeanEx | templatePath : 配置文件或写死 dataProvider: 需要改造已有数据源 out:文件或内存缓存流,可直接转byte数组 |
四、代码样例
以权限申请单为例,样例中数据写死,可以根据参数来设置
客户端直接生成pdf:
/**
* 客户端打印,直接使用已有数据源
*/
public static byte[] exportPdfWithProviderForClient(String template,String billId) throws Exception {
String templatePath = "/EM/SM/PM/PRMREQ/PERREQPRINT.r1-print";
List ids = new ArrayList<String>();
ids.add("M25HxqTATrCO1FNahgAx6HtQXsI=");
com.kingdee.eas.base.permission.client.helper.PermissionReqBillPrintDataProvider dataProvider
= new com.kingdee.eas.base.permission.client.helper.PermissionReqBillPrintDataProvider (ids);
ByteArrayOutputStream out = new ByteArrayOutputStream();
KDNoteHelper kdNoteHelper = new KDNoteHelper();
kdNoteHelper.outputPdf(templatePath,dataProvider,out);
//写到临时目录查看pdf文件是否正确,在EAS客户端安装目录
String eas_home = System.getProperty("EAS_HOME");
FileOutputStream fout = new FileOutputStream(eas_home+ File.separator+"test.pdf");
fout.write(out.toByteArray());
fout.flush();
fout.close();
return out.toByteArray();
}
服务端生成pdf:
/**
* 普通打印下载pdf,ControllerBean已登录,样例权限申请单
* 因为后台无法使用标准权限申请单的数据源, com.kingdee.eas.base.permission.client.helper.PermissionReqBillPrintDataProvider
* 这是在客户端的类,后台无法直接使用
*/
public static byte[] exportPdfWithProvider(Context ctx, String template,String billId) throws Exception {
Map oldEnvContext= GeniusBOSFactory.getCurrentServiceEnv();
try{
//设置ctx到rpc框架使得下面的代码可以使用getRemoteInstance
Map envContext = new HashMap();
envContext.put(GeniusBOSFactory.ENV_KEY_URL, GeniusBOSFactory.URL_LOCAL);
envContext.put(GeniusBOSFactory.ENV_KEY_BOSCTX, ctx);
GeniusBOSFactory.setEnvContext(envContext);
String templatePath = "/EM/SM/PM/PRMREQ/PERREQPRINT.r1-print";
List ids = new ArrayList<String>();
ids.add("M25HxqTATrCO1FNahgAx6HtQXsI=");
PermissionReqBillPrintDataProvider dataProvider = new PermissionReqBillPrintDataProvider(ids);
ByteArrayOutputStream out = new ByteArrayOutputStream();
KDNoteHelper kdNoteHelper = new KDNoteHelper();
kdNoteHelper.outputPdf(templatePath,dataProvider,out);
//写到临时目录查看pdf文件是否正确,在server1..n/bin 目录
FileOutputStream fout = new FileOutputStream("test.pdf");
fout.write(out.toByteArray());
fout.flush();
fout.close();
return out.toByteArray();
}catch(Exception e){
e.printStackTrace();
throw e;
}finally {
GeniusBOSFactory.setEnvContext(oldEnvContext);
}
}
注意:
GeniusBOSFactory.setEnvContext(envContext);这一行代码意味着允许在服务器的ControllerBean调用getRemoteInstance方法,rpc会自动识别并转换为getLocalInstance方法调用,因为很多客户端的业务数据源都是基于客户端来写的,如果设置了这一行则很多客户端的打印数据源可以直接在服务器使用(前提是类能够被服务端加载)。
由于权限单标准打印数据源是客户端的代码,因此我需要将sp-bs_permission-client.jar复制一份到server/lib/sp目录,这样就可以在服务器加载到对应的数据源。
五、注意事项
注意生成文件如果使用内存流存储,可能会导致内存占用过大,需要预估文件大小和并发量。
六、补丁影响
无
EAS套打接口生成PDF文件
本文2024-09-22 20:13:38发表“eas cloud知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-eas-112262.html