Catégorie : Développement

Dossiers et exemples de code dans différents langages de programmation tels que Java, Javascript, PHP, Windev, C#… mais aussi de balisage comme HTML.

Vincent Lecomte
[Java] Mémo – Trucs et astuces impliquant l’API Stream

[Java] Mémo – Trucs et astuces impliquant l’API Stream

Java propose l’API Stream, qui permet de manipuler et effectuer des opérations sur un ensemble de données, telles qu’une collection, un tableau ou même un flux I/O. Elle offre diverses possibilités : tri, parcours de collections, extraction d’éléments à l’aide de filtres, etc.

Dans cet article nous allons voir comment effectuer un tri basique pour retourner une nouvelle liste mais également comment retourner une liste d’objets d’un type spécifique.

Trier une liste

On suppose que l’opération sera effectuée sur une liste d’objets de la classe Client. Cette dernière définit plusieurs membres dont un numéro de client (numClient) et son getter. Nous souhaitons récupérer une nouvelle liste de noms.

listeClients.stream()
	.sorted(Comparator.comparing(Client::getNumClient))
	.map(lo_c -> lo_c.getNomClient())
	.collect(Collectors.toList());

Dans cet exemple nous avons effectué plusieurs opérations sur le stream :

  • Une opération intermédiaire de tri, grâce à la méthode sorted() qui reçoit en paramètre un Comparator.
  • Une seconde opération intermédiaire qui permet de définir ce que l’on souhaite récupérer, en l’occurrence le nom de la personne.
  • Une troisième opération, finale cette fois, qui consiste en une réduction: on demande à ce que le résultat soit sous forme de liste.

Notez que si vous manipulez une List vous pouvez la trier directement à l’aide de la méthode sort(). La méthode effectue l’opération sur la liste existante sans en créer une copie de celle-ci.

Exemple:

listeClients.sort(Comparator.comparing(Client::getNumClient));

Retourner une liste d’un type spécifique

Comme on l’a vu ci-dessus, à l’aide de la méthode map(), on a obtenu une liste de chaines de caractères. Voyons comment aller plus loin pour retourner une liste d’un type spécifique. Toujours sur base d’un client, nous avons une classe nommée ClientDTO qui sera une version réduite. Elle contiendra uniquement le numéro de client et son nom, ainsi qu’un constructeur prenant en paramètre ces deux champs.

listeClients.stream()
	.sorted(Comparator.comparing(Client::getNumClient))
	.collect(Collectors.mapping(lo_c -> {
		return new ClientDTO(
			lo_c.getNumClient(), lo_c.getNomClient()
		);
	}, Collectors.toList()));

Cette fois on effectue un mappage à l’aide de Collectors.mapping(): la fonction en paramètre retourne une instance de ClientDTO avec les champs de notre classe Client. On demande ensuite à ce que le résultat final soit retourné sous forme de liste, comme dans l’exemple ci-dessus.

Bien sûr ce sont deux exemples parmi tant d’autres, l’API offrant énormément de possibilités. Et même si cela a été introduit dans Java 8 on n’a pas toujours la possibilité ou le temps d’en explorer les différentes méthodes. Voici quelques liens qui pourraient vous intéresser pour creuser le sujet:

Bon développement !

[JS] Récupérer le contenu d’un éditeur tinyMCE

[JS] Récupérer le contenu d’un éditeur tinyMCE

Si vous ne connaissez pas encore tinyMCE, il s’agit d’un éditeur WYSIWYG que vous pouvez intégrer à vos sites. Il est notamment très connu grâce à son utilisation dans WordPress. L’édition Community est gratuite mais il existe également des offres avec support et plugins premium.

Pour une raison ou une autre vous souhaitez peut-être récupérer le contenu d’un éditeur initialisé avant de l’envoyer au serveur. Cela est évidemment possible ! Bien que cet article serve avant tout de mémo il va également vous aider à ne pas plonger dans les méandres de l’énorme documentation de la librairie. Voyons ensemble comment procéder.

Obtenir l’instance d’éditeur

Il faut tout d’abord récupérer l’éditeur souhaité avec la méthode tinymce.get(). Celle-ci reçoit une chaine de caractères représentant l’identifiant du champ qui a servi pour l’initialisation de tinyMCE.

