Convert DOCX to PDF in Spring Boot with docx4j: A Lightweight Open‑Source Solution
This article walks through building a pure‑Java DOCX‑to‑PDF converter in Spring Boot using docx4j, compares it with alternatives, shows Maven dependencies, provides a utility class and controller example, and explains how to resolve Chinese font garbling on both Windows and Linux.
1. Solution Comparison
Apache POI + iText : Open source, no external dependencies, medium style fidelity, simple deployment (★), but poor support for complex formats.
docx4j : Open source, no external dependencies, high style fidelity, moderate deployment effort (★★), recommended for pure Java projects.
LibreOffice + JODConverter : Open source, requires LibreOffice installation, very high style fidelity, complex deployment (★★★).
Aspose.Words : Not open source (commercial license), no external dependencies, highest style fidelity, simple deployment (★), but requires a paid license.
2. 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>3. 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.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 mapping to avoid Chinese garbling
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 "宋体(正文)/宋体(标题)" garbling
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());
}
}
}4. 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. Invoke 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();
}
}Send a request with Postman, e.g.:
GET http://localhost:8080/convertToPdf?filePath=E:/ai/report.docx5. Windows: Fix Chinese Garbling
Add the required Chinese fonts to the fontMapper as shown in the utility class.
6. Linux: Fix Chinese Garbling
Install Windows fonts on the Linux host: sudo mkdir -p /usr/share/fonts/win_font Copy the fonts from a Windows 10 installation ( C:\Windows\Fonts) to /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 cacheVerify the fonts are loaded with:
fc-list :lang=zh7. Summary
Use the open‑source library docx4j.
No need to install Office or LibreOffice.
Preserves common styles, images, and tables.
High performance and lightweight deployment.
java1234
Former senior programmer at a Fortune Global 500 company, dedicated to sharing Java expertise. Visit Feng's site: Java Knowledge Sharing, www.java1234.com
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.
