Fermer

mai 18, 2021

Génération de PDF à partir de HTML dans React Demo: exportation de factures


Dans cet article de blog, nous allons créer un exemple de facture dans notre application React en utilisant HTML et CSS, puis générer un fichier PDF basé sur ce contenu. De plus, nous contrôlerons la taille de la page générée exclusivement via CSS.

Bienvenue dans la série d'articles de blog Génération de PDF dans React! Dans la partie 1 de cette série, « Génération de PDF dans React: aussi simple que 1-2-3 », nous avons abordé les bases de la génération de PDF dans React en incluant quelques éléments HTML de base et en voyant le moyen le plus rapide nous pouvons générer un fichier PDF à partir de HTML dans React.

Dans le billet de blog d'aujourd'hui, nous allons approfondir cela en couvrant un scénario très courant que l'équipe de KendoReact considère comme une demande fréquente: comment exporter une facture HTML au format PDF. Au-delà de certains HTML et CSS plus sophistiqués, nous allons également voir comment exporter des éléments SVG (via des graphiques) et comment des composants React encore plus avancés tels que DropDowns peuvent être inclus dans nos fichiers PDF générés.

De plus, nous verrons comment nous peut modifier dynamiquement la taille du papier du fichier PDF généré simplement via CSS. Comme crédit supplémentaire, nous verrons également comment nous pouvons intégrer nos propres polices personnalisées dans nos fichiers PDF pour assurer une bonne prise en charge Unicode.

Si vous aimez les didacticiels vidéo

Tout ce que je couvre dans le billet de blog aujourd'hui est également couvert dans la vidéo « Generating PDF in React: Part 2 » sur YouTube, qui recrée cette interface utilisateur Kendo pour la démo jQuery dans une application React. Donc, si vous préférez un support plus visuel, vous pouvez le regarder ici, ou vous diriger vers la section KendoReact Video où vous trouverez des liens supplémentaires.

Comment générer un document PDF: Exemple de facture

Ce que nous allons créer aujourd'hui est un exemple de mise en page d'une facture. Si vous n'êtes pas familier avec la terminologie, il s'agit essentiellement d'un document qui met en évidence les articles achetés dans le cadre d'une commande. Bien que les afficher dans nos applications Web ait beaucoup de sens, les factures sont très souvent envoyées au format PDF lorsque des personnes partagées peuvent ne pas avoir accès à ladite application Web. Cela peut inclure l'entreprise à laquelle vous vendez quelque chose. Donc, générer un PDF de HTML vers CSS devient critique ici.

Le code source de tout ce que nous faisons ici aujourd'hui, ainsi que les autres parties de cette série, peut être trouvé dans ce dépôt GitHub . L'article de blog d'aujourd'hui couvre le code du composant LayoutSample .

Allons-y et copions notre code HTML et CSS que nous pouvons utiliser comme base pour construire. Vous pouvez lancer un projet avec create-react-app puis dans votre App.js vous pouvez copier dans la section JSX du fichier JS, et vous pouvez copier le CSS dans App.css et partez à la course.

Par souci de simplicité et pour le rendre aussi facile que possible à partager avec tout le monde, voici un projet StackBlitz qui montre le HTML et JavaScript via App.js et le CSS dans style.css . Comme cela peut être un peu long, il est simplement plus facile pour vous de créer un fork de ce projet, ou de le copier-coller à partir de chacun des fichiers appropriés.

Une fois que vous l'avez installé, vous pouvez continuer avec le reste du billet de blog . Il y a quelques détails dans le balisage ci-dessus que nous ajouterons et couvrirons plus en détail, alors ne vous inquiétez pas trop de ce que pourraient être les classes CSS et le balisage HTML.

Maintenant que nous avons cet ensemble, continuons par en ajoutant quelques visualisations de données supplémentaires dans notre application React.

Rendre notre facture pop: Ajouter la visualisation de données

Pour essayer de rendre cette facture aussi sophistiquée que possible, je veux ajouter une visualisation de données pour rendre la fin- résultat vraiment pop. Cela me permet de faire d'une pierre deux coups. Tout d'abord, je peux ajouter quelque chose qui est visuellement agréable à l'exemple. Et, deuxièmement, je peux montrer comment générer des fichiers PDF à partir de HTML qui incluent des éléments SVG.

Puisque nous nous sommes efforcés de nous simplifier les choses dans ces projets, je me pencherai sur les graphiques KendoReact library car elle me permet de créer un graphique avec juste quelques lignes de code au lieu de coder moi-même des éléments SVG à la main. Plus précisément, je souhaite ajouter un React Donut Chart dans la facture que je configure pour la génération PDF.

