Important
Au 31 mai 2024, le service a été réécrit à l'aide de Kotlin et Spring Boot.
Si vous souhaitez utiliser ou regarder l'ancien code source, vous pouvez le faire en consultant la branche nodejs
.
Cet outil transforme les documents Microsoft Word (DOCX) en format PDF.
Bien qu'il y ait une abondance d'outils pour la conversion DOCX à PDF, beaucoup sont confrontés à des défis tels que:
Pour compliquer davantage les questions, bon nombre de ces outils exigent des environnements spécifiques et ont des couches d'abstraction multiples, souvent redondantes.
Pourquoi la conversion DOCX précise est-elle si difficile? La racine du problème réside dans la spécification DOCX, connue sous le nom d' OOXML .
Compte tenu de ces complexités, la création d'un convertisseur Docx à PDF sans faille reste un défi intimidant, sans solution complète en vue. Pas de sitôt.
LibreOffice, une puissante suite de bureaux open source, s'est toujours efforcé d'améliorer la compatibilité avec les formats Microsoft Office, en particulier le format .docx. Ceci est crucial pour garantir que les utilisateurs passant de Microsoft Office à LibreOffice peuvent continuer à travailler avec leurs documents de manière transparente.
Il propose des API intégrées et un mode serveur, permettant aux utilisateurs d'interfacer programmatiquement avec lui via l'API Universal Network ObjectS (UNO).
Bien qu'il ne soit pas parfait, c'est toujours la meilleure solution disponible gratuitement pour rendre les formats DOCX.
Ce service est construit en Java, en utilisant Spring Boot, exposant une API simple qui prend un fichier DOCX en tant qu'entrée et répond avec un fichier application/pdf
.
Il y parvient en lançant un serveur LibreOffice en arrière-plan pendant l'initialisation, puis commence à communiquer avec le serveur via les API UNO fournies par OpenOffice (OO) à:
Puis diffuser la réponse à l'utilisateur.
Vous pouvez extraire la dernière image Docker construite à partir de DockerHub:
docker pull moalhaddar/docx-to-pdf:latest
Ensuite, vous pouvez exécuter le service:
docker run
--rm --name docx-to-pdf
-p 8080:8080
-e " pool.size=1 "
-v ./fonts:/usr/share/fonts/custom
moalhaddar/docx-to-pdf:latest
Quelques détails:
pool.size
: Si vous auriez besoin de plus de travailleurs. Omettre si ce n'est pas nécessaire. . Lisez plus dans la section des performances./usr/share/fonts/custom
: au cas où vous auriez besoin de polices personnalisées. Omettre si ce n'est pas nécessaire. En savoir plus dans la section des polices. Pour exécuter ce service localement, vous aurez besoin de ce qui suit:
Java 17
Maven
$ export PATH= $PATH :/path/to/folder/apache-maven-3.9.4/bin
$ mvn -v
Apache Maven 3.9.4 (dfbb324ad4a7c8fb0bf182e6d91b0ae20e3d2dd9)
LibreOffice, assurez-vous qu'il est disponible dans votre système via la variable $ Path.
$ libreoffice --version
LibreOffice 7.5.6.2 50(Build:2)
Clone ce référentiel, puis à partir du répertoire domestique, exécutez le service
$ mvn spring-boot:run
Attendez-vous à ce que le service fonctionne sur le port 8080 par défaut.
2023-10-06T22:36:06.922+03:00 INFO 1513874 --- [ main] d.a.d.DocxToPdfKotlinApplicationKt : No active profile set, falling back to 1 default profile: "default"
2023-10-06T22:36:07.414+03:00 INFO 1513874 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-10-06T22:36:07.419+03:00 INFO 1513874 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-10-06T22:36:07.419+03:00 INFO 1513874 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.13]
2023-10-06T22:36:07.463+03:00 INFO 1513874 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-10-06T22:36:07.464+03:00 INFO 1513874 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 513 ms
2023-10-06T22:36:07.554+03:00 INFO 1513874 --- [atcher-worker-1] d.a.docxtopdf.server.LibreOfficeServer : [LibreOffice/0] Starting server instance..
2023-10-06T22:36:07.788+03:00 INFO 1513874 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator'
2023-10-06T22:36:07.813+03:00 INFO 1513874 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-10-06T22:36:07.821+03:00 INFO 1513874 --- [ main] d.a.d.DocxToPdfKotlinApplicationKt : Started DocxToPdfKotlinApplicationKt in 1.071 seconds (process running for 1.22)
Une fois le service opérationnel, vous pouvez essayer de frapper le service au point de terminaison /pdf
.
curl --output output.pdf
--location ' http://localhost:8080/pdf '
--form ' document=@"/home/moalhaddar/example.docx" '
var formdata = new FormData ( ) ;
formdata . append ( "document" , fileInput . files [ 0 ] , "file.docx" ) ;
var requestOptions = {
method : 'POST' ,
body : formdata ,
} ;
fetch ( "http://localhost:8080/pdf" , requestOptions )
. then ( response => response . text ( ) )
. then ( result => console . log ( result ) )
. catch ( error => console . log ( 'error' , error ) ) ;
L'exemple de fichiers ci-dessous est inclus dans ce référentiel ici
Il arrivera que vous utilisiez une police dans le document DOCX qui n'est pas incluse dans votre système. Dans ce cas, ladite police devra être incluse soit par:
/usr/share/fonts/
répertoire. Exemple $ cp ./fonts/DroidKufi-Bold.ttf /usr/share/fonts/
Ensuite, vous devrez redémarrer le service.
Si la police n'est pas incluse dans l'image système / docker, le résultat PDFS ne ressemblera pas au fichier DOCX d'origine.
Cet outil a été conçu avec des performances à l'esprit.
Les paramètres par défaut exécutent le service avec un seul travailleur de convertisseur. Si vous disposez de suffisamment de ressources système et devez augmenter la taille du pool de travailleurs, vous pouvez le faire en fournissant le pool.size
de variables d'environnement.
Ou vous pouvez le faire en décomisant la ligne pool.size
dans le fichier Properties.
Le test se fait via un navigateur Web et JavaScript, Checkout Index.html & Stress.js respectivement.
J'ai testé ce service avec des demandes simultanées avec un fichier DOCX très simple d'une page (exemple 1), voici les résultats:
Nombre de demandes simultanées | Nombre de travailleurs | Il est temps de servir toutes les demandes |
---|---|---|
50 | 1 | 5.594S |
50 | 4 | 1,880 |
50 | 8 | 1.277 |
50 | 16 | 1.081 |
Gardez à l'esprit que la complexité du fichier d'entrée importe beaucoup en ce qui concerne les performances de conversion.
Si vous avez des observations de performance, n'hésitez pas à ouvrir et à signaler un problème.
Licence MIT
Mohammad Alhaddar