Imprimer en vrac avec Flex

Cette étude de cas montre comment utiliser PrintAdvancedDataGrid et une coutume itemRenderer pour imprimer plusieurs pages de données et de graphiques, en utilisant le SWFloader composant.


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler. Vous trouverez ci-dessous un aperçu d'un fichier PDF de 12 pages imprimé à partir d'une application Flex utilisant les techniques décrites dans cet article:

flex_print_preview

Démontré dans ce tutoriel:

  1. Utilisation de la classe FlexPrintJob.
  2. En utilisant PrintAdvancedDataGrid.
  3. Créer une coutume itemRenderer avec un SWFLoader.
  4. Imprimer un en-tête et un pied de page.
  5. Filtrer un collectionVoir.
  6. Impression d'un Grille de données avec une hauteur supérieure à 7500.

Quelques difficultés en ce qui concerne l'impression flexible:

  1. Votre contenu ou Grille de données les rangées doivent toutes être visibles sur la scène sinon elles ne seront pas imprimées.
  2. Il est difficile d’ajouter des sauts de page manuels. rowHeight pour correspondre à ce que vous voulez afficher sur chaque page imprimée.
  3. L’impression Flex va mal à l’aise si votre total PrintAdvancedDataGrid hauteur du contenu est supérieure à environ 7500 pixels, ce qui nécessite une solution de contournement de plusieurs PrintAdvancedDataGrids.

Étape 1: Importer les classes d'impression

Commencez par importer les classes d'impression nécessaires, ainsi que votre moteur de rendu d'impression, dans votre projet Flex:

 import mx.printing.FlexPrintJob; import mx.printing.FlexPrintJobScaleType; import com.reiman.PrintItemRenderer;

Étape 2: Créer une vue pour PrintAdvancedDataGrid et itemRenderer

Créez un état d'affichage pour votre impression en masse. Dans mon cas, j'ai créé un état appelé printState.

* alternativement, vous pouvez créer une instance de votre PrintAdvancedDataGrid et itemRenderer et les ajouter à la scène via actionscript, mais pour un projet d'impression en masse, j'ai trouvé qu'il était trop difficile de travailler avec, et comme j'essayais d'imprimer des fichiers SWF gérés par XML, je devais m'assurer que mes fichiers SWF étaient compatibles. affichage correct avant impression.


Étape 3: Ajoutez votre PrintAdvancedDataGrid

     

Si vous avez besoin d’une surface d’impression totale supérieure à 7500, vous aurez besoin d’une autre PrintAdvancedDataGrid pour chaque domaine


Étape 4: Définissez votre PrintAdvancedDataGrid options

Une chose que j'ai trouvée importante a été de définir l'option

 sizetoPage = "true"

Selon la page PrintDataGrid Control de Adobe Live Flex 3 LiveDocs, la propriété sizeToPage garantit que le contrôle PrintAdvancedDataGrid supprime les lignes partiellement visibles ou vides et se redimensionne pour n'inclure que des lignes complètes dans la vue actuelle..


Étape 5: Ajoutez votre itemRenderer

Ajouter un itemRenderer à votre AdvancedDataGridColumn.

 

Étape 6: Créez le itemRenderer Composant

Dans mon cas, je voulais accomplir plusieurs choses avec le itemRenderer:

  1. ajouter un SWFLoader
  2. ajouter un en-tête avec le titre de la page
  3. ajouter un pied de page avec mon url
  4. ajoutez un espacement en haut, en bas et sur les côtés pour une impression correcte

Étant donné que mon URL fonctionnait mieux en tant que texte vertical, je trouvais qu'il valait mieux utiliser un fichier SWF pour ce texte plutôt qu'une zone de texte. Vous pouvez être créatif avec votre itemRenderer, ajout d'éléments de données provenant de votre source XML ou de votre source de données, ainsi que de logos, d'URL, etc. Voici les éléments d'affichage de l'intérieur de mon code pour itemRenderer composant, qui se trouve également dans le src / com / reiman / PrintItemRenderer.mxml fichier dans le package de téléchargement de ce tutoriel:

                

Étape 7: Ajouter le script Actionscript de base FlexPrintJob Code dans votre fichier main.mxml

 fonction publique print (): void var printJob: FlexPrintJob = new FlexPrintJob (); printJob.printAsBitmap = false; if (printJob.start ()) printJob.addObject (printGrid); printJob.send (); 