En regardant la KendoReact Chart Component Getting Started page nous pouvons copiez et collez la commande suivante dans notre console et installez les paquets appropriés:

 npm install --save @ progress / kendo-react-charts @ progress / kendo-drawing @ progress / kendo-react-intl hammerjs @ progress / kendo -licensing 

Nous devons également installer l'un des thèmes KendoReact, qui dans ce cas sera le thème matériel. Cela peut être fait avec npm install :

 npm install --save @ progress / kendo-theme-material 

Et puis nous importons le fichier CSS associé au thème:

 import "@ progress / kendo-theme-material / dist / all.css"; 

Une fois cette installation et configuration terminées, nous devons importer les morceaux appropriés dans notre composant React:

 import   { 
  Graphique 
  ChartLegend 
  ChartSeries 
  ChartSeriesItem 
  ChartSeriesLabels 
  ChartCategoryAxis 
  GraphiqueCategoryAxisItem
}   de   "@ progress / kendo-react-charts" ; 
 import   "hammerjs" ; 
 import   "@ progress / kendo-theme-material / dist / all.css "; 

Dans le cadre de tout graphique, nous devons également disposer d'une sorte de données. Ajoutons donc ce tableau quelque part dans notre application. Dans mon cas, j'ai créé facture-data.json et importé ce fichier dans mon composant, mais n'hésitez pas à l'ajouter là où cela vous semble naturel.

 [
   {
     " produit ":  " Chicken "
    " share ":   0.175 
  } 
   {
    " product "[19659028]:   "Pork" 
     "share" :   0.238 
  } 
   {
     "product" : [19659027] «Turquie» 
     «part» :   0,118 
  } 
   {
     «produit» :   «Kobe Beef "
    " share ":   0.052 
  } 
   {
    " product ":  " Pickled Herring " ]
     "share" :   0.225 
  } 
   {
     "product" :   "Bison" [19659038] "partager" :   0,192 
  } 
] 

C'est aussi ainsi que j'ai importé les données dans mon composant:

 import sampleData from "./invoice-data.json";[19659019</font>Maintenantpourajoutercecidansmonprojetjevaisrechercherledivavecunaccessoire className = "pdf-chart"  défini dessus. De là, je suivrai la documentation de KendoReact pour définir mon Donut Chart: 

 < div    className  =  " pdf-chart "  [19659028]> 
   < Graphique    style  =  { { hauteur :    280  } }  [19659028]> 
     < ChartSeries > 
       < ChartSeriesItem 
         type  =  " donut "  
         data  =  { sampleData }  
         categoryField  =  " product "  
         field  =  " part " 
      > 
         < ChartSeriesLabels 
           color  =  " #fff "  [19659131] background  =  " none " 
         /> 
       </  ChartSeriesItem > 
     </  Ch artSeries > 
   </  Chart > 
 </  div > 

Le graphique en anneau React est assez flexible, mais malgré cela, le balisage peut devenir intuitif rapidement. Tout d'abord, nous définissons un pour définir un seul graphique en anneau (le package KendoReact Data Visualization peut prendre en charge plusieurs séries à la fois) où nous connectons nos données dans le prop data et définissons nos deux champs dans categoryField et field aux deux champs trouvés dans nos exemples de données. L'élément est juste là pour nous permettre d'afficher les étiquettes dans le graphique en anneau - qui ne sera que du texte blanc dans notre cas.

Pour avoir un aperçu rapide de l'état actuel de notre projet, voici tout ce qui fonctionne dans StackBlitz:

Ensuite, nous verrons comment nous pouvons utiliser les classes CSS et un DropDown pour contrôler la taille du papier de notre facture et finalement le fichier PDF que nous générons.

Dynamic Paper Size via CSS

Prenons quelques time et inspectez le CSS que nous avons collé au début de cet article ou dans l'un des projets StackBlitz. Plus précisément cette section ici:




 .size-a4   {
   width :   6.2  in ; 
   height :   ] 8.7  dans ; 
} 

 .size-letter   {
   width :   6.3  in ; [19659155] height :   8.2  in ; 
} 

 .size-executive   {
   width :   5.4  in ; 
   height :   7.8  in ; 
   font-size :   12  px ; [19659096]} 
 .size-executive    .pdf-header   {
   margin-bottom :    .1  in ; 
} 

