News & Updates

How to Convert DOCX to PDF Using Pandoc and Python

By Victoria Shaw 5 min read 4263 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 Senior Journalist with over a decade of experience covering business, public affairs, and community issues. She draws on interviews, original documents, and historical context to explain consequential developments and examine what they mean for the people affected.


You Might Like