
Salut, Habr.
Je veux parler d'un utilitaire appelé DocumentBuilder, qui vous permet de générer des documents, des tableaux et des présentations, et aussi de montrer comment vous pouvez l'utiliser pour résoudre vos problèmes, en utilisant l'exemple de création de CV à partir de modèles.
Le générateur fonctionne comme suit: vous écrivez du code en js en utilisant des méthodes spéciales de la documentation, le donnez à l'utilitaire et il recueille le document. Ou ne collecte pas s'il y a des erreurs.
L'utilisation d'un générateur est recommandée si vous souhaitez résoudre des tâches du type suivant:
- Vous devez faire beaucoup de documents avec de petites variations ou des documents basés sur beaucoup de données.
- Vous devez intégrer la génération de documents dans n'importe quel service.
Il existe des services qui vous permettent de créer un CV: l'utilisateur remplit les champs nécessaires, et le système génère un document et le remet à l'utilisateur. Ce sera un exemple de la façon d'utiliser le générateur.
Comme outils, j'utiliserai Node.js (express).
Plan:
- L'utilisateur entre des données dans le formulaire sur la page du navigateur, le formulaire est envoyé au serveur.
- Sur le serveur Node.js, il crée un script pour le générateur basé sur les données utilisateur.
- Node.js donne le script au générateur.
- Le constructeur crée un document à l'aide d'un script.
- Node.js renvoie le lien vers le document Ă l'utilisateur.
Créez d'abord un formulaire dans lequel l'utilisateur entrera ses données. Le formulaire aura 8 champs: "Nom complet", "Numéro de téléphone", "email", "profil", "diplôme", "université", "lieu", "année", "compétence". Le domaine de compétence peut être cloné.
Créez un fichier index.html et ajoutez-y le code du modèle.
<div class="fill-name"> <input type="text" id="fill-name" placeholder="full name"> </div> <div class="phone-number"> <input type="number" id="phone-number" placeholder="phone number"> </div> <div class="email"> <input type="text" id="email" placeholder="email"> </div> <div class="profile"> <textarea id="profile" placeholder="Insert a brief description of yourself"></textarea> </div> <div class="education"> <input type="text" id="degree" placeholder="degree"> <input type="text" id="university" placeholder="university"> <input type="text" id="location" placeholder="location"> <input type="date" id="year" placeholder="year"> </div> <div class="skills"> <div class="skill"> <input type="text" id="new-skill" placeholder="skill" onkeyup="add_skill_by_enter(event)"> <button onclick="add_skill()">+</button> </div> </div>
Ici, j'utilise deux fonctions: add_skill_by_enter (event) et add_skill (). Ils sont nécessaires pour ajouter plusieurs champs en appuyant sur le bouton + ou Entrée. Je décrirai ces fonctions un peu plus tard.
Ajoutez un bouton pour soumettre le formulaire au serveur:
<button onclick="sendForm()">Send</button>
Nous allons maintenant écrire des fonctions pour travailler avec le formulaire.
La première fonction est add_skill ()
add_skill = () => { const newSkill = document.getElementById("new-skill"); if (newSkill.value === '') {return; }
Nous ajoutons une fonction simple pour collecter les données des champs et les envoyer au serveur.
get_skill_values = () => { const skills = []; if (document.getElementById('new-skill').value !== '') { skills.push(document.getElementById('new-skill').value); } Array.from(document.getElementsByClassName('skillfield')).forEach(current_element => { skills.push(current_element.innerHTML); }); return skills; }; sendForm() sendForm = () => { fetch('/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userData: { fillName: document.getElementById('fill-name').value, phoneNumber: document.getElementById('phone-number').value, email: document.getElementById('email').value, profile: document.getElementById('profile').value, education: { degree: document.getElementById('degree').value, university: document.getElementById('university').value, location: document.getElementById('location').value, year: document.getElementById('year').value, }, skills: get_skill_values() } }) }).then(res => res.json()) .then(response => { location.replace('/' + response.filename);
J'écris la partie serveur sur express. La connexion de toutes les bibliothèques, la configuration du serveur et la description des méthodes get et post ressemblent à ceci:
const path = require('path'); const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.get('/', (req, res) => { res.sendFile(path.join(__dirname + '/index.html')); }); app.post('/', (req, res) => {
Exécutez express:
node main.js
Ouvrez l'adresse dans le navigateur:
http:localhost:3000
Nous voyons le formulaire créé. Nous le remplissons de données arbitraires:

Nous obtenons le json suivant:
{"userData":{"fillName":"Rotatyy Dmitryi","phoneNumber":"89879879898","email":"flamine@list.ru","profile":"Hi, my name is Joe\nAnd I work in a button factory\nI got a wife and two kids\nOne day, my boss says, “Joe, are you busy?”\nI said, “no”\n“Then push this button with your right hand”","country":"Russia","city":"Nizhniy Novgorod","education":{"degree":"Master of Pupets","university":"Nizhny novgorod state technical university","location":"Nizhniy Novgorod","year":"2015-05-02"},"skills":["apple.js","vintage.js","zerg.js","css","html","linux"]}};
Vous devez maintenant écrire un script pour le constructeur. J'ai pris comme base le modèle proposé par Google Docs (modèle de CV).
Ce modèle ressemble à ceci:

À l'aide de ces données et du modèle, vous devez créer un script avec lequel le constructeur créera le document.
Il existe plusieurs options pour ce faire, et la plus simple consiste à télécharger la version de bureau des éditeurs ONLYOFFICE et à écrire une macro qui créera le document en utilisant les données. Et puis ajoutez à la macro la création et l'enregistrement du fichier - vous obtenez un script pour le constructeur. Cela fonctionnera car les macros et le générateur utilisent la même API.

Création d'un script pour un constructeur
Nous commençons par initialiser l'objet page et ajouter les données provenant de l'utilisateur:
const Document = Api.GetDocument(); const data = {"userData":{"fillName":"Rotatyy Dmitryi","phoneNumber":"89879879898","email":"flamine@list.ru","profile":"Hi, my name is Joe\nAnd I work in a button factory\nI got a wife and two kids\nOne day, my boss says, “Joe, are you busy?”\nI said, “no”\n“Then push this button with your right hand”","country":"Russia","city":"Nizhniy Novgorod","education":{"degree":"Master of Pupets","university":"Nizhny novgorod state technical university","location":"Nizhniy Novgorod","year":"2015-05-02"},"skills":["apple.js","vintage.js","zerg.js","css","html","linux"]}};
Vous devez maintenant ajouter le paragraphe avec le nom d'utilisateur complet. Il est écrit en gras et ce paragraphe a un interligne de 1,15.
let paragraph = document.GetElement(0);
Nous ajoutons également les paragraphes restants: En exécutant ce script, nous obtenons le document suivant:

Il est maintenant temps d'ajouter des fonctionnalités pour écrire du code de script dans un fichier et générer un document.
Nous générons le script -> écrire dans le fichier -> donner le fichier au constructeur -> renvoyer le lien vers le fichier à l'utilisateur.
Nous ajoutons une connexion de modules complémentaires pour travailler avec des fichiers et exécuter des commandes à l'aide de Node.js, et également créer un dossier «public» et le rendre public:
const {exec} = require('child_process'); const fs = require('fs'); app.use(express.static('public'));
La fonction pour générer du texte avec un script sera très simple - elle retournera simplement une chaîne avec tout le code pour le générateur, tout en ajoutant des données utilisateur. Il est important d'ajouter un caractère de saut de ligne à la fin de chaque ligne, sinon rien ne fonctionnera.
generate_script = (data) => { let first_template = 'builder.CreateFile("docx");\n' + 'const Document = Api.GetDocument();\n'; first_template += 'const data = ' + JSON.stringify(data) + ';\n'; first_template += 'let paragraph = Document.GetElement(0);\n' + 'FullName_style = Document.CreateStyle("FullName");\n' + .... ~~~~~~~~~~~ return first_template; };
Vous devez maintenant écrire le script dans un fichier et le donner au générateur. En fait, tout travail avec le générateur sera réduit au fait que nous devons exécuter la commande documentbuilder path/script.js Node.js
du documentbuilder path/script.js Node.js
Nous écrivons une fonction de construction qui fera cela:
build = (data, res) => { const filename = Math.random().toString(36).substring(7) + '.docx';
Ajoutez un appel à la méthode de construction (req.body, res); quand post demande
app.post('/', (req, res) => { build(req.body, res); });
Et vous avez terminé. Juste au cas où, j'ai publié l'exemple de code complet ici .
Vous pouvez donc intégrer ONLYOFFICE DocumentBuilder dans une application Web.
J'espère que malgré un grand nombre de simplifications, tout est clair. J'ai utilisé uniquement le code minimum nécessaire pour montrer comment tout fonctionne.
En ce moment, il y a des réflexions pour terminer l'utilitaire et élargir la gamme des problèmes à résoudre. Je vous serais reconnaissant de partager les cas réels de génération de documents (enfin, de tableaux avec présentations, bien sûr, aussi) dans les commentaires ou dans PM.