分类目录归档:flex

JasperReports flash打印实现

JasperReports是一个基于Java的开源报表工具,可以在ireport中进行设计后,输出HTML,PDF,Excell,OpenOffice和Word格式。JasperReports支持applet方式打印,但是flash方式却是注释掉的。在net\sf\jasperreports\flex\view\Viewer.mxml文件中

1
2
3
4
5
6
7
8
9
10
<!--
<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文件上面的文字修改为

1
2
3
4
5
6
7
8
9
10
<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函数,启用打印按钮,将

1
2
3
4
5
6
7
8
9
10
11
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;
}

修改为

1
2
3
4
5
6
7
8
9
10
11
12
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文件,以支持打印

1
import net.sf.jasperreports.flex.view.PrintManager;

在Viewer.mxml增加打印函数btnPrintReport

1
2
3
4
public function  btnPrintReport():void
{
    PrintManager.printAll(jrpxmlUrl,pageFetchSize,report);
}

net\sf\jasperreports\flex\view\PrintMananger.as文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
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