Étape 8: Set printJob Type d'échelle

Choisir la printJob type de balance que vous voulez utiliser (à lire sur FlexPrintJob types de balance, consultez la page Flex LiveDocs ici) et définissez éventuellement la printasBitmap option. Je souhaitais que mes éléments soient imprimés en tant que vecteur. En fait, ce paramètre a été la clé de l'impression correcte du contenu..

 printJob.printAsBitmap = false;

Étape 9: Ajouter le code à exécuter avant le printJob

Ajoutez toutes les alertes ou actions que vous souhaitez effectuer lors de l'impression (par exemple, une alerte pour indiquer à l'utilisateur d'activer l'impression LANDSCAPE). Par exemple:

 Alert.show ("Définissez les paramètres de votre imprimante sur LANDSCAPE" + '\ n' + "ou votre questionnaire n'imprimera PAS correctement!")

Si vous voulez définir un Alerte, il faut exécuter avant votre impression commence. Veuillez regarder le code fourni dans le téléchargement associé à ce tutoriel pour la printAlert () dans le main.mxml fichier.


Étape 10: Définissez votre impression largeur et la taille Variables

Définissez votre avant d'imprimer les valeurs de largeur et de hauteur pour PrintAdvancedDataGridlargeur, et rowHeight

 var before_widdy = printColumn.width; var before_hiddy = printGrid.rowHeight; var widdy = printJob.pageWidth; var hiddy = printJob.pageHeight;

Étape 11: Définir les nouvelles valeurs

Définir les nouvelles valeurs pour le la taille, largeur, et rowHeight égaler le FlexPrintJob valeurs

 printColumn.width = widdy; printGrid.width = widdy; printGrid.rowHeight = hiddy;

Étape 12: Ajoutez le code de plusieurs pages à FlexPrintJob

Ajoutez votre code pour pouvoir ajouter plusieurs pages au printJob. Selon les LiveDocs Flex, cette page suivante() vérifier est censé assurer que votre contenu sera imprimé correctement indépendamment de votre AdvancedDataGrid hauteur, bien que j'ai constaté qu'après une hauteur d'environ 7500, l'impression ne se termine pas correctement.

 while (true) printGrid.nextPage (); if (! printGrid.validNextPage) printJob.addObject (printGrid); Pause; 

Étape 13: Facultatif Ajustez la printGrid la taille

J'ai constaté que j'avais moins d'erreurs d'impression lorsque j'ai ajouté ceci au code de l'étape 12:

 printGrid.height = printGrid.measuredHeight; printGrid.verticalScrollPolicy = "off";

Alors maintenant, mon code total pour l'étape 12 ressemble à ceci:

 while (true) printGrid.nextPage (); if (! printGrid.validNextPage) printGrid.height = printGrid.measuredHeight; printGrid.verticalScrollPolicy = "off"; printJob.addObject (printGrid); Pause; 

Cela semble être dû au problème ou au bogue de Flex 3 concernant l'impression de grilles de données de grande hauteur, ce qui pose un réel problème pour l'impression d'éléments tels que plusieurs fichiers SWF ou images, car la hauteur de votre grille de données doit en fait refléter la hauteur totale des images ou des fichiers SWF. en cours d'impression!


Étape 14: Ajoutez le code pour ajouter quoi que ce soit à votre printJob

 printJob.addObject (printGrid2); printJob.addObject (swfLoader, FlexPrintJobScaleType.NONE);

Étape 15: envoyez votre printJob

Ferme ton printJob, et effectuer des fonctions supplémentaires telles que Alerte, et réinitialiser le printGrid et printColumn valeurs à ce qu’ils étaient avant l’impression. Si vous utilisez un état d'affichage pour l'impression, où l'utilisateur a peut-être un Centre d'impression type interface où ils peuvent voir ce qu’ils sont sur le point d’imprimer, cela serait utile. Si vous choisissez d'ajouter le PrintAdvancedDataGrid à l'étape via actionscript, cela serait inutile et dans cette étape, vous supprimeriez la PrintAdvancedDataGrid de la scène.

 printJob.send (); printColumn.width = before_widdy; printGrid.width = before_widdy; printGrid.rowHeight = before_hiddy; Alert.show ("Travail d'impression terminé!")