Supposons que vous partiez d’un champ de type textarea, avec l’attribut “id” contenant simplement “myTinyEditor” :

var med = tinymce.get('myTinyEditor');

Cela renverra l’instance de l’éditeur, sinon null s’il n’a pas encore été initialisé.

Récupérer le contenu de l’éditeur

Sur l’instance de l’éditeur que vous venez de récupérer, il suffit d’utiliser getContent() pour retourner le contenu au format “brut” (donc en HTML, qui est généré par tinyMCE).

var contHtml = med.getContent();

Remarque: si le champ est vide, c’est bien une chaine vide que vous obtiendrez.

Vous savez désormais comment récupérer le contenu d’un éditeur tinyMCE, bravo !

A lire également…

[JS] Personnaliser la liste de styles dans tinyMCE

Dans l’éditeur tinyMCE, lorsqu’on choisit de dérouler le menu de sélection du format, on dispose d’éléments par défaut comme les en-têtes (h1 à h6), l’alignement ou bien même la mise en forme classique comme le “gras”, “souligné” ou “italique”. Ce menu peut être personnalisé de différentes manières. La méthode la plus simple reste de redéfinir […]

0 commentaire

Sources

Tout est bien décrit dans la documentation de référence.

[JS] Retour sur le rendu d’une page avec PDF.js

[JS] Retour sur le rendu d’une page avec PDF.js

Il y a déjà un moment nous abordions le fait de pouvoir afficher une page de PDF sous forme d’image grâce à la librairie PDF.js. Les différentes mises à jour de celle-ci ont conduit à ce que certains appels soient désormais dépréciés, bien que toujours fonctionnels.

Voici le nouveau code que nous pouvons utiliser :

pdfjsLib.getDocument(
{
	data : ao_pdfData
})
.promise.then(function(dPdf)
{
	dPdf.getPage(ai_num).then(function(page)
	{
		var canvas = document.createElement('canvas');
		canvas.id = as_id + '-page-' + ai_num;
		canvas.className = 'f-canvas';

		var vContext = canvas.getContext('2d');
		var vViewport = page.getViewport({
			scale: af_scale2,
			rotation: 0
		});
		
		canvas.height = vViewport.height;
		canvas.width = vViewport.width;

		var renderContext = {
			canvasContext: vContext,
			viewport: vViewport
		};
		
		page.cleanupAfterRender = true;
		
		var renderTask = page.render(
			renderContext
		);
		
		renderTask.promise.then(function()
		{
			if (canvas.msToBlob) 
			{
				$('#' + img_id).attr("src", 
					canvas.toDataURL(
						"image/jpeg", 0.85
					)
				);
			}
			else
			{
				canvas.toBlob(function(blob) 
				{
					let img = new Image();
					img.onload = function() { 
						URL.revokeObjectURL(img.src); 
					}; 
					img.src = URL.createObjectURL(blob);
					$('#' + img_id).attr("src", 
						img.src
					);
				}, "image/jpg", 0.85);
			}
		})
	});
});

Quelques détails concernant ce code :

  • On charge toujours le document en passant en paramètre les données qui auront été décodées à l’aide de la méthode atob(). On aura passé le contenu du PDF sous forme de chaine de caractères en Base64.
  • Petite différence : on appelle la méthode then() sur un objet “promise”. Même modification pour la tâche de rendu (variable “renderTask”).
  • La variable “viewport” est toujours initialisée avec getViewport() mais on passe un objet contenant les paramètres.
    • scale : l’échelle permettant de définir le zoom (ex: 1,5)
    • rotation : indique la rotation du document (0 = position initiale)
  • On définit toujours la hauteur et la largeur du canevas avec les valeurs du viewport.
  • On ajoute une petite option qui permet d’indiquer que la page doit être libérée et nettoyée après son rendu.
  • Petite nouveauté : l’utilisation de la méthode toBlob() dans les navigateurs qui supportent cela. Notez que si la méthode “msToBlob” existe alors on va plutôt appeler toDataUrl() pour la compatibilité avec IE.
    • On peut également déterminer le type de l’image.
    • On peut aussi indiquer la compression (ex : 0.85, 1 étant la qualité la plus élevée).

Grâce à ces modifications vous n’obtiendrez plus de message dans la console indiquant du code deprecated.

N’hésitez pas à partager votre expérience ou à suggérer des améliorations pour ce code !

