Issue
Exporting Flex chart Component to Excel as image
Solution :
- Create a chart component
- Use the method ImageSnapshot .captureImage() to capture snapshot of any component.
please refer : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/ImageSnapshot.html#captureImage%28%29 as in the code, var ImageBA:ByteArray = ImageSnapshot.captureImage( Chart, 0, new JPEGEncoder() ).data;
Store the same on a byte array and forward the same to a ColdFusion component as an argument. Remote Object call would look like :
<s:RemoteObject id="RemoteCall" endpoint="http://localhost:8300/flex2gateway/"
destination="ColdFusion" source="ChartToShuyi182703455.CallCFCTest">
<s:method name="CreateImage"
result="onResult(event)"
fault="onFault(event)">
</s:method>
</s:RemoteObject>
protected function CreateImage_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
var ImageBA:ByteArray = ImageSnapshot.captureImage( Chart, 0, new JPEGEncoder() ).data;
RemoteCall.CreateImage(ImageBA);
}
<s:Button id="CreateImage" label="CreateImage" click="CreateImage_clickHandler(event)" visible="{SnapshotImage.source != null}"/>
On the ColdFusion Server end
- Use the binary data from the argument and use CFFile Tag to write the image to a file.
<cffunction name="CreateImage" access="remote" output="false" returntype="String" > <cfargument name="ImageBA" type="binary" required="true" /> <cffile action="write" file="#theDir#test.jpg" output="#arguments.ImageBA#" > <cfreturn "The Image can be found on server : "&#theDir#> </cffunction>
- Write the image file to the Excel Spreadsheet using CFspreadsheet
please refer : http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WS434C35B0-279B-4051-A61B-D84B5D76189C.html
and SpreadsheetAddImage please refer : http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-688c.html
<cffunction name="ExportToExcel" access="remote" output="false" returntype="String" > <cfimage name="ComponentImage" source="#theDir#test.jpg" action="read" /> <cfscript> SpreadSheetObj=spreadsheetNew(); spreadsheetAddimage(spreadsheetobj,ComponentImage,"jpg","5,5,25,12"); </cfscript> <cfspreadsheet action="write" name="SpreadSheetObj" filename="#theDir#imagesheet.xls" overwrite="true" > <cfreturn "The SpreadSheet with Chart Image can be found on server : "&#theDir#> </cffunction>
Additional Information :
Adobe Products used SDK 4.5.1 and ColdFusion 9.0
Flex Code [ChartToExcelAsImage.mxml]:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<s:RemoteObject id="RemoteCall" endpoint="http://localhost:8300/flex2gateway/"
destination="ColdFusion" source="ChartToShuyi182703455.CallCFCTest">
<s:method name="CreateImage"
result="onResult(event)"
fault="onFault(event)">
</s:method>
<s:method name="ExportToExcel"
result="onResult(event)"
fault="onFault(event)">
</s:method>
<s:method name="ClearFiles"
result="onResult(event)"
fault="onFault(event)">
</s:method>
</s:RemoteObject>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private var SnapShot:ImageSnapshot;
[Bindable]private var medalsAC:ArrayCollection = new ArrayCollection( [
{ Country: "USA", Gold: 35, Silver:39, Bronze: 29 },
{ Country: "China", Gold: 32, Silver:17, Bronze: 14 },
{ Country: "Russia", Gold: 27, Silver:27, Bronze: 38 } ]);
private var snapshot :ImageSnapshot;
protected function ScreenShot_clickHandler(event:MouseEvent):void
{
SnapshotImage.source=ImageSnapshot.captureImage( Chart, 0, new JPEGEncoder() ).data;
SnapshotImage.width=ChartComponent.width;
SnapshotImage.height=ChartComponent.height;
CreateImage.enabled=true;
}
public function onResult(event : ResultEvent) : void
{
ServerReturn.text=event.result as String;
}
public function onFault(event : FaultEvent) : void
{
Alert.show(event.fault.message,event.fault.faultCode );
}
protected function CreateImage_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
var ImageBA:ByteArray = ImageSnapshot.captureImage( Chart, 0, new JPEGEncoder() ).data;
RemoteCall.CreateImage(ImageBA);
CreateImage.enabled=false;
ExportToExcel.enabled=true;
ClearFiles.enabled=false;
}
protected function ExportToExcel_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
RemoteCall.ExportToExcel.send();
CreateImage.enabled=false;
ExportToExcel.enabled=false;
ClearFiles.enabled=true;
}
protected function ClearFiles_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
RemoteCall.ClearFiles.send();
CreateImage.enabled=false;
ExportToExcel.enabled=false;
ClearFiles.enabled=false;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout verticalAlign="middle" horizontalAlign="center" />
</s:layout>
<s:Panel title="BarChart Control"
color="0x000000"
borderAlpha="0.15" width="100%">
<s:layout>
<s:HorizontalLayout />
</s:layout>
<mx:HDividedBox width="100%">
<s:Panel id="ChartComponent" title="Chart Component" >
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<mx:HBox id="Chart" backgroundColor="white">
<mx:BarChart id="bar" height="100%" color="0x323232"
showDataTips="true" dataProvider="{medalsAC}">
<mx:verticalAxis>
<mx:CategoryAxis categoryField="Country"/>
</mx:verticalAxis>
<mx:series>
<mx:BarSeries yField="Country" xField="Gold" displayName="Gold"/>
<mx:BarSeries yField="Country" xField="Silver" displayName="Silver"/>
<mx:BarSeries yField="Country" xField="Bronze" displayName="Bronze"/>
</mx:series>
</mx:BarChart>
<mx:Legend dataProvider="{bar}" color="0x323232"/>
</mx:HBox>
</s:Panel>
<s:Panel title="Screen Shot">
<s:Image id="SnapshotImage" width="{ChartComponent.width}" height="{ChartComponent.height}"/>
</s:Panel>
</mx:HDividedBox>
</s:Panel>
<s:Panel minWidth="600" minHeight="150">
<s:layout>
<s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
</s:layout>
<s:Button id="ScreenShot" label="Take ScreenShot" click="ScreenShot_clickHandler(event)"/>
<mx:Text id="ServerReturn" text="no data from server"/>
<s:Button id="CreateImage" label="CreateImage" click="CreateImage_clickHandler(event)" visible="{SnapshotImage.source != null}"/>
<s:Button id="ExportToExcel" label="ExportToExcel" click="ExportToExcel_clickHandler(event)" enabled="false" />
<s:Button id="ClearFiles" label="ExportToExcel" click="ClearFiles_clickHandler(event)" enabled="false" />
</s:Panel>
</s:Application>
ColdFusion Code :[CallCFCTest.cfc]
<cfcomponent displayname="CallCFCTest"> <cfscript> theDir=getDirectoryFromPath(GetCurrentTemplatePath()); </cfscript> <cffunction name="CreateImage" access="remote" output="false" returntype="String" > <cfargument name="ImageBA" type="binary" required="true" /> <cffile action="write" file="#theDir#test.jpg" output="#arguments.ImageBA#" > <cfreturn "The Image can be found on server : "&#theDir#> </cffunction> <cffunction name="ExportToExcel" access="remote" output="false" returntype="String" > <cfimage name="ComponentImage" source="#theDir#test.jpg" action="read" /> <cfscript> SpreadSheetObj=spreadsheetNew(); spreadsheetAddimage(spreadsheetobj,ComponentImage,"jpg","5,5,25,12"); </cfscript> <cfspreadsheet action="write" name="SpreadSheetObj" filename="#theDir#imagesheet.xls" overwrite="true" > <cfreturn "The SpreadSheet with Chart Image can be found on server : "&#theDir#> </cffunction> <cffunction name="ClearFiles" access="remote" output="false" returntype="String" > <cffile action="delete" file="#theDir#test.jpg"> <cffile action="delete" file="#theDir#imagesheet.xls"> <cfreturn "The SpreadSheet along with Chart Image have been deleted from Server: "&#theDir#> </cffunction> </cfcomponent>


