Это исследование демонстрирует, как использовать PrintAdvancedDataGrid
и пользовательский itemRenderer
для печати нескольких страниц данных и графики с использованием компонента SWFloader
.
Окончательный результат предварительного просмотра
Давайте посмотрим на конечный результат, к которому мы будем стремиться — ниже представлен обзор 12-страничного PDF-документа, напечатанного из приложения Flex с использованием методов, описанных в этой статье:
Демонстрируется в этом уроке:
- Использование класса FlexPrintJob.
- Использование
PrintAdvancedDataGrid
. - Создание пользовательского
itemRenderer
с помощьюSWFLoader
. - Печать верхнего и нижнего колонтитула.
- Фильтрация
collectionView
. - Печать
DataGrid
с высотой, которая превышает 7500.
Некоторые трудности, связанные с гибкой печатью:
- Все содержимое или строки
DataGrid
должны быть видны на сцене, иначе они не будут печататься. - Добавление разрывов страниц вручную затруднено и достигается путем установки значения
rowHeight
соответствующего тому, что вы хотите отображать на каждой напечатанной странице. - Гибкая печать становится
PrintAdvancedDataGrid
если общаяPrintAdvancedDataGrid
содержимогоPrintAdvancedDataGrid
превышает приблизительно 7500 пикселей, что требует обходного пути для несколькихPrintAdvancedDataGrids
.
Шаг 1. Импортируйте классы печати
Начните с импорта необходимых классов печати, а также средства визуализации печати в проект Flex:
1
2
3
|
import mx.printing.FlexPrintJob;
import mx.printing.FlexPrintJobScaleType;
import com.reiman.PrintItemRenderer;
|
Шаг 2. Создание представления для PrintAdvancedDataGrid
и itemRenderer
Создайте состояние просмотра для вашей массовой печати. В моем случае я создал состояние с именем printState.
* в качестве альтернативы, вы можете создать экземпляр вашего PrintAdvancedDataGrid
и itemRenderer и добавить их на сцену с помощью actionScript, но для проекта массовой печати я обнаружил, что с этим слишком сложно работать, и когда я пытался напечатать SWF-файлы, которые представляют собой XML Я должен был убедиться, что мои SWF-файлы правильно отображались перед печатью.
Шаг 3. Добавьте свой PrintAdvancedDataGrid
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<mx:PrintAdvancedDataGrid
paddingTop=»0″
paddingBottom=»0″
visible=»true»
rowHeight=»200″
sizeToPage=»true»
showHeaders=»false»
id=»printGrid»
creationComplete=»stripQuiz();»
height=»{grid_height}»
width=»300″>
<mx:columns>
<mx:AdvancedDataGridColumn
width=»200″
id=»printColumn»
itemRenderer=»com.reiman.PrintItemRenderer»
sortable=»false» />
</mx:columns>
</mx:PrintAdvancedDataGrid>
|
Если вам нужна общая область печати более 7500 по высоте, вам понадобится еще одна PrintAdvancedDataGrid
для каждой области
Шаг 4. Установите параметры PrintAdvancedDataGrid
Одна вещь, которую я нашел важным, это установить опцию
1
|
sizetoPage=»true»
|
Согласно странице ControlDataGrid Control из Adobe Flex 3 LiveDocs , свойство sizeToPage гарантирует, что элемент управления PrintAdvancedDataGrid удаляет все частично видимые или пустые строки и изменяет свой размер, чтобы включать только полные строки в текущем представлении.
Шаг 5: Добавьте ваш itemRenderer
Добавьте itemRenderer в свой AdvancedDataGridColumn
.
1
2
3
4
5
|
<mx:AdvancedDataGridColumn
width=»200″
id=»printColumn»
itemRenderer=»com.reiman.PrintItemRenderer»
sortable=»false» />
|
Шаг 6: Создайте компонент itemRenderer
В моем случае я хотел сделать несколько вещей с itemRenderer
:
- добавить
SWFLoader
- добавить заголовок с заголовком страницы
- добавить боковой колонтитул с моим URL
- добавить интервалы сверху, снизу и по бокам для правильной печати
Поскольку мой URL работал лучше как вертикальный текст, я обнаружил, что гораздо лучше использовать SWF для этого текста вместо текстового поля. Вы можете проявить творческий подход с помощью itemRenderer
, добавив элементы данных из вашего XML или источника данных, а также логотипы, URL-адреса и т. Д. Вот элементы отображения из моего кода для компонента itemRenderer
, который также находится в src / com / reiman Файл /PrintItemRenderer.mxml в пакете загрузки для этого руководства:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<mx:VBox width=»100%» >
<mx:Spacer height=»10″ width=»100%»/>
<mx:HBox horizontalAlign=»center» width=»100%»>
<mx:Text textAlign=»center» styleName=»printHeader» text=»{appy.printGrid.dataProvider.getItemAt(0).title} — {row.lessonTitle} © Insta Spanish 2011″ width=»92%» x=»10″ y=»-7″/>
<mx:Image right=»20″ source=»{row.lessonIcon==’video’?video:
row.lessonIcon==’worksheet’?worksheet:
row.lessonIcon==’lesson’?activity:
row.lessonIcon==’hover’?hover:
row.lessonIcon==’drag’?matching:
row.lessonIcon==’song’?song:
row.lessonIcon==’memory’?memory:
row.lessonIcon==’downloads’?’assets/images/icons/downloads.swf’:
row.lessonIcon==’hangman’?hangman:
row.lessonIcon==’quiz’?quiz:
row.lessonIcon==’wordgame’?wordgame:
row.lessonIcon==’flashcards’?flashcard:
row.lessonIcon==’oral’?oral:
row.lessonIcon==’cloze’?cloze:empty}» height=»25″ width=»25″/>
</mx:HBox>
</mx:VBox>
<mx:VBox id=»print_vbox» horizontalScrollPolicy=»off» verticalScrollPolicy=»off»
verticalAlign=»middle» height=»100%» width=»100%»>
<mx:Spacer height=»5%» />
<mx:HBox horizontalScrollPolicy=»off» verticalScrollPolicy=»off»
verticalAlign=»middle» height=»100%» width=»100%»>
<mx:Spacer width=»3%» />
<mx:SWFLoader id=»swfPrintLoader» height=»90%» width=»90%» scaleContent=»true» source=»{row.fileName}» autoLoad=»true» />
<mx:Spacer height=»1%» />
<mx:SWFLoader height=»198″ width=»20″ scaleContent=»true» source=»assets/images/wwwinstaspanishcom.swf»/>
</mx:HBox>
</mx:VBox>
|
Шаг 7. Добавьте базовый код ActionScript FlexPrintJob в файл main.mxml.
1
2
3
4
5
6
7
8
9
|
public function print():void {
var printJob:FlexPrintJob = new FlexPrintJob();
printJob.printAsBitmap=false;
if(printJob.start())
{
printJob.addObject(printGrid);
printJob.send();
}
}
|
Шаг 8: Установите printJob
масштаба printJob
Выберите printJob
масштаба printJob
вы хотите использовать (чтобы узнать о FlexPrintJob
масштаба FlexPrintJob
, проверьте страницу Flex LiveDocs здесь ), и при необходимости установите параметр printasBitmap
. Я хотел, чтобы мои элементы печатались как векторные, и на самом деле этот параметр был ключом к правильной печати содержимого.
1
|
printJob.printAsBitmap=false;
|
Шаг 9: Добавьте код для выполнения перед printJob
Добавьте любые оповещения или действия, которые вы хотите выполнить при печати (например, оповещение, чтобы сообщить пользователю о включении LANDSCAPE печати). Например:
1
|
Alert.show («Please set your printer settings to LANDSCAPE » + ‘\n’ + «or your quiz will NOT print correctly!»)
|
Если вы хотите установить Alert
, оно должно быть выполнено до начала печати. Пожалуйста, посмотрите на код, предоставленный в загрузке, связанной с этим руководством для printAlert()
в файле main.mxml .
Шаг 10. Установите width
и height
печати.
Установите значения ширины и высоты перед печатью для ширины PrintAdvancedDataGrid
и rowHeight
1
2
3
4
|
var before_widdy = printColumn.width;
var before_hiddy = printGrid.rowHeight;
var widdy = printJob.pageWidth;
var hiddy = printJob.pageHeight;
|
Шаг 11: Установите новые значения
Установите новые значения для height
, width
и rowHeight
чтобы они равнялись значениям FlexPrintJob
1
2
3
|
printColumn.width = widdy;
printGrid.width = widdy;
printGrid.rowHeight = hiddy;
|
Шаг 12. Добавьте код из нескольких страниц в FlexPrintJob
Добавьте свой код для размещения нескольких страниц в printJob
. Согласно Flex LiveDocs, эта nextPage()
должна гарантировать, что ваш контент будет печататься правильно, независимо от высоты AdvancedDataGrid
, хотя я обнаружил, что после высоты примерно 7500, печать не может завершиться правильно.
1
2
3
4
5
6
7
|
while(true) {
printGrid.nextPage();
if(!printGrid.validNextPage){
printJob.addObject(printGrid);
break;
}
}
|
Шаг 13: Дополнительно отрегулируйте printGrid
Я обнаружил, что у меня стало меньше ошибок печати, когда я добавил это в код из шага 12:
1
2
|
printGrid.height = printGrid.measuredHeight;
printGrid.verticalScrollPolicy = «off»;
|
Итак, теперь мой общий код для шага 12 выглядит следующим образом:
1
2
3
4
5
6
7
8
9
|
while(true) {
printGrid.nextPage();
if(!printGrid.validNextPage){
printGrid.height = printGrid.measuredHeight;
printGrid.verticalScrollPolicy = «off»;
printJob.addObject(printGrid);
break;
}
}
|
Похоже, это связано с проблемой или ошибкой Flex 3, связанной с печатью сеток данных с большой высотой, что является реальной проблемой при печати таких вещей, как несколько SWF или изображений, поскольку высота вашей сетки данных должна фактически отражать общую высоту изображений или SWF. печатается!
Шаг 14: Добавьте код, чтобы добавить что-нибудь еще к вашей printJob
1
2
3
|
printJob.addObject(printGrid2);
printJob.addObject(swfLoader,
FlexPrintJobScaleType.NONE);
|
Шаг 15: Отправь свой printJob
Закройте printJob
и выполните любые дополнительные функции, такие как Alert
, и printColumn
значения printGrid
и printColumn
до того, что было до печати. Если вы используете состояние просмотра для печати, где у пользователя, возможно, есть интерфейс типа Центра печати, где он может видеть, что он собирается напечатать, это было бы полезно. Если вы решите добавить PrintAdvancedDataGrid
на сцену с помощью actionScript, тогда это будет ненужным, и на этом шаге вы вместо этого удалите PrintAdvancedDataGrid
из стадии.
1
2
3
4
5
|
printJob.send();
printColumn.width = before_widdy;
printGrid.width = before_widdy;
printGrid.rowHeight = before_hiddy;
Alert.show(«Print Job Complete!»)
|
Шаг 16. Добавьте еще один PrintAdvancedDataGrid
если ваш контент превышает высоту 7500
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<mx:PrintAdvancedDataGrid
paddingTop=»0″
paddingBottom=»0″
visible=»true»
rowHeight=»200″
sizeToPage=»true»
showHeaders=»false»
id=»printGrid2″
creationComplete=»stripQuiz2();»
height=»{grid_height}»
width=»300″>
<mx:columns>
<mx:AdvancedDataGridColumn
width=»200″
id=»printColumn2″
itemRenderer=»com.reiman.PrintItemRenderer»
sortable=»false» />
</mx:columns>
</mx:PrintAdvancedDataGrid>
|
Шаг 17: resultHandler
ваши resultHandler
и resultHandler
Изначально мой вызов данных выглядел так:
1
|
<mx:HTTPService id=»httpService» url=»{myUrl}» resultFormat=»object» result=»httpResult_handler(event)» fault=»Alert.show(‘data load error’)» />
|
Все, что мне нужно было сделать, это добавить дополнительный обработчик результатов, чтобы данные для второго PrintAdvancedDatagrid
были отдельными:
1
|
<mx:HTTPService id=»httpService» url=»{myUrl}» resultFormat=»object» result=»httpResult_handler(event);httpResult_handler2(event)» fault=»Alert.show(‘data load error’)» />
|
Затем я добавил новый обработчик результатов:
01
02
03
04
05
06
07
08
09
10
|
private function httpResult_handler2(evt:ResultEvent):void {
if (evt.result.lessons.row) {
var resultAC:ArrayCollection = evt.result.lessons.row as ArrayCollection;
for (var i:int=0;i<resultAC.length;i++) {
var row:Row = new Row();
row.fill(resultAC[i]);
lessonsDataProvider2.addItem(row);
}
getSelectedItem()
}
|
Этот новый dataProvider
для второго PrintAdvancedDatagrid
установлен в моей stripQuiz2()
фильтра stripQuiz2()
.
Шаг 18: Добавьте collectionView
Переменные и Дополнительные dataProvider
В моем случае мне нужно было добавить 3 новых ListCollectionView
и еще 1 dataProvider
:
1
2
3
4
|
[Bindable]private var removeQuiz:ListCollectionView = new ListCollectionView();
[Bindable]private var removeQuiz2:ListCollectionView = new ListCollectionView();
[Bindable]private var itemsQuiz:ListCollectionView = new ListCollectionView();
[Bindable]private var lessonsDataProvider2:ArrayCollection = new ArrayCollection();
|
Шаг 19: Добавьте функции filterFunction
Для двух сетей данных, из которых я хотел печатать, мне были нужны фильтры, которые будут выполнять следующие функции:
- Удалите определенные виды деятельности из моего списка печати, поскольку некоторые из них не были необходимы
- Усечите данные до 12 записей, так как после обширного тестирования я обнаружил, что это был предел для успешной печати полностраничных SWF-файлов из таблицы данных.
- Удалите первые 12 записей из
ListCollectionView
для 2-гоPrintAdvancedDatagrid
Это привело к созданию следующих функций:
01
02
03
04
05
06
07
08
09
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
|
private function stripQuiz():void {
removeQuiz = new ListCollectionView(lessonsDataProvider);
removeQuiz.filterFunction = quizStripped;
removeQuiz.refresh();
quizLimit();
removeQuiz.refresh();
printGrid.dataProvider = removeQuiz;
}
private function stripQuiz2():void {
removeQuiz2 = new ListCollectionView(lessonsDataProvider2);
removeQuiz2.filterFunction = quizStripped;
removeQuiz2.refresh();
quizPage2();
removeQuiz2.refresh();
printGrid2.dataProvider = removeQuiz2;
}
private function quizStripped(value:Object):Boolean {
return String(value.lessonIcon).toUpperCase() != «QUIZ» &&
String(value.lessonIcon).toUpperCase() != «HANGMAN» &&
String(value.lessonIcon).toUpperCase() != «FLASHCARDS» &&
String(value.lessonIcon).toUpperCase() != «DOWNLOADS» &&
String(value.lessonIcon).toUpperCase() != «VIDEO» &&
String(value.fileName).toUpperCase() != «ASSETS/ACTIVITIES/WORKSHEET_KIDS_AUDIO.SWF» &&
String(value.fileName).toUpperCase() != «ASSETS/ACTIVITIES/WORKSHEET_KIDS_AUDIO5.SWF»;
}
private function quizLimit():void {
for (var i:int=removeQuiz.length-1; i>=0; i—)
{
if (removeQuiz.length >= 13)
removeQuiz.removeItemAt(i);
}
}
private function quizPage2():void {
if (removeQuiz2.length >= 13)
removeQuiz2.removeItemAt(12);
removeQuiz2.removeItemAt(11);
removeQuiz2.removeItemAt(10);
removeQuiz2.removeItemAt(9);
removeQuiz2.removeItemAt(8);
removeQuiz2.removeItemAt(7);
removeQuiz2.removeItemAt(6);
removeQuiz2.removeItemAt(5);
removeQuiz2.removeItemAt(4);
removeQuiz2.removeItemAt(3);
removeQuiz2.removeItemAt(2);
removeQuiz2.removeItemAt(1);
}
|
Шаг 20: добавь вторую printGrid
к printJob
Перед отправкой printJob я добавил второй PrintAdvancedDatagrid
для печати:
1
2
|
printJob.addObject(printGrid2);
printJob.send();
|
Для лучшего ознакомления с полным кодом, пожалуйста, загрузите исходные файлы, связанные с этим руководством, и посмотрите на файл main.mxml .
Вывод
Возможно, это не самое элегантное решение для массовой печати SWF-файлов из Flex, но это решение, которое я нашел, надежно работает с высоким качеством вывода. Печать во Flex может быть очень полезной, но это не значит, что вам следует упускать из виду доступные вам параметры, в частности, с помощью PrintDatagrid
и PrintAdvancedDatagrid
. Большое спасибо за чтение моего урока, и я с нетерпением жду ваших вопросов и комментариев.