[Java] Filtre sur liste avec les streams

[Java] Filtre sur liste avec les streams

L’une des grosses améliorations de Java 8, c’est ce qu’on appelle les streams. C’est un nouveau pattern de manipulation de données et cela permet de se passer notamment des itérateurs que l’on connait. On peut les utiliser sur des collections ou même des tableaux.

On prend la classe suivante comme exemple :

public class MyObject
{
 private String sId;
 private String sName;
 
 // ...
}

Une méthode nous retourne alors une liste qui reprend des objets caractérisés par leur nom et un identifiant. On voudrait filtrer la liste pour ne récupérer que les objets nommés “chair” par exemple.

Stream<MyObject> lo_s = lo_listObj.stream().filter(
 myObj -> myObj.getName().equals("chair")
);

Le paramètre de la méthode filter() est un prédicat (type Predicate). Le code ci-dessus renvoie un stream que l’on peut ensuite manipuler pour retourner une collection ou bien un seul objet. Par exemple on pourrait utiliser la méthode collect() pour renvoyer une nouvelle liste.

List<Myobject> lo_list = lo_s.collect(Collectors.toList());

On peut aussi retourner le premier objet qui correspond au filtre, avec findFirst(). Cela retourne un objet de type Optional.

Optional<MyObject> lo_opt = lo_s.findFirst();

Plusieurs opérations sont possibles sur cet objet. On peut savoir s’il y a bien un résultat avec la méthode isPresent(), ou bien retourner directement le résultat ou une autre valeur si aucun objet n’avait été trouvé lors du filtre.

MyObject lo_result = lo_opt.orElse(lo_defaultObject);

La méthode orElse() renvoie la valeur qui avait été trouvée et si elle n’est pas présente, alors elle renvoie un autre objet du même type.

if (lo_opt.isPresent())
{
 MyObject lo_result = lo_opt.get();
}

L’exemple ci-dessus montre comment récupérer l’objet uniquement s’il est présent et pour également éviter l’exception NoSuchElementException. Cela peut être un raccourci à la méthode orElse(), tout dépend de quoi on a besoin en retour et ce qu’on va en faire.

[Java] Mémo – Validation de beans

[Java] Mémo – Validation de beans

En Java, il est possible d’utiliser la validation de beans pour permettre d’en valider son contenu, donc les différents membres de la classe. Par exemple, si on a une classe “Personne“, qui contient un nom et un prénom, on voudrait valider que ceux-ci ne dépassent pas une certaine taille ou même qu’ils respectent une expression régulière. Plutôt que de créer des méthodes visant à vérifier chaque élément un à un, on va se baser sur des annotations.

Prenons la classe suivante comme référence pour ce 1er exemple :

public class Person
{
    @Size(min = 1, max = 5, message = "cod: btw. 1 and 5")
    private String      cod;
 
    @Size(max = 60, message = "firstName: Length max 60")
    private String      firstName;

    @NotNull(message = "birthdate: mandatory")
    private LocalDate   birthdate;
 
    // ...
}

On utilise l’annotation Size pour définir la taille maximum qu’une chaine peut avoir. Si on ne spécifie pas de minimum, cela veut dire que la chaine peut être vide. A chaque fois on spécifie le paramètre “message” pour indiquer quel sera le message retourné lors de la validation.

Pour récupérer les erreurs sous forme de chaine :

Person lo_p = new Person();
Set<ConstraintViolation<T>> lo_violations = 
 Validation.buildDefaultValidatorFactory()
  .getValidator()
  .validate(lo_p);
for (ConstraintViolation<T> lo_violation : lo_violations)
{
    System.out.println(lo_violation.getMessage());
}

Ce code affiche les messages en fonction des champs qui sont en erreur par rapport à l’objet qu’on donne en paramètre de la méthode validate().

Si notre classe contient une liste d’objets que l’on veut aussi valider, ou un objet d’une autre classe, il faut rajouter une annotation Valid pour qu’il soit pris en compte lors de la validation.

public class PremObj
{
    @Size(min = 1, max = 20, message = "id: btw. 1 and 20")
    private String                  id;
 
    @Valid
    @NotNull(message = "liste_sousobj: Mandatory")
    private List<UnSousObj>  liste_sousobj;
 
    // ...
}

