News & Updates

How to Convert DOCX to PDF Using Pandoc and Python

By Victoria Shaw 13 min read 4779 views

How to Convert DOCX to PDF Using Pandoc and Python

Turning a Word document into a PDF doesn’t have to involve a mouse click in a GUI. With a few lines of code and Pandoc, you can automate the whole process, whether you’re batch‑processing reports or integrating conversion into a web service.

Why Choose Pandoc with Python?

Pandoc is a powerhouse for document conversion. It understands a wide range of formats—Markdown, LaTeX, DOCX, HTML, and more—so you aren’t limited to a single source type. Pairing it with Python gives you:

  • Programmatic control: loop over folders, rename outputs, log errors.
  • Cross‑platform consistency: the same script works on Windows, macOS, or Linux.
  • Extensibility: hook in custom filters to tweak styling before the PDF is produced.

Getting Started: Install What You Need

1. Install Pandoc

On most systems you can grab the latest release from pandoc.org. On Debian‑based Linux:

sudo apt-get update && sudo apt-get install pandoc

For macOS using Homebrew:

brew install pandoc

2. Install a LaTeX engine

Pandoc renders PDFs via LaTeX, so you’ll need a distribution such as texlive or MiKTeX. A minimal installation is usually enough:

sudo apt-get install texlive-latex-base

3. Set up Python

Make sure you have Python 3.7+ and pip available. Then install the subprocess wrapper (built‑in) and optionally pypandoc if you prefer a higher‑level API:

pip install pypandoc

Simple Conversion with subprocess

If you like keeping things explicit, call Pandoc directly from the shell. Here’s a minimal script that takes an input .docx and writes out a .pdf:

import subprocess

import pathlib

def docx_to_pdf(src_path, dst_path=None):

src = pathlib.Path(src_path)

if not src.is_file() or src.suffix.lower() != '.docx':

raise ValueError('Provide a valid .docx file')

dst = pathlib.Path(dst_path or src.with_suffix('.pdf'))

cmd = [

'pandoc',

str(src),

'-o', str(dst),

'--pdf-engine=xelatex' # use xelatex for better font handling

]

result = subprocess.run(cmd, capture_output=True, text=True)

if result.returncode != 0:

raise RuntimeError(f'Pandoc error: {result.stderr}')

return dst

# Example usage

if __name__ == '__main__':

print(docx_to_pdf('example.docx'))

The script checks the input, builds a command list, and captures any error messages. Using xelatex helps with Unicode fonts, which can be a headache otherwise.

Using pypandoc for a Cleaner API

If you’d rather avoid dealing with subprocess yourself, pypandoc wraps the call and returns the result as a byte string. That makes it easy to write the PDF to a memory buffer or send it over a network.

import pypandoc

import pathlib

def docx_to_pdf_buffer(docx_path):

docx = pathlib.Path(docx_path)

if not docx.is_file():

raise FileNotFoundError(docx_path)

return pypandoc.convert_file(

str(docx),

'pdf',

outputfile=None, # None → return as bytes

extra_args=['--pdf-engine=xelatex']

)

pdf_bytes = docx_to_pdf_buffer('report.docx')

# Save to disk

with open('report.pdf', 'wb') as f:

f.write(pdf_bytes)

This approach shines when you need to embed the PDF in a Flask response or store it directly in a database.

Batch Processing a Folder

Often you’ll have dozens of Word files to convert. A quick loop does the trick:

import os

from pathlib import Path

def batch_convert(folder):

folder = Path(folder)

for docx_file in folder.rglob('*.docx'):

try:

pdf_file = docx_to_pdf(docx_file)

print(f'✔ {docx_file.name} → {pdf_file.name}')

except Exception as e:

print(f'✘ {docx_file.name}: {e}')

batch_convert('my_documents')

Notice the use of rglob, which walks sub‑directories automatically. Errors are caught so the script keeps running even if a single file is problematic.

Troubleshooting Common Hurdles

  • Missing fonts: If the PDF looks blank or reports “Font not found,” install the missing font on your system or point Pandoc to a local .ttf using the --variable=mainfont argument.
  • Unicode characters: Use xelatex or lualatex instead of the default pdflatex. They handle UTF‑8 out of the box.
  • Large tables or images: Add --metadata=geometry:margin=1in to give the layout a bit more breathing room.

Putting It All Together in a Flask Endpoint

For a lightweight web service that accepts a DOCX upload and returns a PDF, combine Flask with the pypandoc function:

from flask import Flask, request, send_file

import io

app = Flask(__name__)

@app.route('/convert', methods=['POST'])

def convert():

uploaded = request.files.get('file')

if not uploaded or not uploaded.filename.endswith('.docx'):

return 'Invalid file', 400

pdf_bytes = pypandoc.convert_text(

uploaded.read(),

'pdf',

format='docx',

extra_args=['--pdf-engine=xelatex']

)

return send_file(

io.BytesIO(pdf_bytes),

mimetype='application/pdf',

as_attachment=True,

download_name=uploaded.filename.rsplit('.', 1)[0] + '.pdf'

)

if __name__ == '__main__':

app.run(debug=True)

This snippet demonstrates the whole pipeline—receive, convert, and stream back—without ever touching the filesystem.

Final Thoughts

Leveraging Pandoc’s robust conversion engine together with Python’s flexibility gives you a reliable, scriptable way to turn DOCX files into polished PDFs. Whether you’re handling a single report or building a conversion microservice, the code snippets above should get you up and running quickly. Happy coding!

Convert Word DOC or DOCX to PDF with Python: A Comprehensive Guide | by ...
How to Convert PDF to Docx in Python - The Python Code
Convert PDF File to Docx in Python | by Nutan | Medium
【2025 最新】Pandoc 使用手册 - Windows 安装与多格式转换指南-CSDN博客

Written by Victoria Shaw

Victoria Shaw is a Chief Correspondent with over a decade of experience covering breaking trends, in-depth analysis, and exclusive insights.