À partir de là, nous pouvons voir que nous avons trois tailles de page différentes dans lesquelles nous pouvons opérer: A4, Letter et Executive. Normalement, lorsque nous générons un PDF dans React, nous devons nous fier au support paperSize du KendoReact PDF Generator pour définir le format de papier souhaité. Cependant, si nous connaissons les mesures pour la sortie souhaitée, nous pouvons en fait personnaliser cela à 100% grâce à CSS!

Dans notre facture, c'est l'élément dont nous avons besoin pour ajuster et définir une nouvelle classe CSS lorsque nous voulons mettre à jour le taille de la facture:

Pour cette application, nos utilisateurs ont besoin de pouvoir personnaliser le type de papier sur lequel le PDF doit être généré , alors donnons à nos utilisateurs un DropDown qui peut sélectionner parmi les tailles disponibles et changer le format de papier à la volée.

Chaque fois que nous avons une liste finie d'options disponibles que nous voulons que les utilisateurs choisissent (sans avoir la possibilité d'entrer texte personnalisé), un élément select est généralement un excellent moyen de procéder. Cependant, puisque nous avons déjà KendoReact inclus dans notre projet, nous pouvons aussi bien opter pour une version plus sophistiquée de cet élément et passer à la React DropDownList . Pour que cela soit ajouté dans notre application, nous devons installer le package à l'aide de la commande npm install suivante, trouvée sur la page de présentation du package de React DropDown :

 npm install --save @ progress / kendo-react -dropdowns @ progress / kendo-react-intl @ progress / kendo-licensing 

Une fois que nous l'avons installé, nous pouvons importer la DropDownList dans notre composant React:

 import   { DropDownList  }   de    "@ progress / kendo-react-dropdowns" ; 

Maintenant, nous devons définir la liste des options disponibles pour se lier à notre React DropDownList. Voici la variable que nous pouvons utiliser:

 const  ddData  =   [
   { text :    "A4"  value :    "size-a4"  } 
   { text :    "Letter"  value : [19659199] "size-letter"  } 
   { text :    "Executive"  value :    "size -exécutif " } 
] ; 

Comme vous pouvez le voir, nous utilisons le champ text pour nous donner une chaîne facile à lire que nous pouvons présenter à l'utilisateur, tandis que le champ value pour chaque élément utilise le nom de classe CSS que nous voulons définir pour chaque option.

Une autre chose que nous devons définir est une sorte d'état dans notre composant qui peut garder une trace de la valeur actuelle de l'élément sélectionné - c'est un composant React , après tout! Donc, nous pouvons le faire en important useState de React et l'utiliser pour définir une variable. Tout d'abord, nous effectuons l'importation appropriée:

 import   { useRef  useState  useEffect }   from    'react' ; 

Ensuite, dans notre composant, nous pouvons configurer ce qui suit:

 const   [ layoutSelection  setLayoutSelection ]   =    useState  (  { texte :    "A4"  valeur :    "size-a4" } ) ; 

Pour ceux d'entre vous qui n'ont pas encore utilisé React Hooks, cela peut sembler un peu déroutant, mais la partie layoutSelection est la variable à laquelle nous pouvons accéder dans notre application, et setLayoutSelection ] peut être appelé lorsque nous voulons mettre à jour notre état. De plus, pour que nous ayons un élément par défaut sélectionné lorsque notre application se charge, nous définissons un état initial égal à celui de notre première option dans notre DropDownList, qui est le format A4.

Une fois que nous avons fait tout cela , nous pouvons ajouter le code suivant en haut de l'application en trouvant le premier élément

en haut de notre HTML:

 < div    className  =  " ] box-col  " > 
   < h4 >  Sélectionnez une taille de page  </  h4 > 
   < DropDownList 
     data  =  { ddData } 
     textField  =  " text " 
     dataItemKey  =  " value " 
     value  =  { layoutSelection } 
     onChange  =  { updatePageLayout }  
  > 
  </  DropDownList > 
 </  div > 

Comme vous pouvez le voir, nous passons notre variable ddData à DropDownList, puis définissons le textField pour représenter ce que l'utilisateur verra et le dataItemKey être la valeur sous-jacente. Nous définissons la valeur initiale de notre variable layoutSelection et enfin nous utilisons l'événement onChange pour appeler une fonction que nous utiliserons pour mettre à jour notre état. Puisque nous n'avons pas encore défini cela, allons-y et faisons-le:

 const   updatePageLayout   =   ( event )   =>   {[19659284] setLayoutSelection  ( event .  target .  value ) ; 
} 

