How to Convert DOCX to PDF in Spring Boot Using docx4j (Open‑Source Solution)
The article explains how to implement a pure‑Java DOCX‑to‑PDF conversion service in Spring Boot with docx4j, compares it against alternatives such as Apache POI+iText, LibreOffice+JODConverter and Aspose.Words, and provides step‑by‑step code for Maven dependencies, a utility class with font mapping to avoid Chinese garbling, a controller endpoint, and platform‑specific font‑installation fixes for Windows and Linux.
Solution Comparison
Apache POI + iText – open source, no external dependency, medium style fidelity, low deployment complexity, poor support for complex formats.
docx4j – open source, no external dependency, high style fidelity, moderate deployment complexity, recommended because it is pure Java.
LibreOffice + JODConverter – open source, requires LibreOffice installation, very high fidelity, high deployment complexity.
Aspose.Words – commercial, no external dependency, highest fidelity, low deployment complexity.
docx4j is selected for its pure‑Java implementation, no Office installation required, Apache‑2.0 license and good preservation of images, tables, headers and footers.
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>Core 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.*;
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 mapping to avoid Chinese garble
Mapper fontMapper = new IdentityPlusMapper();
PhysicalFonts.discoverPhysicalFonts();
PhysicalFont simsun = PhysicalFonts.get("SimSun");
if (simsun != null) {
fontMapper.put("SimSun", simsun);
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 "宋体(正文)/宋体(标题)" garble
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 生成成功:" + pdfPath);
} catch (Exception e) {
System.err.println("❌ 转换失败:" + e.getMessage());
}
}
}Controller Example
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
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("文件不存在: " + filePath);
}
// 2. Define temporary PDF path
String pdfPath = filePath.replace(".docx", ".pdf");
// 3. Invoke conversion utility
DocxToPdfUtil.convert(filePath, pdfPath);
// 4. Set response headers and stream PDF
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
new File(pdfPath).delete();
}
}Windows Chinese‑Garble Fix
Configure the font mapper with common Chinese fonts (SimSun, LiSu, KaiTi, etc.) as shown in the utility class. This prevents garbled characters when the source DOCX contains Chinese text.
Linux Font Installation
Create a directory for Windows fonts: sudo mkdir -p /usr/share/fonts/win_font Copy the Windows C:\Windows\Fonts files into the directory.
Generate font indexes and refresh the cache:
cd /usr/share/fonts/win_font
sudo mkfontscale # generate font scaling file
sudo mkfontdir # generate font directory index
sudo fc-cache -fv # refresh font cacheVerify the installation:
fc-list :lang=zhSummary
Use the open‑source library docx4j.
No need to install Office or LibreOffice.
Preserves common styles, images, and tables.
High performance and lightweight deployment.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