Chaque objet de la liste sera donc analysé. C’est aussi valable si on avait mis un seul objet de type “UnSousObj“. La classe que l’on référence doit évidemment posséder diverses annotations de validation.

Un champ peut également être validé sur base de valeurs d’une énumération. On peut ainsi utiliser l’annotation Enum (sur une variable de type String). Le paramètre obligatoire “enumClass” permet de spécifier la classe qui servira à la validation.

D’autres annotations utiles :

  • Pattern : sur une chaine, permet de faire en sorte qu’elle respecte une expression régulière.
  • Min : indique la valeur minimale d’un nombre.
  • Max : indique la valeur maximale d’un nombre.

Liens

Liste des annotations disponibles

[Utilitaires] Plugin Compare pour Notepad++

[Utilitaires] Plugin Compare pour Notepad++

Si vous cherchez un plugin de comparaison pour la version 64 bits de Notepad++, vous pouvez télécharger celui proposé par le développeur Pavel Nedev. Il vous permettra de mettre en évidence les différences dans deux fichiers texte, et si ceux-ci correspondent vous serez directement notifié par l’outil.

Téléchargez donc la version 64 bits. Pour l’installer:

  • Depuis Notepad++ cliquez sur le menu Compléments puis sur Open plugins folder…
  • Par défaut cela ouvre C:\Program Files\Notepad++\plugins
  • Créez un sous-dossier “ComparePlugin“.
  • Décompressez le contenu de l’archive dans ce nouveau dossier.

Vous devriez donc obtenir quelque chose de similaire à la capture d’écran ci-dessous.

Fermez Notepad++ puis relancez-le. Vous devriez donc avoir le menu

[SQL] Rechercher du texte dans un BLOB

[SQL] Rechercher du texte dans un BLOB

En SQL il est possible de rechercher du texte dans une colonne de type BLOB. Attention que cette méthode s’applique à la base de données Oracle. On utilise des méthodes internes qui permettent de convertir le terme cherché en données brutes et effectuer une recherche de caractères dans la colonne.

Voici le code à utiliser :

SELECT *
FROM t1
WHERE DBMS_LOB.INSTR (
   t1.champ_blob, 
   UTL_RAW.cast_to_raw (
     'Search text'
   ), 1, 1 
) > 0

Explications:

  • Le premier paramètre de la méthode “instr” est le champ BLOB dans lequel on veut effectuer la recherche.
  • L’appel à UTL_RAW.cast_to_raw en tant que second paramètre, permet de convertir la chaine de recherche en données brutes (RAW)
  • Le troisième paramètre de la méthode est l’indice à partir du quel on cherche.
  • Le quatrième paramètre indique quelle occurrence on souhaite (dans l’exemple on récupère la première)
  • Enfin le résultat est un la position de l’occurrence trouvée. Dans notre cas on vérifie qu’elle est supérieure à 0 juste pour récupérer tout ce qui correspond au terme de recherche

C’est plutôt pratique quand on stocke par exemple du XML ou du JSON dans un champ de type BLOB.

[JS] Prism, une alternative à SyntaxHighlighter

[JS] Prism, une alternative à SyntaxHighlighter

En guise d’alternative au très bon SyntaxHighlighter développé par Alex Gorbatchev (voir le site ici) mais qui n’est malheureusement plus mis à jour, on peut utiliser Prism.js.

Il offre la coloration syntaxique pour afficher du code de manière à ce qu’il soit lisible par les utilisateurs. Il se veut intuitif et extensible car il est possible d’ajouter assez facilement des langages à ceux déjà pris en charge. On peut même basculer entre différents thèmes. La librairie est utilisée par de nombreux sites tels que React ou même Drupal.

Pour l’utiliser sur Blogger comme c’est mon cas, il faut importer les scripts et styles de base. Et pour cela il faut modifier le thème du blog. Depuis le tableau de bord de votre blog choisissez Thème puis cliquez sur Modifier le code HTML.

Juste avant l’élément fermant head du thème, il faut inclure les feuilles de style.

<link href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism.css' rel='stylesheet'/>
<link href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/line-numbers/prism-line-numbers.css' rel='stylesheet'/>

De même qu’il faut inclure le script et l’autoloader avant la fermeture de l’élément body. On y ajoute aussi les différents plugins que l’on veut utiliser. Les éléments obligatoires sont prism-core et prism-autoloader.