La dernière pièce du puzzle est également de mettre à jour le CSS de l'élément div susmentionné qui nous permet de contrôler les dimensions de notre facture. Plus précisément, cet élément:

Afin de mettre à jour le className chaque fois que l'état de layoutSelection change, nous pouvons définir le className prop doit être égal à une chaîne littérale qui saisit la valeur actuelle de layoutSelection avec ce qui suit:

 < div className  =  {  `pdf-page  $ { layoutSelection .  value }   `  } > 

Maintenant, chaque fois que notre état est mis à jour, cette partie de notre code sera également mise à jour pour être l'une des chaînes suivantes:

  • pdf-page size-a4
  • pdf-page size-letter
  • pdf- page size-executive

Une fois que nous avons compilé les choses et que notre application est opérationnelle, vous pouvez sélectionner une valeur dans la React DropDownList et voir comment la mise en page de la facture change à chaque choix!

Voici une mise à jour -date Projet StackBlitz présentant nos progrès jusqu'à présent.

Le décor est planté, passons donc à la dernière étape de notre voyage et permettons aux utilisateurs de générer un PDF de différentes tailles en fonction du choix que notre utilisateur a fait! [19659304] Il est temps de générer notre PDF à partir de HTML

Maintenant que nous avons la facture globale HTML et CSS au carré, ainsi qu'un DropDown avec lequel les utilisateurs peuvent interagir pour modifier la mise en page de la facture, ajoutons la génération PDF à notre application React !

Pour ce faire, j'aurai besoin du package KendoReact PDF Generation que nous également utilisé dans la partie 1 de cette série d'articles de blog, et je vais également ajouter le bouton KendoReact pour nous donner un joli bouton sur lequel appuyer afin de générer un fichier PDF à partir du HTML de notre application React.

Pour commencer cette étape, je vais simplement lancer l'installation de npm suivante:

 npm install --save @ progress / kendo-react-pdf @ progress / kendo-drawing @ progress / kendo- React-Buttons @ Progress / Kendo-Licence

Et puis importez les deux composants en ajoutant ceci en haut de mon composant React:

 import   { Button }   from    '@ progress / kendo-react- boutons '; 
 import   { PDFExport  savePDF }   from   ' @ progress / kendo-react-pdf ' ; 

Tout d'abord, je vais adopter l'approche la plus simple pour exporter au format PDF en enveloppant simplement le contenu souhaité avec un composant . Oui, c’est vraiment aussi simple que cela! Dans ce cas, je dois envelopper l'élément div que nous venons d'utiliser pour mettre à jour dynamiquement la taille de la page, ce qui devrait me laisser avec ce qui suit:

 < div    className  =  " page-container hidden-on-narrow "  > 
   < PDFExport    ref  =  { pdfExportComponent  }  > 
     < div className  =  {   `page-pdf  $ { layoutSelection .  value }   ` } > 
     ... 
     </  div > 
   </  PDFExport > 
   ... 
 </  div > 

Nous utilisons l'hélice ref ci-dessus afin de nous permettre de référencer rapidement cet élément lorsque nous devons lancer notre génération. Grâce à notre importation précédente de useRef de React, nous pouvons simplement ajouter la ligne de code suivante à notre composant:

 const  pdfExportComponent  =   useRef  ([19659351] null ) ; 

Ensuite, nous pouvons continuer et ajouter notre bouton React quelque part sur la page. Dans ce cas, je pense qu'il est logique de l'ajouter sous DropDownList et de lui donner un en-tête approprié, alors ajustons le haut de la page pour qu'il ressemble à ceci:

 < div    className  =  " box wide hidden-on-narrow "  > 
   < div    class  =  " box -col  " > 
     < h4 >  Sélectionnez une taille de page  </  h4 > 
     < DropDownList 
       data  =  { ddData } 
       textField  =  " text " 
       dataItemKey  =  " value " 
       value  =  { layoutSelection } 
       onChange  =  { updatePageLayout } 
    > 
     </  DropDownList > 
   </  div > 
   < div    className  =  "  box-col  " > 
     < h4 >  Export PDF  </  h4 > 
     < Button    primary  =  { true }     onClick  =  { handleExportWithComponent }  >  Exporter  </  Bouton > 
   </  div > 
 </  div > [19659253]

J'ai également inclus le code React DropDownList pour vous donner une référence, mais l'élément le plus important à regarder ici est le




Source link