Convert Word (.docx) to PDF in Spring Boot with docx4j – A Complete Guide

Learn how to convert user‑uploaded .docx files to PDF in a Spring Boot application using the pure‑Java docx4j library, covering solution comparison, Maven dependencies, utility class implementation, controller endpoint, and handling Chinese font issues on Windows and Linux.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Convert Word (.docx) to PDF in Spring Boot with docx4j – A Complete Guide

Background

In many projects users need to upload Word (.docx) files and obtain PDF versions for download, archiving, or online preview.

Solution Comparison

Apache POI + iText – open source, no external dependencies, medium style fidelity, low deployment complexity, poor support for complex formats.

docx4j – open source, no external dependencies, high style fidelity, moderate deployment complexity, recommended for pure Java projects.

LibreOffice + JODConverter – open source, requires LibreOffice installation, very high style fidelity, high deployment complexity.

Aspose.Words – commercial, no external dependencies, highest style fidelity, low deployment complexity but requires a paid license.

Why Choose docx4j

Pure Java implementation, no need to install Office or LibreOffice.

Apache 2.0 license, free for commercial use.

Good conversion quality, retains images, tables, headers and footers.

Easy to integrate into Spring Boot.

Add Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-core</artifactId>
        <version>11.4.8</version>
    </dependency>

    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
        <version>11.4.8</version>
    </dependency>

    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-export-fo</artifactId>
        <version>11.4.8</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.0.9</version>
    </dependency>
</dependencies>

Utility Class: DocxToPdfUtil

package com.donglin.utils;

import org.docx4j.Docx4J;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

import java.io.File;
import java.io.FileOutputStream;

public class DocxToPdfUtil {

    /**
     * Convert a docx file to PDF.
     * @param docxPath input file path
     * @param pdfPath  output file path
     */
    public static void convert(String docxPath, String pdfPath) {
        try {
            // 1. Load the Word document
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(docxPath));

            // 2. Configure font mapper to avoid Chinese garbled text
            Mapper fontMapper = new IdentityPlusMapper();
            PhysicalFonts.discoverPhysicalFonts();
            PhysicalFont simsun = PhysicalFonts.get("SimSun");
            if (simsun != null) {
                fontMapper.put("SimSun", simsun);
                // Common Chinese font mappings
                fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
                fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
                fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft YaHei"));
                fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
                fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
                fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
                fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
                fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
                fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
                fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
                fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
                fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
                fontMapper.put("等线", PhysicalFonts.get("SimSun"));
                fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
                fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
                fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
                fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
                fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
                fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
                fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
                fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
                fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
                fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
                fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
                // Fix "SimSun" garbled text for certain styles
                PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
                PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
                wordMLPackage.setFontMapper(fontMapper);
            }

            // 3. Create output stream and perform conversion
            try (FileOutputStream os = new FileOutputStream(pdfPath)) {
                Docx4J.toPDF(wordMLPackage, os);
            }

            System.out.println("✅ PDF generated successfully: " + pdfPath);
        } catch (Exception e) {
            System.err.println("❌ Conversion failed: " + e.getMessage());
        }
    }
}

Controller Example

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/convert")
public class FileController {

    @GetMapping("/convertToPdf")
    public void convertToPdf(@RequestParam String filePath, HttpServletResponse response) throws Exception {
        // 1. Verify file existence
        File inputFile = new File(filePath);
        if (!inputFile.exists()) {
            throw new RuntimeException("File not found: " + filePath);
        }

        // 2. Define temporary PDF output path
        String pdfPath = filePath.replace(".docx", ".pdf");

        // 3. Call conversion utility
        DocxToPdfUtil.convert(filePath, pdfPath);

        // 4. Set response headers and stream PDF back to client
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=" + new File(pdfPath).getName());
        try (FileInputStream fis = new FileInputStream(pdfPath);
             OutputStream os = response.getOutputStream()) {
            fis.transferTo(os);
            os.flush();
        }

        // Optional: delete temporary PDF file
        new File(pdfPath).delete();
    }
}

Testing with Postman

Send a GET request such as:

GET http://localhost:8080/convertToPdf?filePath=E:/ai/report.docx

Upload a .docx file and the service returns a PDF with the same name.

Fixing Chinese Font Issues on Windows

The utility class configures a comprehensive font mapper that maps many Chinese fonts (SimSun, LiSu, KaiTi, etc.) to avoid garbled characters when converting on Windows.

Fixing Chinese Font Issues on Linux

Install Windows fonts on the Linux server and refresh the font cache:

sudo mkdir -p /usr/share/fonts/win_font
cd /usr/share/fonts/win_font
sudo mkfontscale    # generate font scale file
sudo mkfontdir      # generate font directory index
sudo fc-cache -fv  # refresh font cache

Verify the installation with:

fc-list :lang=zh

Conclusion

Use the open‑source docx4j library.

No need to install Office or LibreOffice.

Preserves common styles, images, and tables.

High performance and lightweight deployment.

JavaSpring BootPDF conversiondocx to pdfdocx4jfont mapping
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.