I have an AdvancedDataGrid that's pretty wide (lots of columns that need to be wide enough to read) that I need to print. The PrintAdvancedDataGrid.sizeToPage property adjusts the height of the grid so that page breaks only occur between rows.
I'm looking for something similar for columns.
Here's a test case (main program, FlexBuilder 4.5)
<fx:Script>
<![CDATA[
import mx.printing.FlexPrintJob;
import mx.printing.FlexPrintJobScaleType;
protected function btnPrint_clickHandler(event:MouseEvent):void
{
doPrint();
}
private function doPrint():void {
var printJob:FlexPrintJob = new FlexPrintJob();
if (printJob.start()) {
printJob.printAsBitmap = false;
var thePrintView:PrintView = new PrintView();
thePrintView.includeInLayout = false;
addElement(thePrintView);
thePrintView.height = printJob.pageHeight;
thePrintView.myDataGrid.source = myGrid;
thePrintView.validateNow();
// This example doesn't have that many rows,
// so I'm skipping the extra code to handle "multiple pages"
printJob.addObject(thePrintView, FlexPrintJobScaleType.NONE);
removeElement(thePrintView);
}
printJob.send();
}
]]>
</fx:Script>
<fx:Declarations>
<fx:Array id="data">
<fx:Object c1="c1r1" c2="c2r1" c3="c3r1" c4="c4r1" c5="c5r1" c6="c6r1" c7="c7r1" c8="c8r1" c9="c9r1" c10="c10r1" />
<fx:Object c1="c1r2" c2="c2r2" c3="c3r2" c4="c4r2" c5="c5r2" c6="c6r2" c7="c7r2" c8="c8r2" c9="c9r2" c10="c10r2" />
<fx:Object c1="c1r3" c2="c2r3" c3="c3r3" c4="c4r3" c5="c5r3" c6="c6r3" c7="c7r3" c8="c8r3" c9="c9r3" c10="c10r3" />
<fx:Object c1="c1r4" c2="c2r4" c3="c3r4" c4="c4r4" c5="c5r4" c6="c6r4" c7="c7r4" c8="c8r4" c9="c9r4" c10="c10r4" />
<fx:Object c1="c1r5" c2="c2r5" c3="c3r5" c4="c4r5" c5="c5r5" c6="c6r5" c7="c7r5" c8="c8r5" c9="c9r5" c10="c10r5" />
<fx:Object c1="c1r6" c2="c2r6" c3="c3r6" c4="c4r6" c5="c5r6" c6="c6r6" c7="c7r6" c8="c8r6" c9="c9r6" c10="c10r6" />
<fx:Object c1="c1r7" c2="c2r7" c3="c3r7" c4="c4r7" c5="c5r7" c6="c6r7" c7="c7r7" c8="c8r7" c9="c9r7" c10="c10r7" />
<fx:Object c1="c1r8" c2="c2r8" c3="c3r8" c4="c4r8" c5="c5r8" c6="c6r8" c7="c7r8" c8="c8r8" c9="c9r8" c10="c10r8" />
<fx:Object c1="c1r9" c2="c2r9" c3="c3r9" c4="c4r9" c5="c5r9" c6="c6r9" c7="c7r9" c8="c8r9" c9="c9r9" c10="c10r9" />
<fx:Object c1="c1r10" c2="c2r10" c3="c3r10" c4="c4r10" c5="c5r10" c6="c6r10" c7="c7r10" c8="c8r10" c9="c9r10" c10="c10r10" />
<fx:Object c1="c1r11" c2="c2r11" c3="c3r11" c4="c4r11" c5="c5r11" c6="c6r11" c7="c7r11" c8="c8r11" c9="c9r11" c10="c10r11" />
<fx:Object c1="c1r12" c2="c2r12" c3="c3r12" c4="c4r12" c5="c5r12" c6="c6r12" c7="c7r12" c8="c8r12" c9="c9r12" c10="c10r12" />
</fx:Array>
</fx:Declarations>
<s:Button id="btnPrint" x="0" y="0" label="Print" click="btnPrint_clickHandler(event)"/>
<mx:AdvancedDataGrid id="myGrid" top="30" dataProvider="{data}">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="c1" width="200" />
<mx:AdvancedDataGridColumn dataField="c2" width="200"/>
<mx:AdvancedDataGridColumn dataField="c3" width="200"/>
<mx:AdvancedDataGridColumn dataField="c4" width="200"/>
<mx:AdvancedDataGridColumn dataField="c5" width="200"/>
<mx:AdvancedDataGridColumn dataField="c6" width="200"/>
<mx:AdvancedDataGridColumn dataField="c7" width="200"/>
<mx:AdvancedDataGridColumn dataField="c8" width="200"/>
<mx:AdvancedDataGridColumn dataField="c9" width="200"/>
<mx:AdvancedDataGridColumn dataField="c10" width="200"/>
</mx:columns>
</mx:AdvancedDataGrid>
</s:WindowedApplication>
And here's the PrintView.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
backgroundColor="0xffffff">
<!-- The sizeToPage property is true by default, so the last
page has only as many grid rows as are needed for the data. -->
<mx:PrintAdvancedDataGrid id="myDataGrid" height="100%" horizontalCenter="0">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="c1" width="200" />
<mx:AdvancedDataGridColumn dataField="c2" width="200"/>
<mx:AdvancedDataGridColumn dataField="c3" width="200"/>
<mx:AdvancedDataGridColumn dataField="c4" width="200"/>
<mx:AdvancedDataGridColumn dataField="c5" width="200"/>
<mx:AdvancedDataGridColumn dataField="c6" width="200"/>
<mx:AdvancedDataGridColumn dataField="c7" width="200"/>
<mx:AdvancedDataGridColumn dataField="c8" width="200"/>
<mx:AdvancedDataGridColumn dataField="c9" width="200"/>
<mx:AdvancedDataGridColumn dataField="c10" width="200"/>
</mx:columns>
</mx:PrintAdvancedDataGrid>
</mx:VBox>
When you run this and press the Print button, you'll see the grid printed across 4 pages. That's a good thing - in my real app, I need the grid that wide. My concern is that the page breaks are splitting columns in a very ugly way.
Thanks,
Dan
Here's a more generalized solution. In the production code the original grid gets columns added dynamically, so the previous answer won't work. Also, I don't need all those extra PrintView objects. (It's good to have one for headers & footers).
Here's the main code:
<fx:Script>
<![CDATA[
import mx.printing.FlexPrintJob;
import mx.printing.FlexPrintJobScaleType;
import mx.printing.PrintAdvancedDataGrid;
protected function btnPrint_clickHandler(event:MouseEvent):void
{
doPrint2();
}
private function doPrint2():void {
var printJob:FlexPrintJob = new FlexPrintJob();
if (printJob.start()) {
printJob.printAsBitmap = false;
var thePrintView:PrintView = new PrintView();
thePrintView.includeInLayout = false;
addElement(thePrintView);
thePrintView.height = printJob.pageHeight;
var columns:Array = new Array();
var colWidth:Number = 0;
for (var colIndex:int = 0; colIndex < myGrid.columns.length; colIndex++)
{
var aColumn:AdvancedDataGridColumn = myGrid.columns[colIndex] as AdvancedDataGridColumn;
if (colWidth + aColumn.width < printJob.pageWidth) {
columns.push(aColumn);
colWidth += aColumn.width;
} else {
thePrintView.grid.columns = columns;
thePrintView.grid.dataProvider = myGrid.dataProvider;
thePrintView.validateNow();
// This example doesn't have that many rows,
// so I'm skipping the extra code to handle "multiple pages"
printJob.addObject(thePrintView, FlexPrintJobScaleType.NONE);
removeElement(thePrintView);
columns.length = 0;
columns.push(aColumn);
colWidth = aColumn.width;
thePrintView = new PrintView();
thePrintView.includeInLayout = false;
addElement(thePrintView);
thePrintView.height = printJob.pageHeight;
}
}
if (columns.length > 0)
{
thePrintView.grid.columns = columns;
thePrintView.grid.dataProvider = myGrid.dataProvider;
thePrintView.validateNow();
// This example doesn't have that many rows,
// so I'm skipping the extra code to handle "multiple pages"
printJob.addObject(thePrintView, FlexPrintJobScaleType.NONE);
removeElement(thePrintView);
}
}
printJob.send();
}
]]>
</fx:Script>
<fx:Declarations>
<fx:Array id="data">
<fx:Object c1="c1r1" c2="c2r1" c3="c3r1" c4="c4r1" c5="c5r1" c6="c6r1" c7="c7r1" c8="c8r1" c9="c9r1" c10="c10r1" />
<fx:Object c1="c1r2" c2="c2r2" c3="c3r2" c4="c4r2" c5="c5r2" c6="c6r2" c7="c7r2" c8="c8r2" c9="c9r2" c10="c10r2" />
<fx:Object c1="c1r3" c2="c2r3" c3="c3r3" c4="c4r3" c5="c5r3" c6="c6r3" c7="c7r3" c8="c8r3" c9="c9r3" c10="c10r3" />
<fx:Object c1="c1r4" c2="c2r4" c3="c3r4" c4="c4r4" c5="c5r4" c6="c6r4" c7="c7r4" c8="c8r4" c9="c9r4" c10="c10r4" />
<fx:Object c1="c1r5" c2="c2r5" c3="c3r5" c4="c4r5" c5="c5r5" c6="c6r5" c7="c7r5" c8="c8r5" c9="c9r5" c10="c10r5" />
<fx:Object c1="c1r6" c2="c2r6" c3="c3r6" c4="c4r6" c5="c5r6" c6="c6r6" c7="c7r6" c8="c8r6" c9="c9r6" c10="c10r6" />
<fx:Object c1="c1r7" c2="c2r7" c3="c3r7" c4="c4r7" c5="c5r7" c6="c6r7" c7="c7r7" c8="c8r7" c9="c9r7" c10="c10r7" />
<fx:Object c1="c1r8" c2="c2r8" c3="c3r8" c4="c4r8" c5="c5r8" c6="c6r8" c7="c7r8" c8="c8r8" c9="c9r8" c10="c10r8" />
<fx:Object c1="c1r9" c2="c2r9" c3="c3r9" c4="c4r9" c5="c5r9" c6="c6r9" c7="c7r9" c8="c8r9" c9="c9r9" c10="c10r9" />
<fx:Object c1="c1r10" c2="c2r10" c3="c3r10" c4="c4r10" c5="c5r10" c6="c6r10" c7="c7r10" c8="c8r10" c9="c9r10" c10="c10r10" />
<fx:Object c1="c1r11" c2="c2r11" c3="c3r11" c4="c4r11" c5="c5r11" c6="c6r11" c7="c7r11" c8="c8r11" c9="c9r11" c10="c10r11" />
<fx:Object c1="c1r12" c2="c2r12" c3="c3r12" c4="c4r12" c5="c5r12" c6="c6r12" c7="c7r12" c8="c8r12" c9="c9r12" c10="c10r12" />
</fx:Array>
</fx:Declarations>
<s:Button id="btnPrint" x="0" y="0" label="Print" click="btnPrint_clickHandler(event)"/>
<mx:AdvancedDataGrid id="myGrid" top="30" dataProvider="{data}">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="c1" width="200" />
<mx:AdvancedDataGridColumn dataField="c2" width="200"/>
<mx:AdvancedDataGridColumn dataField="c3" width="200"/>
<mx:AdvancedDataGridColumn dataField="c4" width="200"/>
<mx:AdvancedDataGridColumn dataField="c5" width="200"/>
<mx:AdvancedDataGridColumn dataField="c6" width="200"/>
<mx:AdvancedDataGridColumn dataField="c7" width="200"/>
<mx:AdvancedDataGridColumn dataField="c8" width="200"/>
<mx:AdvancedDataGridColumn dataField="c9" width="200"/>
<mx:AdvancedDataGridColumn dataField="c10" width="200"/>
</mx:columns>
</mx:AdvancedDataGrid>
</s:WindowedApplication>
The PrintView is as before. The actual column definitions are irrelevant.
<!-- The sizeToPage property is true by default, so the last
page has only as many grid rows as are needed for the data. -->
<mx:PrintAdvancedDataGrid id="grid" height="100%" horizontalCenter="0">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="c1" width="200" />
<mx:AdvancedDataGridColumn dataField="c2" width="200"/>
<mx:AdvancedDataGridColumn dataField="c3" width="200"/>
</mx:columns>
</mx:PrintAdvancedDataGrid>
</mx:VBox>
I hope this helps someone else.