<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-core.min.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/autoloader/prism-autoloader.min.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/line-numbers/prism-line-numbers.min.js'/>

Ensuite on peut commencer à utiliser les blocs de code. Il faut utiliser les balises pre et code. La seconde prendra une classe qui sera le langage du code que l’on veut formater. La liste complète est disponible sur le site officiel. La classe peut être language-* ou lang-*, l’astérisque étant remplacée par le bon code pioché dans la liste.

<pre>
<code class="lang-html">
<!-- Code qu'on veut formater -->
</code>
</pre>

Il faut faire attention car il faut échapper les caractères du code à formater, sinon il sera évidemment interprété (très important donc si on veut afficher du HTML au lecteur).

Pour éviter de le faire à la main utilisez plutôt l’outil en ligne Quick Escape Tool.Petit truc supplémentaire avant de nous quitter : afin d’utiliser le plugin line-numbers (destiné à afficher les numéros de ligne) que nous avons importé dans le second exemple ci-dessus, il vous suffira d’ajouter la classe “line-numbers” à l’élément ouvrant pre. N’hésitez pas à consulter le site officiel : vous y découvrirez de nombreux plugins ainsi que des tutoriels.

Bon développement !

Prismjs.com

[Java] Gestion des erreurs à l’aide d’une servlet

[Java] Gestion des erreurs à l’aide d’une servlet

Dans votre application web, il est possible de réaliser une gestion d’exceptions – notamment pour intercepter ServletException – en passant par une servlet. Par défaut, les erreurs telles que le code HTTP 500 sont gérées par le serveur et renvoient vers une page par défaut. L’idée est donc de changer ce comportement en renvoyant par exemple une information en JSON ou en redirigeant vers une JSP.

On va donc créer une classe qui hérite de HttpServlet. Celle-ci devra implémenter des fonctions pour gérer les différentes méthodes HTTP (exemple : PUT, GET, POST…).

public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        // On gère l'erreur...
    }
}

Comme on peut le constater on a donc créé une fonction qui sera exécutée lorsque la méthode GET est utilisée. Typiquement lorsqu’on appelle une URL et qu’on spécifie un ensemble de paramètres dans celle-ci. Il faudra donc ajouter les autres fonctions comme doPost() – généralement appelée lors d’un envoi de formulaire – ou doPut().On remarque aussi l’annotation @WebServlet qui permet de définir tout un ensemble d’informations utiles, notamment l’ “URL pattern”. On peut soit spécifier cette valeur directement comme dans l’exemple ci-dessus, soit en spécifiant les attributs de la manière suivante.

@WebServlet(
        name = "maBelleServlet",
        description = "Gestion d'exceptions",
        urlPatterns = "/maServletHttp"
)
public class MaServletHttp extends HttpServlet 
{
    // Code de la servlet...
}

Certains attributs de la servlet ne sont utiles que pour les outils utilisés lors du développement (par exemple, description ou encore smallIcon). Ces attributs sont décrits dans la documentation de JavaEE 7.Il faut ensuite modifier le fichier web.xml pour spécifier dans quels cas la servlet doit être appelée pour gérer les exceptions ou les différents code d’erreur. Dans l’exemple ci-dessous on va faire en sorte que la servlet soit appelée en cas d’erreur HTTP 500.

<web-app ... >
    <error-page> 
        <error-code>500</error-code> 
        <location>/maServletHttp</location> 
    </error-page>
</web-app>

On a donc ajouté un élément “error-page” dans le fichier descriptif de l’application. Pour cet élément on a spécifié le code d’erreur grâce à l’élément “error-code” et l’emplacement de la servlet (qui correspond au URL pattern défini précédemment dans l’annotation de la classe Java) représenté par l’élément “location“.

A la place de l’élément “error-code” on peut aussi spécifier “exception-type” et indiquer les erreurs que la servlet devra intercepter. On y spécifie alors le canonical name de la classe d’exception visée (ex : java.lang.NullPointerException).

Une fois le fichier de configuration XML modifié, on peut s’attaquer au code de la servlet. Aussi bien lorsqu’on redirige vers une JSP qu’une servlet, des attributs contenant des informations à propos de l’erreur qui se produit, sont définis au niveau de la requête et peuvent donc être rapatriés dans le code.

