Importante
A partir del 31 de mayo de 2024, el servicio se ha reescrito utilizando Kotlin y Spring Boot.
Si desea usar o mirar el código fuente anterior, puede hacerlo revisando la rama nodejs
.
Esta herramienta transforma los documentos de Microsoft Word (DOCX) en formato PDF.
Aunque hay una gran cantidad de herramientas para la conversión de DOCX a PDF, muchos enfrentan desafíos como:
Para complicar aún más las cosas, muchas de estas herramientas exigen entornos específicos y tienen capas de abstracción múltiples, a menudo redundantes.
¿Por qué la conversión precisa de DOCX es tan desafiante? La raíz del problema se encuentra en la especificación DOCX, conocida como OOXML .
Dadas estas complejidades, crear un DocX impecable al convertidor PDF sigue siendo un desafío desalentador, sin una solución a prueba completa a la vista. No en el corto plazo.
LibreOffice, una poderosa suite de oficina de código abierto, se ha esforzado constantemente por mejorar la compatibilidad con los formatos de Microsoft Office, particularmente el formato .docx. Esto es crucial para garantizar que los usuarios que pasen de Microsoft Office a LibreOffice puedan continuar trabajando con sus documentos sin problemas.
Ofrece API incorporadas y un modo de servidor, lo que permite a los usuarios interactuar programáticamente con ella a través de la API de Objetos de Red Universal (UNO).
Si bien no es perfecto, sigue siendo la mejor solución disponible de forma gratuita para representar formatos DOCX.
Este servicio está integrado en Java, utilizando el arranque de Spring, exponiendo una API simple que toma un archivo DOCX como entrada y responde con un archivo application/pdf
.
Logra esto lanzando un servidor LibreOffice en segundo plano durante la inicialización, luego comienza a comunicarse con el servidor a través de las API UNO proporcionadas por OpenOffice (OO) a:
Y luego transmitiendo la respuesta al usuario.
Puede extraer la última imagen de Docker construida de Dockerhub:
docker pull moalhaddar/docx-to-pdf:latest
Entonces puede ejecutar el servicio:
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
Algunos detalles:
pool.size
: en caso de que necesite más trabajadores. Omitir si no es necesario. . Read más en la sección de rendimiento./usr/share/fonts/custom
: en caso de que necesite fuentes personalizadas. Omitir si no es necesario. Lea más en la sección de fuentes. Para ejecutar este servicio localmente, necesitará lo siguiente:
Java 17
Aturdir
$ export PATH= $PATH :/path/to/folder/apache-maven-3.9.4/bin
$ mvn -v
Apache Maven 3.9.4 (dfbb324ad4a7c8fb0bf182e6d91b0ae20e3d2dd9)
LibreOffice, asegúrese de que esté disponible en su sistema a través de la variable $ ruta.
$ libreoffice --version
LibreOffice 7.5.6.2 50(Build:2)
Clonar este repositorio y luego desde el directorio de inicio ejecutar el servicio
$ mvn spring-boot:run
Espere que el servicio se ejecute en el puerto 8080 de forma predeterminada.
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)
Una vez que el servicio está en funcionamiento, puede intentar alcanzar el servicio en el punto final /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 ) ) ;
Los archivos de ejemplo a continuación se incluyen en este repositorio aquí
Se sucederá que use una fuente en el documento DOCX que no se incluye en su sistema. En ese caso, dicha fuente deberá ser incluida por:
/usr/share/fonts/
. Ejemplo $ cp ./fonts/DroidKufi-Bold.ttf /usr/share/fonts/
Entonces necesitará reiniciar el servicio.
Si la fuente no está incluida dentro de la imagen del sistema/Docker, entonces el resultado PDFS no se verá igual que el archivo DOCX original.
Esta herramienta fue diseñada teniendo en cuenta el rendimiento.
La configuración predeterminada ejecuta el servicio con un solo trabajador convertidor. Si tiene suficientes recursos del sistema disponibles y necesita aumentar el tamaño del grupo de trabajadores, puede hacerlo proporcionando el pool.size
variables de entorno.
O puede hacerlo sin comentarse la línea pool.size
. En el archivo Propiedades.
La prueba se realiza a través de un navegador web y JavaScript, checkout index.html y stress.js respectivamente.
He probado este servicio con solicitudes concurrentes con un archivo DOCX de 1 página muy simple (ejemplo 1), aquí están los resultados:
Número de solicitudes concurrentes | Número de trabajadores | Es hora de atender todas las solicitudes |
---|---|---|
50 | 1 | 5.594s |
50 | 4 | 1.880s |
50 | 8 | 1.277s |
50 | 16 | 1.081s |
Tenga en cuenta que la complejidad del archivo de entrada es importante cuando se trata del rendimiento de conversión.
Si tiene alguna observación de rendimiento, no dude en abrir e informar un problema.
Licencia de MIT
Mohammad Alhaddar