由于现在所作得项目是mes,在这之中有很多得时候需要打印标签等。并且本人参与得项目中用的是JavaFx开发得客户端。在打印得时候开始得做法是点击按钮在JavaFx中弹出新的浏览器页面,然后再调用润乾本身得打印方式,但是润乾本身得打印方式还有较多局限,applet打印只能用再IE浏览器(其他浏览器屏蔽了Java插件),pdf等打印可以用在其他得浏览器。然后还要经过pdf预览页面最终才能打印出来。
用这样得方式十分不利于产线人员得操作。于是就想能不能直接调用打印机打印出来。后来发现此方法确实可行。但是现阶段还存在一定问题会在下文中解释。在web端的可以直接传入参数,然后在jsp页面中润乾报表会运算并进行展现报表。如果想要在jsp页面之外的地方展现报表就要先行计算好报表再用相应的控件接报表。
代码如下所示:
可以先用map传入参数值,map中的key需要完全与报表中的参数名一致
HashMap hashmap = new HashMap(); hashmap.put("id", msg.getText());
这里写了一个公用的方法,其中传入参数和报表文件的名称
public IReport report(HashMap hashmap,String file) throws Exception { File flic = new File(getClass().getClassLoader().getResource("WEB-INF/reportLicense.lic").toExternalForm().replace("file:/","")); FileInputStream lis = new FileInputStream(flic); Sequence.readLicense( Sequence.P_RPT, lis); ReportDefine rd = null; try { //红色地方为报表的文件位置可以是相对路径也可以是绝对路径 rd = (ReportDefine) ReportUtils.read(getClass().getClassLoader().getResource("WEB-INF/reportFiles/"+file).toExternalForm().replace("file:/","")); } catch (Exception e) { e.printStackTrace(); } //第二步,运算报表 Context context = new Context(); Connection con = null; try{ //此处配置数据库连接方式 Driver driver = (Driver) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); DriverManager.registerDriver(driver); //数据库地址和用户名密码 con= DriverManager.getConnection("jdbc:oracle:thin:@192.168.17.218:1","me","me"); }catch (Exception e){ e.printStackTrace(); } //增加DataSourceConfig配置 context.setDefDataSourceName("mesdb"); context.setConnection("mesdb", con); DataSourceConfig dsoc = new DataSourceConfig(DBTypes.getDBType("oracle"), true, "GBK", "GBK", false); context.setDataSourceConfig("mesdb", dsoc); context.setParamMap(hashmap); Engine enging = new Engine(rd, context); IReport report = enging.calc(); //最后返回运算好的报表文件 return report; }
可参考润乾的文档
http://doc.raqsoft.com.cn/report/preference/ysbb123.html
在开始阶段我想的方法是利用润乾导出pdf的功能先将pdf文件导出然后再读取导出的文件从而进行连接打印机打印
一些会用到的类
import java.io.*;
import com.raqsoft.report.usermodel.*;
import com.raqsoft.report.model.*;
import com.raqsoft.report.util.*;
import com.raqsoft.report.view.*;
import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import static com.raqsoft.report.view.ServletMappings.application;
代码如下:
//第一步,读取报表模板
InputStream reportFile = application.getResourceAsStream("/reportFiles/labelTemplate/beidanghistory.rpx");
//新建一个 HashMap对象存放参数,map可以存放空参数。传递参数时名称要保证和报表组用到的参数名一致。
HashMap map = new HashMap();
map.put("id", id);
ReportDefine rd = (ReportDefine) ReportUtils.read(reportFile);
//第二步,运算报表
Context context = new Context();
context.setParamMap(map);
Engine enging = new Engine(rd, context);
IReport report = enging.calc();
//导出
String fileName = "D:/beidanghistory.pdf";
ReportExporter re = new ReportExporter(fileName, ReportExporter.EXPORT_PDF_PAGE);
re.export(report);
reportFile.close();
//不同的导出文件的方式
//ReportUtils.exportToPDF(fileName, report, true, false);
//设置打印数据的格式,此处为图片PDF格式
//DocFlavor psInFormat = DocFlavor.INPUT_STREAM.PDF;
//自动选择格式,当文件格式不确定的时候可用
DocFlavor psInFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
//设置打印属性
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
//查找所有打印服务
PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset);
aset.add(new Copies(2));//打印份数,2份
// 定位默认的打印服务
//将所有查找出来的打印机与自己想要的打印机进行匹配,找出自己想要的打印机
PrintService myPrinter = null;
for (int i = 0; i < services.length; i++) {
String svcName = services[i].toString();
if (svcName.contains("Argox OS-214 plus series PPLA")) {
myPrinter = services[i];
break;
}
}
FileInputStream psStream = new FileInputStream(new File("D:/history.pdf"));
if (psStream == null) {
return;
}
if (myPrinter != null) {
//创建打印数据
Doc myDoc = new SimpleDoc(psStream, psInFormat, null);
DocPrintJob job = myPrinter.createPrintJob();//创建文档打印作业
job.print(myDoc, aset);//打印文档
} else {
System.out.println("no printer services found");
}
}
但是此处我不清楚哪里写的不对,用打印机打印出一堆代码,但是本人觉得这个方式应该可行,仅供参考。而且项目负责人说(本人刚毕业小白)这样的话传输文件流会占用大量带宽,而且当项目部署到服务器上也需要判断哪个电脑想要用打印。
然后就用了另一个办法(再询问了润乾客服好久后得出的)
润乾报表本身带了一个打印方法可以直接用Java代码去掉用类中的方法,然后即可打印
再下的ReportUtils2.class中有print方法。可以直接把运算好的report作为参数传入到这个方法中即可实现打印。
本人现在遇到的问题是,再客户端不可以直接让润乾报表连接服务器去运算。然后就想我再客户端通过webservice传报表模板和参数再服务端运算好,把算好的报表返还给客户端,然后调用打印方法。悲伤的是
服务端
IReport report = enging.calc(); map.put("report", report); return JsonMapper.toJsonString(map);
客户端
String result = WebServiceUtil.getResult("backUpWebservice", "printRunQian", map); JSONObject jsonObject = new JSONObject(result); IReport report = (IReport) jsonObject.get("report");
客户端接收到的是null ,大佬说是应为report不能序列化,于是我也就不懂了,然后,然后就没啥然后了