Étape 16: Ajouter un autre PrintAdvancedDataGrid si votre contenu dépasse 7500 hauteurs

     

Étape 17: dupliquez votre fournisseur de données et resultHandler

Mon appel de données ressemblait à ceci à l'origine:

 

Tout ce que je devais faire était d’ajouter un gestionnaire de résultat supplémentaire, de sorte que les données de la seconde PrintAdvancedDatagrid serait séparé:

 

Puis j'ai ajouté un nouveau gestionnaire de résultats:

 fonction privée httpResult_handler2 (evt: ResultEvent): void if (evt.result.lessons.row) var resultAC: ArrayCollection = evt.result.lessons.row comme ArrayCollection; pour (var i: int = 0; i 

Cette nouvelle fournisseur de données pour la seconde PrintAdvancedDatagrid est situé dans mon stripQuiz2 () fonction de filtrage.


Étape 18: Ajouter collectionVoir Variables et supplémentaires fournisseur de données

Dans mon cas, il me fallait ajouter 3 nouveaux ListCollectionViews et 1 de plus fournisseur de données:

 [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 ();

Étape 19: Ajouter filtreFonction Les fonctions

Pour les deux datagrides à partir desquelles je souhaitais imprimer, j'avais besoin de filtres permettant d'effectuer les tâches suivantes:

  1. Supprimez certains types d'activité de ma liste d'impression, car certains n'étaient pas nécessaires
  2. Tronquez les données en 12 entrées, car après des tests approfondis, j’ai trouvé qu’il s’agissait là de la limite pour imprimer avec succès des fichiers SWF pleine page depuis la grille de données.
  3. Supprimer les 12 premières entrées de la ListCollectionView pour le 2ème PrintAdvancedDatagrid

Cela a abouti à la création des fonctions suivantes:

 fonction privée stripQuiz (): void removeQuiz = new ListCollectionView (lessonsDataProvider); removeQuiz.filterFunction = quizStripped; removeQuiz.refresh (); quizLimit (); removeQuiz.refresh (); printGrid.dataProvider = removeQuiz;  fonction privée stripQuiz2 (): void removeQuiz2 = new ListCollectionView (lessonsDataProvider2); removeQuiz2.filterFunction = quizStripped; removeQuiz2.refresh (); quizPage2 (); removeQuiz2.refresh (); printGrid2.dataProvider = removeQuiz2;  fonction privée quizStripped (value: Object): Boolean return String (value.lessonIcon) .toUpperCase ()! = "QUIZ" && String (value.lessonIcon) .toUpperCase ()! = "HANGMAN" && String (value.lessonIcon ) .toUpperCase ()! = "FLASHCARDS" && Chaîne (value.lessonIcon) .toUpperCase ()! = "DOWNLOADS" && String (valeur.lessonIcon) .toUpperCase ()! = "VIDEO" && String (value.fileName). toUpperCase ()! = "ACTIFS / ACTIVITÉS / WORKSHEET_KIDS_AUDIO.SWF" && String (value.fileName) .toUpperCase ()! = "ACTIFS / ACTIVITÉS / WORKSHEET_KIDS_AUDIO5.SWF";  fonction privée quizLimit (): void for (var i: int = removeQuiz.length-1; i> = 0; i--) if (removeQuiz.length> = 13) removeQuiz.removeItemAt (i);  fonction privée 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); 

Étape 20: Ajouter une seconde printGrid à printJob

Avant d’envoyer le printJob, j’ai ajouté le second PrintAdvancedDatagrid être imprimé:

 printJob.addObject (printGrid2); printJob.send ();

Pour un meilleur aperçu du code complet, veuillez télécharger les fichiers source associés à ce didacticiel et consulter le main.mxml fichier.


Conclusion

Cela ne constitue peut-être pas la solution la plus élégante pour l’impression en masse de fichiers SWF de Flex, mais c’est une solution que j’ai trouvée qui fonctionne de manière fiable, avec une sortie de haute qualité. L'impression en Flex peut être un véritable ours, mais cela ne signifie pas pour autant que vous devez ignorer les options qui vous sont offertes, notamment par l'utilisation de PrintDatagrid et PrintAdvancedDatagrid. Merci beaucoup d'avoir lu mon tutoriel et j'attends avec impatience vos questions et commentaires..