# Converting Office Open XML (DOCX) to PDF in Java

> Learn how to convert Office Open XML (DOCX) documents to PDF in Java using the powerful ServerTextControl library. This guide provides step-by-step instructions and code examples to help you achieve seamless document conversion in your Java applications.

- **Author:** Bjoern Meyer
- **Published:** 2025-10-14
- **Modified:** 2025-11-29
- **Updated:** 2025-11-19
- **Description:** Learn how to convert Office Open XML (DOCX) documents to PDF in Java using the powerful ServerTextControl library. This guide provides step-by-step instructions and code examples to help you achieve seamless document conversion in your Java applications.
- **6 min read** (1100 words)
- **Tags:**
  - ASP.NET
  - ASP.NET Core
  - PDF
  - Java
- **Web URL:** https://www.textcontrol.com/blog/2025/10/14/converting-office-open-xml-docx-to-pdf-in-java/
- **LLMs URL:** https://www.textcontrol.com/blog/2025/10/14/converting-office-open-xml-docx-to-pdf-in-java/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2025/10/14/converting-office-open-xml-docx-to-pdf-in-java/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/TXTextControl.Core.Java.Convert

---

In many software architectures, developers combine different technologies to create the most effective solutions for specific tasks. A common example is using the power of .NET libraries, such as TX Text Control, inside Java-based systems.

In this article, we'll show you how to integrate a .NET console application for DOCX-to-PDF conversion into a Java application, all inside a neat, tidy Docker container. The result is a portable, cross-platform setup that allows you to access TX Text Control's conversion engine from Java with no platform friction.

### Using TX Text Control in Java Applications

Our goal is simple. We want to build a small .NET console application that uses TX Text Control to convert a DOCX file to a PDF and expose it as a base64-streaming command-line tool. Then, we wrap that tool in a Java application that:

- Accepts a DOCX file as input
- Calls the .NET console application to perform the conversion
- Receives the base64-encoded PDF stream and decodes it
- Saves the resulting PDF file to disk

The two worlds of .NET and Java communicate through standard input/output (stdin/stdout). There is no native interop, JNI, or complex APIs, just simple process streaming.

### Architecture Overview

Here's a high-level overview of the architecture:

