Для Flex PrintAdvancedDataGrid нужно что-то похожее на sizeToPage для столбцов - PullRequest
0 голосов
/ 28 июля 2011

У меня есть AdvancedDataGrid, который довольно широк (много столбцов, которые должны быть достаточно широкими, чтобы их можно было прочитать), которые мне нужно распечатать. Свойство PrintAdvancedDataGrid.sizeToPage регулирует высоту сетки, чтобы разрывы страниц возникали только между строками.

Я ищу что-то похожее для столбцов.

Вот тестовый пример (основная программа, 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>

А вот 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>

Когда вы запустите это и нажмете кнопку «Печать», вы увидите сетку, напечатанную на 4 страницах. Это хорошо - в моем реальном приложении мне нужна такая широкая сетка. Меня беспокоит то, что разрывы страниц очень уродливо разбивают столбцы.

Спасибо

Dan

Ответы [ 2 ]

1 голос
/ 29 июля 2011

Вот более обобщенное решение.В рабочем коде исходная сетка добавляет столбцы динамически, поэтому предыдущий ответ не будет работать.Кроме того, мне не нужны все эти дополнительные объекты PrintView.(Хорошо иметь один для верхних и нижних колонтитулов).

Вот основной код:

    <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>

PrintView как и раньшеФактические определения столбцов не имеют значения.

    <!-- 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>

Надеюсь, это поможет кому-то еще.

1 голос
/ 29 июля 2011

Я не собирался отвечать на свой вопрос, но нашел ответ, и, надеюсь, это поможет кому-то еще.

Решение состоит в том, чтобы использовать несколько объектов PrintAdvancedGrid и устанавливать столбцы каждого из них по мере необходимости. Я отправлю этот ответ с моим первым решением, а затем с более общим подходом.

В этом я предположил фиксированное количество столбцов в исходной сетке.

Вот основной файл:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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:Script>
        <![CDATA[
            import mx.printing.FlexPrintJob;
            import mx.printing.FlexPrintJobScaleType;
            import mx.printing.PrintAdvancedDataGrid;

            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();
                    var pv2:PrintView2 = new PrintView2();
                    var pv3:PrintView3 = new PrintView3();
                    var pv4:PrintView4 = new PrintView4();

                    thePrintView.includeInLayout = false;
                    addElement(thePrintView);
                    pv2.includeInLayout = false;
                    addElement(pv2);
                    pv3.includeInLayout = false;
                    addElement(pv3);
                    pv4.includeInLayout = false;
                    addElement(pv4);

                    thePrintView.height = printJob.pageHeight;
                    pv2.height = printJob.pageHeight;
                    pv3.height = printJob.pageHeight;
                    pv4.height = printJob.pageHeight;

                    //thePrintView.myDataGrid.source = myGrid;
                    thePrintView.grid.dataProvider = myGrid.dataProvider;
                    pv2.grid.dataProvider = myGrid.dataProvider;
                    pv3.grid.dataProvider = myGrid.dataProvider;
                    pv4.grid.dataProvider = myGrid.dataProvider;

                    thePrintView.validateNow();
                    pv2.validateNow();
                    pv3.validateNow();
                    pv4.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);
                    printJob.addObject(pv2, FlexPrintJobScaleType.NONE);
                    printJob.addObject(pv3, FlexPrintJobScaleType.NONE);
                    printJob.addObject(pv4, FlexPrintJobScaleType.NONE);

                    removeElement(thePrintView);
                    removeElement(pv2);
                    removeElement(pv3);
                    removeElement(pv4);
                }
                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>

Каждый из 4 объектов PrintView похож, отличается только тем, какие столбцы отображаются:

<?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="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>

Остальные похожи и не стоит публиковать - просто измените значения в <mx:columns>.

...