JasperReports是一个基于Java的开源报表工具,可以在ireport中进行设计后,输出HTML,PDF,Excell,OpenOffice和Word格式。JasperReports支持applet方式打印,但是flash方式却是注释掉的。在net\sf\jasperreports\flex\view\Viewer.mxml文件中
<!--
<mx:Button width="22" toolTip="Print Report" id="btnPrintReport0"
buttonMode="true"enabled="false" >
<mx:icon>@Embed(source='images/print.GIF')</mx:icon>
</mx:Button>
<mx:Button width="22" toolTip="Print Report" id="btnReload"
buttonMode="true" enabled="true" click="btnReloadClick()">
<mx:icon>@Embed(source='images/reload.GIF')</mx:icon>
</mx:Button>
-->
本文主要完成JasperReports的flash打印功能,是基于JasperReports Flash Viewer 4.0.0修改,参考了网络上基于3.0版本的修改。将Viewer.mxml文件上面的文字修改为
<mx:Button width="22" toolTip="Print Report" id="btnPrintReport0"
buttonMode="true" enabled="false" click="btnPrintReport()">
<mx:icon>@Embed(source='images/print.GIF')</mx:icon>
</mx:Button>
<!--
<mx:Button width="22" toolTip="Print Report" id="btnReload"
buttonMode="true" enabled="true" click="btnReloadClick()">
<mx:icon>@Embed(source='images/reload.GIF')</mx:icon>
</mx:Button>
-->
在Viewer.mxml中找到refreshPage函数,启用打印按钮,将
if (report.pageCount > 0)
{
var pageCanvas:PageCanvas = new PageCanvas(report.pages[pageIndex]);
pageCanvas.scaleX = zoomRatio;
pageCanvas.scaleY = zoomRatio;
pageBox.visible = false;
pageBox.removeAllChildren();
pageBox.addChild(pageCanvas);
pageBox.visible = true;
}
修改为
if (report.pageCount > 0)
{
var pageCanvas:PageCanvas = new PageCanvas(report.pages[pageIndex]);
pageCanvas.scaleX = zoomRatio;
pageCanvas.scaleY = zoomRatio;
pageBox.visible = false;
pageBox.removeAllChildren();
pageBox.addChild(pageCanvas);
pageBox.visible = true;
btnPrintReport0.enabled = true;
}
在Viewer.mxml中引入net\sf\jasperreports\flex\view\PrintMananger.as文件,以支持打印
import net.sf.jasperreports.flex.view.PrintManager;
在Viewer.mxml增加打印函数btnPrintReport
public function btnPrintReport():void
{
PrintManager.printAll(jrpxmlUrl,pageFetchSize,report);
}
net\sf\jasperreports\flex\view\PrintMananger.as文件内容
package net.sf.jasperreports.flex.view
{
import flash.events.EventDispatcher;
import flash.events.SecurityErrorEvent;
import flash.events.Event;
import flash.events.ProgressEvent;
import mx.core.UIComponent;
import mx.collections.IList;
import mx.collections.ArrayCollection;
import net.sf.jasperreports.flex.view.PageCanvas;
import net.sf.jasperreports.flex.model.Report;
import net.sf.jasperreports.flex.xml.ReportFactory;
import flash.events.HTTPStatusEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
import mx.printing.FlexPrintJobScaleType;
import mx.printing.FlexPrintJob;
import mx.core.Application;
import mx.containers.VBox;
import mx.events.FlexEvent;
public class PrintManager extends EventDispatcher
{
private var url:String;
private var urlLoader:URLLoader;
private var report:Report;
private var pageIndex:int = 0;
private var pageFetchSize:int = 1;
private var componentsToBeInitialized:int = 0;
private var pagesPrint:Array = [];
public const LOAD_PAGE:String="loadPage";
public const ALL_PAGE:String = "allPageLoader";
public function PrintManager(){
super();
}
public function get url():String
{
return url;
}
public function set url(value:String):void
{
url=value;
}
public function set fetchSize(fetchSize:int):void
{
pageFetchSize = fetchSize;
}
public static function printAll(url:String,fetchSize:int,report:Report):void
{
var pm:PrintManager = new PrintManager();
pm.url = url;
pm.pageFetchSize = fetchSize;
pm.report = report;
pm.loadAll();
}
private function loadAll():void
{
this.addEventListener(LOAD_PAGE, onLoadPage);
this.addEventListener(ALL_PAGE, onAllPageLoaded);
pageIndex=0;
if (report)
{
var loadFlag:Boolean=false;
while (pageIndex < report.pageCount) {
if (!report.pages[pageIndex]) {
loadFlag=true;
break;
}
pageIndex++;
}
}
if (loadFlag) {
loadPage();
}
else{
removeEventListener(LOAD_PAGE, onLoadPage);
dispatchEvent(new Event(ALL_PAGE));
}
}
private function onLoadPage(e:Event):void
{
pageIndex++;
if (pageIndex < report.pageCount) {
if(!report.pages[pageIndex]){
loadPage();
}
}
else{
removeEventListener(LOAD_PAGE, onLoadPage);
dispatchEvent(new Event(ALL_PAGE));
}
}
public function onAllPageLoaded(event:Event):void
{
var cur:int;
var uc:UIComponent;
var pj:*;
if (report != null){
pj = new FlexPrintJob();
pj.printAsBitmap = false;
if (pj.start()){
cur = 0;
while (cur < report.pageCount) {
uc = processPage(new PageCanvas(report.pages[cur]));
Application.application.addChild(uc);
pj.addObject(uc);
Application.application.removeChild(uc);
cur++;
};
pj.send();
};
} else {
};
}
private function processPage(param1:PageCanvas):UIComponent{
var vbox:* = new VBox();
vbox.horizontalScrollPolicy = "off";
vbox.verticalScrollPolicy = "off";
vbox.width = report.pageWidth;
vbox.height = report.pageHeight;
vbox.setStyle("backgroundColor", "#FFFFFF");
vbox.addChild(param1);
return (vbox);
}
private function loadPage():void
{
urlLoader=new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(Event.OPEN, openHandler);
urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
if (report)
{
var goRight:Boolean = true;
var goLeft:Boolean = true;
var right:int = 0;
var left:int = 0;
while(goRight || goLeft)
{
if (
goRight
&& left + right + 1 < pageFetchSize
&& pageIndex + right + 1 < report.pageCount
&& !report.pages[pageIndex + right + 1]
)
{
right++;
}
else
{
goRight = false;
}
if (
goLeft
&& left + right + 1 < pageFetchSize
&& pageIndex - left - 1 >= 0
&& !report.pages[pageIndex - left - 1]
)
{
left++;
}
else
{
goLeft = false;
}
}
urlLoader.load(new URLRequest(url + "&startPage=" + (pageIndex - left) + "&endPage=" + (pageIndex + right)));
}
else
{
//first load; pageIndex == 0
urlLoader.load(new URLRequest(url + "&page=" + pageIndex));
}
}
private function completeHandler(event:Event):void
{
var newReport:Report = ReportFactory.create(XML(urlLoader.data));
var i:int;
var pages:IList;
if (report)
{
pages = report.pages;
}
else
{
//first load
report = newReport;
pages = new ArrayCollection(new Array(report.pageCount));
}
for(i = newReport.startPageIndex; i <= newReport.endPageIndex; i++)
{
pages[i] = newReport.pages[i - newReport.startPageIndex];
}
report.pages = pages;
report.startPageIndex = Math.min(report.startPageIndex, newReport.startPageIndex);
report.endPageIndex = Math.max(report.endPageIndex, newReport.endPageIndex);
refreshPage();
}
private function openHandler(event:Event):void
{
trace("openHandler: " + event);
}
private function progressHandler(event:ProgressEvent):void
{
trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
}
private function securityErrorHandler(event:SecurityErrorEvent):void
{
trace("securityErrorHandler: " + event);
}
private function httpStatusHandler(event:HTTPStatusEvent):void
{
trace("httpStatusHandler: " + event);
}
private function ioErrorHandler(event:IOErrorEvent):void
{
trace("ioErrorHandler: " + event);
}
private function refreshPage():void
{
if (report) {
this.dispatchEvent(new Event(this.LOAD_PAGE));
}
}
}
}
编译Main.mxml运行,即实现打印功能,但是包含图片的打印依然打印不出来。对于这种动态图片的打印添加了等待事件完成,仍能无效,不知道有没有好的实现。
参考链接:
JasperReports Library
完成Flex报表设计、生成、打印功能
Flex 4 Printing Problem with dynamic components