![High-level architecture](https://s1-www.textcontrol.com/assets/dist/blog/2025/10/14/a/assets/architecture.webp "High-level architecture")

Everything runs seamlessly inside a single Docker container. This includes the Java 21 (headless) runtime, the .NET 8 runtime, and all TX Text Control dependencies. No additional UI or font libraries are necessary.

### The .NET Converter

The .NET tool, DocxToPdfStdout.dll, is a minimal console application. It reads Base64 DOCX input from stdin, a file, or a command-line argument, converts it to PDF, and writes the Base64 output to stdout. The .NET converter is a lightweight, command-line interface designed for fully automated document conversion. It receives a DOCX document as Base64 input, loads and processes the file in memory using TX Text Control's powerful document rendering engine, and exports a PDF as Base64 output — all without a user interface, fonts, or GDI dependencies.

At its core, the tool creates a headless ServerTextControl instance.

```
using var tx = new TXTextControl.ServerTextControl();
tx.Create();
tx.Load(docxBytes, TXTextControl.BinaryStreamType.WordprocessingML);
tx.Save(out bytes, TXTextControl.BinaryStreamType.AdobePDF);
```

This short sequence performs a high-fidelity conversion from WordprocessingML to Adobe PDF, preserving layout, styles, and embedded elements. The rest of the tool handles Base64 input and output, making it scriptable and language-agnostic. This allows it to be easily called from Java, Python, Node.js, or any other runtime through standard input and output streams.

### The Java Wrapper

The process reads a DOCX file and encodes it in Base64 format into a temporary file. Then, it launches the .NET converter using dotnet /app/tool/DocxToPdfStdout/DocxToPdfStdout.dll temp.b64. The converter writes the resulting PDF as a Base64 stream to standard output. This stream is then decoded and saved as a PDF file. This approach enables Java to perform the conversion without requiring knowledge of .NET internals. Of course, all of this could also be done in memory, but this is a simple example.

This integration hinges on how Java launches the .NET-based converter and processes its output. After the DOCX file is Base64-encoded into a temporary .b64 file, Java starts the .NET console tool as an external process using `ProcessBuilder.`

```
ProcessBuilder pb = new ProcessBuilder("dotnet", DLL_PATH, tempB64.toString());
pb.redirectErrorStream(false);
Process proc = pb.start();
```

This line executes the equivalent of:

```
dotnet /app/tool/DocxToPdfStdout/DocxToPdfStdout.dll /tmp/docx2pdf-1234.b64
```

Inside the converter, TX Text Control reads the Base64-encoded DOCX file, loads it into a headless `ServerTextControl`, and writes a Base64-encoded PDF stream to the standard output (stdout). This design makes the converter stateless and language-agnostic, so any runtime can feed input and read the result via standard I/O.

Back in Java, the converter's stdout stream is read and decoded in real time:

```
try (
    InputStream toolStdout = new BufferedInputStream(proc.getInputStream());
    InputStream decodedPdf = Base64.getMimeDecoder().wrap(toolStdout);
    OutputStream pdfOut = new BufferedOutputStream(
        Files.newOutputStream(outputPdf, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING))
) {
    decodedPdf.transferTo(pdfOut);
}
```

Here's what happens step by step:

1. proc.getInputStream() connects directly to the .NET app’s stdout (its Base64 output).
2. Base64.getMimeDecoder().wrap(...) wraps that stream so every Base64 chunk is decoded on the fly.
3. transferTo(pdfOut) continuously writes the decoded PDF bytes to the final file.

The full PDF is not stored in memory during the process; the data flows seamlessly from the .NET process to the Java output stream. This streaming approach is extremely efficient and scalable, even for large documents.

### Docker Container

The entire setup is encapsulated in a Docker container to ensure that all dependencies are included and that the environment remains consistent across different systems. The Dockerfile installs the necessary runtimes, copies the .NET tool and Java application, and establishes the entry point for execution.

The final Docker image contains:

- The .NET 8 Runtime
- OpenJDK 21 headless
- The compiled Java JAR
- The published .NET DLLs

Here's the short version of the Dockerfile:

```
FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy

RUN apt-get update && apt-get install -y --no-install-recommends \
      openjdk-21-jre-headless && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=build /src/target/*-jar-with-dependencies.jar /app/app.jar
COPY publish/linux-x64/ /app/tool/
COPY data /data
VOLUME ["/out"]

ENTRYPOINT ["java","-jar","/app/app.jar"]
CMD ["/data/input.docx","/out/output.pdf"]
```

### Running the Container

To run the container, use the following command, replacing the paths with your actual file locations:

```
docker build --no-cache -t docx2pdf-java:runtime .
docker run --rm -v "${PWD}\data\out:/out" docx2pdf-java:runtime
```

You can map your own input and output files:

```
docker run --rm -v "${PWD}:/work" -w /work docx2pdf-java:runtime \
  ./my.docx ./out/my.pdf
```

This command mounts the input DOCX file and specifies the location of the resulting PDF file. The container then handles the conversion process and saves the resulting PDF to your specified location.

### Conclusion

This approach shows how to combine the strengths of different technologies into one cohesive application. Using TX Text Control's robust document conversion capabilities in a .NET console application and wrapping it in a Java application achieves seamless DOCX-to-PDF conversion in a cross-platform environment. Using Docker ensures the entire setup is portable and easy to deploy, making it an ideal solution for various use cases. For C# developers, explore similar conversion capabilities and selection criteria in this [C# PDF library selection guide.](https://www.textcontrol.com/blog/2025/11/12/how-to-choose-the-right-csharp-pdf-generation-library-developer-checklist/llms-full.txt)

Get started with your own document conversion tasks by downloading the project from our GitHub repository below.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [C# Document Generation: A Developer's Guide for .NET](https://www.textcontrol.com/blog/2026/07/08/csharp-document-generation-developer-guide-for-dotnet/llms.txt)
- [Validating PDF/UA Documents in .NET C#: A Practical Guide](https://www.textcontrol.com/blog/2026/07/06/validating-pdf-ua-documents-in-dotnet-csharp/llms.txt)
- [Using QR Codes in PDF Documents in C# .NET](https://www.textcontrol.com/blog/2026/04/21/using-qr-codes-in-pdf-documents-in-csharp-dotnet/llms.txt)
- [Why Structured E-Invoices Still Need Tamper Protection using C# and .NET](https://www.textcontrol.com/blog/2026/03/24/why-structured-e-invoices-still-need-tamper-protection-using-csharp-and-dotnet/llms.txt)
- [Create Fillable PDFs from HTML Forms in C# ASP.NET Core Using a WYSIWYG Template](https://www.textcontrol.com/blog/2026/03/17/create-fillable-pdfs-from-html-forms-in-csharp-aspnet-core-using-a-wysiwyg-template/llms.txt)
- [Why HTML to PDF Conversion is Often the Wrong Choice for Business Documents in C# .NET](https://www.textcontrol.com/blog/2026/03/13/why-html-to-pdf-conversion-is-often-the-wrong-choice-for-business-documents-in-csharp-dot-net/llms.txt)
- [A Complete Guide to Converting Markdown to PDF in .NET C#](https://www.textcontrol.com/blog/2026/01/07/a-complete-guide-to-converting-markdown-to-pdf-in-dotnet-csharp/llms.txt)
- [Why PDF Creation Belongs at the End of the Business Process](https://www.textcontrol.com/blog/2026/01/02/why-pdf-creation-belongs-at-the-end-of-the-business-process/llms.txt)
- [Designing the Perfect PDF Form with TX Text Control in .NET C#](https://www.textcontrol.com/blog/2025/12/16/designing-the-perfect-pdf-form-with-tx-text-control-in-dotnet-csharp/llms.txt)
- [Why Defining MIME Types for PDF/A Attachments Is Essential](https://www.textcontrol.com/blog/2025/12/10/why-defining-mime-types-for-pdfa-attachments-is-essential/llms.txt)
- [Validate Digital Signatures and the Integrity of PDF Documents in C# .NET](https://www.textcontrol.com/blog/2025/11/14/validate-digital-signatures-and-the-integrity-of-pdf-documents-in-csharp-dotnet/llms.txt)
- [Validate PDF/UA Documents and Verify Electronic Signatures in C# .NET](https://www.textcontrol.com/blog/2025/11/13/validate-pdf-ua-documents-and-verify-electronic-signatures-in-csharp-dotnet/llms.txt)
- [How To Choose the Right C# PDF Generation Library: Developer Checklist](https://www.textcontrol.com/blog/2025/11/12/how-to-choose-the-right-csharp-pdf-generation-library-developer-checklist/llms.txt)
- [Why Digitally Signing your PDFs is the Only Reliable Way to Prevent Tampering](https://www.textcontrol.com/blog/2025/10/30/why-digitally-signing-your-pdfs-is-the-only-reliable-way-to-prevent-tampering/llms.txt)
- [Automating PDF/UA Accessibility with AI: Describing DOCX Documents Using TX Text Control and LLMs](https://www.textcontrol.com/blog/2025/10/16/automating-pdf-ua-accessibility-with-ai-describing-docx-documents-using-tx-text-control-and-llms/llms.txt)
- [Extending DS Server with Custom Digital Signature APIs](https://www.textcontrol.com/blog/2025/10/09/extending-ds-server-with-custom-digital-signature-apis/llms.txt)
- [Why PDF/UA and PDF/A-3a Matter: Accessibility, Archiving, and Legal Compliance](https://www.textcontrol.com/blog/2025/10/07/why-pdf-ua-and-pdf-a-3a-matter-accessibility-archiving-and-legal-compliance/llms.txt)
- [Convert Markdown to PDF in a Console Application on Linux and Windows](https://www.textcontrol.com/blog/2025/09/23/convert-markdown-to-pdf-in-a-console-application-on-linux-and-windows/llms.txt)
- [Mining PDFs with Regex in C#: Practical Patterns, Tips, and Ideas](https://www.textcontrol.com/blog/2025/08/12/mining-pdfs-with-regex-in-csharp-practical-patterns-tips-and-ideas/llms.txt)
- [Streamline Data Collection with Embedded Forms in C# .NET](https://www.textcontrol.com/blog/2025/08/02/streamline-data-collection-with-embedded-forms-in-csharp-dotnet/llms.txt)
- [Adding QR Codes to PDF Documents in C# .NET](https://www.textcontrol.com/blog/2025/07/15/adding-qr-codes-to-pdf-documents-in-csharp-dotnet/llms.txt)
- [Adding SVG Graphics to PDF Documents in C# .NET](https://www.textcontrol.com/blog/2025/07/08/adding-svg-graphics-to-pdf-documents-in-csharp-dotnet/llms.txt)
- [Enhancing PDF Searchability in Large Repositories by Adding and Reading Keywords Using C# .NET](https://www.textcontrol.com/blog/2025/06/24/enhancing-pdf-searchability-in-large-repositories-by-adding-and-reading-keywords-using-csharp-dotnet/llms.txt)
- [How to Verify PDF Encryption Programmatically in C# .NET](https://www.textcontrol.com/blog/2025/06/20/how-to-verify-pdf-encryption-programmatically-in-csharp-dotnet/llms.txt)
- [PDF Security for C# Developers: Encryption and Permissions in .NET](https://www.textcontrol.com/blog/2025/06/16/pdf-security-for-csharp-developers-encryption-and-permissions-in-dotnet/llms.txt)