@WebServlet("/maServletHttp")
public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        Integer li_st = (Integer) request.getAttribute(
                "javax.servlet.error.status_code"
        );

        Throwable lo_e = (Throwable) request.getAttribute(
                "javax.servlet.error.exception"
        );

        String ls_svlt = (String) request.getAttribute(
                "javax.servlet.error.servlet_name"
        );
        
        // Envoi de la réponse après.
        // Voir ci-dessous.
    }
}

Voici le tableau des attributs disponibles (source : tutorialspoint).

L’attribut qui contient le nom de la servlet est intéressant car il s’agit de la source, là où l’erreur s’est produite. Cela signifie qu’en fonction du nom on peut imaginer un traitement différent en retour.L’exemple ci-dessous renvoie simplement du JSON au client après une erreur dans un Web Service.

@WebServlet("/maServletHttp")
public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        // Récupération des attributs avant.
        // Voir ci-dessus.
        if (ls_svlt.equals("webserviceServlet"))
        {
            response.setContentType("application/json");
            response.getWriter().print(
                "{ key1: 'val1', key2: 'val2' }"
            );

            response.getWriter().flush();
        }
    }
}

On peut également modifier le code de retour (par exemple, si le code était 500, on peut le redéfinir au niveau de l’objet HttpServletResponse).

Sources

Baeldung
CodeJava.net
LogicBig
Oracle
Tutorialspoint

[JS] Afficher un PDF en image avec pdf.js

[JS] Afficher un PDF en image avec pdf.js

Il existe plusieurs méthodes en Java pour transformer un PDF (ou une partie seulement) en image côté serveur, afin de renvoyer le résultat au client, pour qu’il ne lui reste plus qu’à l’afficher. La première qui vient à l’esprit est Apache PDFBox. D’autres comme IcePDF ou JPedal font bien le job aussi, mais sont souvent payantes. De plus, le traitement peut évidemment vite devenir lourd pour le serveur si de nombreuses requêtes sont effectuées par plusieurs utilisateurs.

On peut imaginer laisser le client faire le boulot, en utilisant la librairie pdf.js, qui est sous licence Apache. Elle permet de visualiser des documents PDF dans une page web mais aussi de les transformer en image ce qui nous intéresse ici.

L’idée de l’exemple qui suit est de transformer une page donnée en image. Après ajout du script principal dans l’élément head, on va créer une fonction qui recevra plusieurs paramètres tels que les données du fichier PDF (sous forme de chaine encodée en Base64), le numéro de page à transformer, un ID pour la création du canvas, une valeur pour l’échelle du rendu, et l’identifiant de l’élément img qui recevra le résultat.

PDFJS.getDocument({data : atob(ao_pdfData)})
    .then(function(ao_pdf) 
{
 ao_pdf.getPage(ai_num).then(function(ao_page) 
 {
  var lo_canvas = document.createElement('canvas');
  lo_canvas.id = as_idd + '-page-' + ai_num;
  lo_canvas.className = 'f-canvas';

  var lo_context = lo_canvas.getContext('2d');
  var lo_viewport = ao_page.getViewport(af_scale2);
  lo_canvas.height = lo_viewport.height;
  lo_canvas.width = lo_viewport.width;
  
  var lo_renderContext = {
   canvasContext: lo_context,
   viewport: lo_viewport
  };

  ao_page.render(lo_renderContext).then(function()
  {
   $('#' + as_imageId)
     .attr("src", lo_canvas.toDataURL());
  });
 });
});

La fonction PDFJS.getDocument() reçoit en paramètre les données, décodées par la fonction JavaScript atob().

Une fois le document chargé, on va demander à récupérer la page dont le numéro est passé en paramètre. Une fois que cela est fait on exécute une fonction pour traiter les données de cette fameuse page. On crée un élément canvas temporaire, qu’on pourra stocker – ou pas – dans la page. On récupère aussi le contexte de dessin de ce canvas.

On récupère le viewport en indiquant l’échelle (ex : 1.5f). On définit ensuite la hauteur et la largeur du canvas avec les valeurs du viewport.

On crée ensuite un objet qui contiendra le contexte de dessin et le viewport. Ceux-ci seront passés à la fonction render() qui est une fonction de l’objet page. Lorsque le rendu est terminé, on peut récupérer la source de l’image depuis le canvas, grâce à la fonction toDataURL() de ce dernier.