Knowledgebase (2613)
Children categories

Downloading PDF files from URLs programmatically is essential for developers building document processing systems, web scrapers, content aggregators, or automated report generators. Automating PDF download and processing improves workflow efficiency, allowing developers to extract information, archive documents, or perform analysis without manual intervention.
In this guide, we demonstrate how to download PDFs from URLs using Python with Spire.PDF, process them entirely in memory, handle network errors, manage large files, and troubleshoot common issues.
Quick Navigation:
- Why Use Spire.PDF for Python
- Install Required Libraries
- Download PDF from URL
- Processing PDFs Without Saving
- Handling Large PDFs
- Adding Retry Logic
- Common Issues and Troubleshooting
- Conclusion
- FAQs
1. Why Use Spire.PDF for Python
Spire.PDF for Python enables loading PDFs directly from memory, without needing a disk path. This makes in-memory processing fast and avoids unnecessary disk I/O.
Key capabilities include:
- Load PDFs from bytes or Stream objects
- Extract text, images, and metadata
- Modify PDFs and convert to other formats
- Efficiently handle large files in memory
These capabilities are particularly useful in web scraping pipelines, document archiving systems, automated report generation, and content extraction workflows, where performance and memory efficiency are important.
2. Install Required Libraries
Install Spire.PDF and requests via pip:
pip install spire.pdf requests
Import the necessary modules:
from spire.pdf import *
import requests
3. Download PDF from URL
Here’s a complete example showing how to download a PDF from a URL, process it in memory, and save it to disk. Each line includes explanations for clarity.
import requests
from spire.pdf import *
def download_pdf_from_url():
# Specify the PDF URL
url = "resource/sample.pdf"
# Send HTTP GET request to download the PDF
response = requests.get(url)
# Raise an error if the request failed (4xx or 5xx)
response.raise_for_status()
# Create a Stream object from the downloaded bytes
stream = Stream(response.content)
# Load PDF from Stream
document = PdfDocument(stream)
# Save PDF to local file
document.SaveToFile("Downloaded.pdf")
document.Close()
print("PDF downloaded and saved successfully!")
if __name__ == "__main__":
download_pdf_from_url()
Output:

Explanation of key components:
requests.get(url)– Sends the HTTP GET request. The server responds with headers and the PDF binary.response.raise_for_status()– Checks for HTTP errors (e.g., 404, 500).response.content– Contains raw PDF bytes.Stream(response.content)– Wraps bytes in a readable, seekable in-memory stream.PdfDocument(stream)– Loads the PDF into memory for further operations.document.SaveToFile()– writes the PDF to disk.
This workflow loads PDF data into memory for instant saving, improving speed and avoiding unnecessary disk writes.
4. Processing PDFs Without Saving
You can extract metadata or text directly in memory without writing files:
def process_pdf_from_url():
url = "resource/sample.pdf"
response = requests.get(url)
response.raise_for_status()
# Load PDF in memory
document = PdfDocument(Stream(response.content))
# Retrieve document information
print(f"Number of pages: {document.Pages.Count}")
info = document.DocumentInformation
print(f"Title: {info.Title}")
print(f"Author: {info.Author}")
# Extract text from the first page
from spire.pdf import PdfTextExtractor
extractor = PdfTextExtractor(document.Pages[0])
text = extractor.ExtractText()
print(f"First 100 characters: {text[:100]}")
document.Close()
if __name__ == "__main__":
process_pdf_from_url()
Why this is useful: You can analyze content, index text, or extract metadata without creating unnecessary files on disk. This is ideal for server-side scripts, cloud functions, or batch processing.
5. Handling Large PDFs
Downloading very large PDFs (e.g., 100MB+) can consume significant memory. Use streaming download and temporary files to reduce memory usage:
import tempfile
import os
def download_large_pdf(url: str, output_path: str):
try:
response = requests.get(url, stream=True, timeout=60)
response.raise_for_status()
# Write chunks to a temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
tmp.write(chunk)
temp_path = tmp.name
# Load PDF from temporary file
document = PdfDocument()
document.LoadFromFile(temp_path)
document.SaveToFile(output_path)
document.Close()
# Clean up temporary file
os.unlink(temp_path)
print(f"Large PDF saved to: {output_path}")
except Exception as e:
print(f"Error: {e}")
Notes:
stream=Trueavoids loading the entire file into memory.- Temporary files allow processing PDFs that exceed available RAM.
6. Adding Retry Logic
Network requests may fail intermittently. Adding retries improves robustness:
import time
def download_with_retry(url: str, output_path: str, max_retries: int = 3):
for attempt in range(max_retries):
try:
response = requests.get(url, timeout=30)
response.raise_for_status()
document = PdfDocument(Stream(response.content))
document.SaveToFile(output_path)
document.Close()
print(f"Downloaded successfully: {output_path}")
return True
except requests.exceptions.RequestException as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Retrying in {wait_time} seconds...")
time.sleep(wait_time)
print("All retry attempts failed.")
return False
Why use this: Exponential backoff prevents overwhelming servers and handles transient network failures gracefully.
7. Common Issues and Troubleshooting
PDF Not Found (404)
Problem: The URL does not point to a valid PDF, resulting in a 404 error.
Solution: Verify the URL and add a User-Agent header if needed:
import requests
url = "https://example.com/missing.pdf"
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)
if response.status_code == 404:
print("PDF not found (404)")
Server Returns HTML Instead of PDF
Problem: The URL returns an HTML page instead of a PDF.
Solution: Check the Content-Type and parse HTML to locate the actual PDF:
import requests
from bs4 import BeautifulSoup
url = "https://example.com/download-page"
response = requests.get(url)
content_type = response.headers.get('Content-Type', '')
if 'application/pdf' not in content_type and 'text/html' in content_type:
soup = BeautifulSoup(response.text, 'html.parser')
for link in soup.find_all('a', href=True):
if link['href'].endswith('.pdf'):
print(f"Found PDF link: {link['href']}")
# Download the actual PDF URL
Extracted Text Shows Garbled Characters
Problem: Text extraction returns unreadable characters, often due to encoding or scanned PDFs.
Solution: Ensure proper handling or use OCR for scanned PDFs:
from spire.pdf import PdfDocument, PdfTextExtractor
document = PdfDocument("example.pdf")
extractor = PdfTextExtractor(document.Pages[0])
text = extractor.ExtractText()
print(text[:200])
# If text is still garbled, the PDF may be image-based; consider OCR
PDF Loads But Has No Pages
Problem: document.Pages.Count returns 0 even though the file exists.
Solution: PDF may be corrupted or password-protected:
from spire.pdf import PdfDocument, Stream
with open("protected.pdf", "rb") as f:
pdf_bytes = f.read()
# For password-protected PDF
document = PdfDocument(Stream(pdf_bytes), "password")
print(f"Pages: {document.Pages.Count}")
8. Conclusion
In this article, we demonstrated how to download PDF files from URLs in Python using Spire.PDF for Python. By leveraging the Stream class, developers can load PDF data directly from memory without unnecessary disk I/O, enabling efficient document processing pipelines.
We covered the complete workflow: downloading PDF data with the requests library, creating Stream objects from bytes, loading PdfDocument instances, handling network errors, managing large files, and troubleshooting common issues. The production-ready code examples provide a solid foundation for building robust PDF download and processing systems.
To fully experience the capabilities of Spire.PDF for Python without any evaluation limitations, you can request a free 30-day trial license.
9. FAQs
Q1. How do I download a PDF from a URL using Python?
Use the requests library to fetch the PDF data and Spire.PDF to load it from memory:
response = requests.get(url)
stream = Stream(response.content)
document = PdfDocument(stream)
Q2. How do I handle authentication-protected PDFs?
For basic authentication, use the auth parameter:
response = requests.get(url, auth=('username', 'password'))
For token-based authentication, add headers:
headers = {'Authorization': 'Bearer YOUR_TOKEN'}
response = requests.get(url, headers=headers)
Q3. What's the maximum PDF file size I can download?
The theoretical limit depends on your system's available memory. For files larger than 200MB, use the streaming approach with a temporary file instead of loading everything into memory.
Q4. Can I download multiple PDFs in parallel?
Yes. Use concurrent.futures or asyncio to download multiple PDFs simultaneously for better performance.
from concurrent.futures import ThreadPoolExecutor
urls = ["url1.pdf", "url2.pdf", "url3.pdf"]
with ThreadPoolExecutor(max_workers=5) as executor:
executor.map(lambda u: download_pdf(u), urls)

Inserting mathematical equations into Word documents programmatically is essential for developers building scientific document generators, academic reporting systems, educational platforms, or engineering automation tools. Whether you're generating research papers, technical documentation, or mathematics worksheets, automating equation insertion greatly improves efficiency and consistency.
However, manually formatting equations in Microsoft Word is time-consuming, and building a mathematical rendering engine from scratch can be extremely complex. Developers often need a reliable way to add equations in Word while supporting standard mathematical formats such as LaTeX and MathML.
With Spire.Doc for Python, developers can insert mathematical equations into Word documents directly from LaTeX and MathML code using a straightforward API. This article demonstrates how to create Word equations in Python, including how to insert formulas, convert equations between LaTeX, MathML, and Office MathML (OMML), and export Word equations into different mathematical formats.
Quick Navigation
- Understanding Mathematical Equations in Word Documents
- Install Spire.Doc for Python
- Insert Equations into Word from LaTeX in Python
- Add MathML Equations to Word Documents in Python
- Convert Word Equations to LaTeX or MathML
- Render Equation as Image
- Complete Example: Multi-Format Equation Processing
- Common Pitfalls
- FAQ
1. Understanding Mathematical Equations in Word Documents
Microsoft Word uses Office Math Markup Language (OMML) as its internal format for mathematical equations. OMML is an XML-based structure that controls equation layout, symbols, fractions, matrices, and other mathematical elements in Word documents. However, directly creating or editing OMML is cumbersome for most developers.
In real-world applications, mathematical content is more commonly written in LaTeX or MathML:
- LaTeX is widely used in academia and scientific publishing because of its concise syntax and powerful mathematical typesetting capabilities.
- MathML is an XML-based standard designed for mathematical content on the web and in educational systems.
To generate editable Word equations programmatically, developers often need to convert between these formats and Word's native equation objects.
Why Choose Spire.Doc for Python?
Spire.Doc for Python provides native support for Word equation processing through the OfficeMath class. Instead of manually generating OMML or relying on image-based workarounds, developers can directly create editable Word equations from LaTeX or MathML code.
Key capabilities include:
| Capability | Supported |
|---|---|
| Insert equations from LaTeX | ✓ |
| Insert equations from MathML | ✓ |
| Export Word equations to LaTeX | ✓ |
| Export Word equations to MathML | ✓ |
| Access native OMML content | ✓ |
| Render equations as images | ✓ |
These capabilities are particularly useful for academic report generation, educational platforms, MathML-to-Word conversion workflows, LaTeX publishing pipelines, and other automated document generation scenarios involving mathematical content.
2. Install Spire.Doc for Python
Install Spire.Doc for Python via pip:
pip install spire.doc
Import the required classes in your Python script:
from spire.doc import *
Alternatively, you can manually install the library from the Spire.Doc for Python download page.
3. Insert Equations into Word from LaTeX in Python
LaTeX is the most widely used format for writing mathematical equations in academic and scientific documents. With Spire.Doc for Python, you can convert LaTeX expressions into native Word equation objects and insert these equations directly into DOCX files.
The following example demonstrates how to insert multiple LaTeX equations into a Word document using the OfficeMath class.
from spire.doc import *
def insert_latex_equations():
# Create a new Word document
doc = Document()
section = doc.AddSection()
# Add a title paragraph
title_para = section.AddParagraph()
title_para.AppendText("Mathematical Equations from LaTeX")
title_para.Format.HorizontalAlignment = HorizontalAlignment.Left
# Define LaTeX equations to insert
latex_equations = [
r"x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}", # Quadratic formula
r"e^{i\pi} + 1 = 0", # Euler's identity
r"\int_0^\infty e^{-x} \, dx = 1", # Definite integral
# Summation formula
r"\sum_{i=1}^{n} i = \frac{n(n+1)}{2}",
r"\sum_{i=1}^{n} i = \frac{n(n+1)}{2}", # Summation formula
r"A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}", # Matrix
r"P(A \mid B) = \frac{P(B \mid A)P(A)}{P(B)}", # Probability formula
r"\sin^2\theta + \cos^2\theta = 1", # Trigonometric identity
]
# Insert each LaTeX equation as a separate paragraph
for latex_code in latex_equations:
# Create an OfficeMath object from LaTeX code
office_math = OfficeMath(doc)
office_math.FromLatexMathCode(latex_code)
# Add the equation to a new paragraph
para = section.AddParagraph()
para.Items.Add(office_math)
# Save the document
doc.SaveToFile("latex_equations.docx", FileFormat.Docx2019)
doc.Close()
print("LaTeX equations inserted successfully!")
if __name__ == "__main__":
insert_latex_equations()
The following screenshot shows the generated Word document with equations converted from LaTeX code.

Key API Methods
- Document – Represents the Word document container used to create sections and paragraphs
- OfficeMath – Represents a mathematical equation object in Word documents
- FromLatexMathCode() – Converts LaTeX mathematical code into an Office Math object that Word can render natively
- Items.Add() – Adds the OfficeMath object to a paragraph's content collection
- SaveToFile() – Saves the document to disk in DOCX format using FileFormat.Docx2019
This approach supports complex LaTeX constructs such as fractions, integrals, matrices, Greek letters, and other mathematical operators while preserving native Word equation formatting.
Adding Inline Equations
In addition to standalone equations, you can insert inline equations within text paragraphs. This is useful for embedding mathematical expressions within sentences or explanations.
from spire.doc import *
def insert_inline_equation():
# Create a new Word document
doc = Document()
section = doc.AddSection()
# Add introductory text
para = section.AddParagraph()
para.AppendText("The quadratic formula is ")
# Insert inline equation
office_math = OfficeMath(doc)
office_math.FromLatexMathCode(r"x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}")
para.Items.Add(office_math)
para.AppendText(", where a ≠ 0.")
# Save the document
doc.SaveToFile("inline_equation.docx", FileFormat.Docx2019)
doc.Close()
if __name__ == "__main__":
insert_inline_equation()
The inserted equation appears inline within the text:

This approach makes it easy to embed mathematical expressions directly within regular text content, which is useful for educational materials, research papers, and technical documentation.
If you need to combine equations with formatted text, headings, tables, and other structured document elements, you can also refer to our tutorial on creating structured Word documents in Python.
4. Add MathML Equations to Word Documents in Python
MathML (Mathematical Markup Language) is an XML-based standard for representing mathematical expressions on the web and in digital documents. It's commonly used in online education platforms, scientific databases, and content management systems. The following example shows how to convert MathML to Word equations using Spire.Doc for Python.
from spire.doc import *
def insert_mathml_equations():
# Create a new Word document
doc = Document()
section = doc.AddSection()
# Add a title paragraph
title_para = section.AddParagraph()
title_para.AppendText("Mathematical Equations from MathML")
# Define MathML equations to insert
mathml_equations = [
# Euler's identity
r'<math xmlns="http://www.w3.org/1998/Math/MathML">'
r'<msup><mi>e</mi><mrow><mi>i</mi><mi>π</mi></mrow></msup>'
r'<mo>+</mo><mn>1</mn><mo>=</mo><mn>0</mn>'
r'</math>',
# Pythagorean theorem
r'<math xmlns="http://www.w3.org/1998/Math/MathML">'
r'<msup><mi>a</mi><mn>2</mn></msup>'
r'<mo>+</mo>'
r'<msup><mi>b</mi><mn>2</mn></msup>'
r'<mo>=</mo>'
r'<msup><mi>c</mi><mn>2</mn></msup>'
r'</math>',
# Fraction expression
r'<math xmlns="http://www.w3.org/1998/Math/MathML">'
r'<mfrac>'
r'<mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow>'
r'<mrow><mi>z</mi><mo>−</mo><mn>1</mn></mrow>'
r'</mfrac>'
r'</math>',
# Integral equation
r'<math xmlns="http://www.w3.org/1998/Math/MathML">'
r'<msubsup><mo>∫</mo><mn>0</mn><mn>1</mn></msubsup>'
r'<msup><mi>x</mi><mn>2</mn></msup>'
r'<mi>d</mi><mi>x</mi>'
r'<mo>=</mo>'
r'<mfrac><mn>1</mn><mn>3</mn></mfrac>'
r'</math>'
]
# Insert each MathML equation as a separate paragraph
for mathml_code in mathml_equations:
# Create an OfficeMath object from MathML code
office_math = OfficeMath(doc)
office_math.FromMathMLCode(mathml_code)
# Add the equation to a new paragraph
para = section.AddParagraph()
para.Items.Add(office_math)
# Save the document
doc.SaveToFile("mathml_equations.docx", FileFormat.Docx2019)
doc.Close()
print("MathML equations inserted successfully!")
if __name__ == "__main__":
insert_mathml_equations()
The following screenshot shows the generated Word document with equations converted from MathML code.

Key API Method
- FromMathMLCode() – Parses MathML markup and converts it into a native Word equation object.
MathML support is especially useful when working with XML-based educational content, web-based equation systems, and STEM learning platforms that store mathematical expressions in MathML format.
Combining LaTeX and MathML in One Document
You can mix both LaTeX and MathML equations within the same document, allowing flexibility in content sources:
from spire.doc import *
def insert_mixed_equations():
# Create a new Word document
doc = Document()
section = doc.AddSection()
# Insert LaTeX equation
latex_para = section.AddParagraph()
latex_math = OfficeMath(doc)
latex_math.FromLatexMathCode(r"E = mc^2")
latex_para.Items.Add(latex_math)
# Insert MathML equation
mathml_para = section.AddParagraph()
mathml_math = OfficeMath(doc)
mathml_math.FromMathMLCode(
r'<math xmlns="http://www.w3.org/1998/Math/MathML">'
r'<mi>F</mi><mo>=</mo><mi>m</mi><mi>a</mi>'
r'</math>'
)
mathml_para.Items.Add(mathml_math)
# Save the document
doc.SaveToFile("mixed_equations.docx", FileFormat.Docx2019)
doc.Close()
if __name__ == "__main__":
insert_mixed_equations()
This approach is useful when mathematical content comes from different sources, such as LaTeX-based publishing systems and MathML-based web applications.
If your mathematical content originates from web pages or HTML-based systems, you can also refer to our tutorial on converting HTML content to Word documents in Python.
5. Convert Word Equations to LaTeX, MathML, and OMML
Besides inserting equations into Word documents, Spire.Doc for Python also supports exporting Word equations to multiple mathematical markup formats. This is useful for interoperability between Word, LaTeX publishing systems, web-based MathML platforms, and custom XML workflows.
The following example demonstrates how to extract equations from a Word document and export them as LaTeX, MathML, and Office MathML (OMML).
from spire.doc import *
def export_equation_formats():
# Load a Word document containing equations
doc = Document()
doc.LoadFromFile("equations.docx")
# Access the first paragraph
section = doc.Sections[0]
para = section.Paragraphs[0]
# Find OfficeMath objects
for item in para.ChildObjects:
if isinstance(item, OfficeMath):
# Export to LaTeX
latex_code = item.ToLaTexMathCode()
print("LaTeX:")
print(latex_code)
print()
# Export to MathML
mathml_code = item.ToMathMLCode()
print("MathML:")
print(mathml_code)
print()
# Export to Office MathML (OMML)
omml_code = item.ToOfficeMathMLCode()
print("OMML:")
print(omml_code)
# Save outputs to files
with open("equation.tex", "w", encoding="utf-8") as f:
f.write(latex_code)
with open("equation.xml", "w", encoding="utf-8") as f:
f.write(mathml_code)
with open("equation.omml", "w", encoding="utf-8") as f:
f.write(omml_code)
break
doc.Close()
if __name__ == "__main__":
export_equation_formats()
The following screenshot shows the exported equation formats printed in the Python console.

Supported Export Formats
| Format | Primary Use Case | Characteristics |
|---|---|---|
| LaTeX | Academic publishing and scientific papers | Compact syntax widely used in academia |
| MathML | Web-based mathematical content | XML-based format designed for browsers and educational systems |
| OMML | Microsoft Word integration | Native Office equation format with full Word compatibility |
These export capabilities make it easier to:
- Convert Word equations into LaTeX publishing workflows
- Publish equations on websites using MathML
- Integrate Word documents with XML-based systems
- Inspect and debug Word equation structures using OMML
6. Render Office Math Equations to Images
In some scenarios, you may need to export equations as image files for use in presentations, web pages, or other non-editable contexts. Spire.Doc for Python allows you to render Office Math equations into image streams that can be saved as image files.
from spire.doc import *
def render_equation_as_image():
# Create a new Word document with an equation
doc = Document()
section = doc.AddSection()
para = section.AddParagraph()
# Insert an equation
office_math = OfficeMath(doc)
office_math.FromLatexMathCode(
r"\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}"
)
para.Items.Add(office_math)
# Render the equation as an image stream
image_stream = office_math.SaveImageToStream(ImageType.Bitmap)
# Save the image to file
with open("equations/equation.png", "wb") as f:
f.write(image_stream.ToArray())
# Release unmanaged resources
image_stream.Dispose()
doc.Close()
print("Equation rendered as image successfully!")
if __name__ == "__main__":
render_equation_as_image()
The following screenshot shows the equation rendered as an image file.

This feature is particularly useful for:
- Embedding equations in presentations
- Displaying formulas on web pages
- Generating static previews for document systems
If you want to render complete Word documents as images rather than exporting individual equations, check out our tutorial on converting Word documents to images in Python.
7. Complete Example: Multi-Format Equation Processing
The following comprehensive example demonstrates a complete workflow that combines multiple equation operations: inserting equations from different sources, exporting to various formats, and rendering as images.
from spire.doc import *
def complete_equation_workflow():
"""
Demonstrates a complete workflow for equation processing:
- Create equations from LaTeX and MathML
- Export equations to LaTeX and MathML
- Render equations as images
"""
# Create a new Word document
doc = Document()
section = doc.AddSection()
# Add document title
title_para = section.AddParagraph()
title_text = title_para.AppendText("Complete Equation Processing Workflow")
title_text.CharacterFormat.FontSize = 16
title_text.CharacterFormat.Bold = True
title_para.Format.HorizontalAlignment = HorizontalAlignment.Center
# Insert equations from LaTeX
latex_section_title = section.AddParagraph()
latex_title_text = latex_section_title.AppendText("\nEquations from LaTeX:")
latex_title_text.CharacterFormat.Bold = True
latex_examples = [
(r"E = mc^2", "Einstein's Mass-Energy Equivalence"),
(r"\sum_{i=1}^{n} i = \frac{n(n+1)}{2}", "Sum of First n Integers"),
(r"\frac{d}{dx}\left(\int_a^x f(t)dt\right) = f(x)", "Fundamental Theorem of Calculus")
]
first_equation = None
for latex_code, description in latex_examples:
# Add description
desc_para = section.AddParagraph()
desc_para.AppendText(f"{description}:")
# Insert equation
office_math = OfficeMath(doc)
office_math.FromLatexMathCode(latex_code)
eq_para = section.AddParagraph()
eq_para.Items.Add(office_math)
if first_equation is None:
first_equation = office_math
# Insert equations from MathML
mathml_section_title = section.AddParagraph()
mathml_title_text = mathml_section_title.AppendText("\nEquations from MathML:")
mathml_title_text.CharacterFormat.Bold = True
mathml_examples = [
(
r'<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>a</mi><mo>+</mo><mi>b</mi><mo>=</mo><mi>c</mi></math>',
"Simple Addition"
),
(
r'<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>e</mi><mrow><mi>i</mi><mi>π</mi></mrow></msup><mo>+</mo><mn>1</mn><mo>=</mo><mn>0</mn></math>',
"Euler's Identity"
)
]
for mathml_code, description in mathml_examples:
# Add description
desc_para = section.AddParagraph()
desc_para.AppendText(f"{description}:")
# Insert equation
office_math = OfficeMath(doc)
office_math.FromMathMLCode(mathml_code)
eq_para = section.AddParagraph()
eq_para.Items.Add(office_math)
# Save the Word document
output_docx = "complete_equations.docx"
doc.SaveToFile(output_docx, FileFormat.Docx2019)
print(f"Word document saved: {output_docx}")
# Export the first equation to LaTeX
latex_export = first_equation.ToLaTexMathCode()
with open("exported_equation.tex", "w", encoding="utf-8") as f:
f.write(latex_export)
print(f"Exported to LaTeX: {latex_export}")
# Export the first equation to MathML
mathml_export = first_equation.ToMathMLCode()
with open("exported_equation.xml", "w", encoding="utf-8") as f:
f.write(mathml_export)
print("Exported to MathML")
# Render the first equation as an image
image_stream = first_equation.SaveImageToStream(ImageType.Bitmap)
with open("equation_render.png", "wb") as f:
f.write(image_stream.ToArray())
# Release unmanaged resources
image_stream.Dispose()
print("Equation rendered as image successfully!")
# Clean up
doc.Close()
print("\nWorkflow completed successfully!")
if __name__ == "__main__":
complete_equation_workflow()
The generated Word document will look like this:

This complete example demonstrates:
- Multi-source equation insertion – Combining LaTeX and MathML inputs
- Descriptive labeling – Adding context to each equation
- Format conversion – Exporting to LaTeX and MathML
- Image rendering – Creating visual representations
- Resource management – Proper cleanup of document objects
The resulting Word document contains well-formatted equations with descriptions, while the exported files provide alternative formats for different use cases.
8. Common Pitfalls
Raw String Literals for LaTeX
When writing LaTeX code in Python strings, always use raw strings (prefix with r) to prevent escape sequence interpretation:
# Correct: Use raw string
latex_code = r"\int_0^\infty e^{-x} dx"
# Incorrect: Backslashes will be interpreted as escape sequences
latex_code = "\int_0^\infty e^{-x} dx"
Unsupported LaTeX Commands
Not all LaTeX commands are supported by Word's equation engine. Some advanced LaTeX constructs may not render correctly. Stick to standard mathematical notation whenever possible:
# Supported: Standard mathematical notation
office_math.FromLatexMathCode(r"\alpha + \beta = \gamma")
# Some advanced LaTeX constructs may not be supported
# office_math.FromLatexMathCode(r"\begin{align} ... \end{align}")
MathML Namespace Requirements
MathML code must include the proper namespace declaration to parse correctly:
# Correct: Include namespace
mathml = r'<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>'
# Incorrect: Missing namespace may fail
mathml = r'<math><mi>x</mi></math>'
Memory Management
Always close documents after processing to release resources, especially in batch operations:
doc = Document()
try:
# Process equations
doc.SaveToFile("output.docx", FileFormat.Docx2019)
finally:
doc.Close() # Ensure cleanup even if errors occur
Character Encoding
When saving exported LaTeX or MathML to files, ensure proper UTF-8 encoding for special characters:
with open("equation.tex", "w", encoding="utf-8") as f:
f.write(latex_code)
Image Stream Disposal
Always dispose of image streams after use to properly release resources:
image_stream = office_math.SaveImageToStream(ImageType.Bitmap)
try:
with open("equation.png", "wb") as f:
f.write(image_stream.ToArray())
finally:
image_stream.Dispose()
Conclusion
In this article, we demonstrated how to insert mathematical equations into Word documents in Python using Spire.Doc for Python. By leveraging the Spire API, developers can create Word equations from LaTeX and MathML code, convert between LaTeX, MathML, and Word’s native OMML format, and render equations as images. This capability is essential for automating scientific document generation, educational content creation, and mathematical publishing workflows.
Spire.Doc for Python provides comprehensive equation processing capabilities beyond basic insertion, including conversion between LaTeX and MathML into Word’s native OMML format, as well as exporting Word equations back to LaTeX, MathML, and OMML. The library simplifies complex mathematical typesetting while maintaining compatibility with Microsoft Word’s native equation engine.
If you want to evaluate the full capabilities of Spire.Doc for Python, you can apply for a 30-day free license.
9. FAQ
How do I insert equations into Word using Python?
Use the OfficeMath class from Spire.Doc for Python. Create an OfficeMath object, call FromLatexMathCode() or FromMathMLCode() with your equation code, then add it to a paragraph using para.Items.Add(office_math). Finally, save the document using doc.SaveToFile().
Can I add LaTeX equations to Word documents in Python?
Yes. Spire.Doc for Python supports inserting equations from LaTeX code using the FromLatexMathCode() method. Standard mathematical notation such as fractions, integrals, superscripts, subscripts, and Greek letters can be converted into Word-compatible equations.
Does Spire.Doc support MathML equations?
Yes. You can create Word equations from MathML using the FromMathMLCode() method. Make sure the MathML content includes the correct namespace declaration:
<math xmlns="http://www.w3.org/1998/Math/MathML">
Can I export Word equations back to LaTeX or MathML?
Yes. Spire.Doc for Python provides methods such as ToLaTexMathCode() and ToMathMLCode() to export Office Math equations into LaTeX or MathML formats. This is useful for content migration, storage, or integration with other mathematical systems.
How can I render equations as images?
Use the SaveImageToStream() method on an OfficeMath object to render the equation as an image stream. You can then save the stream as an image file and use it in presentations, web pages, or preview systems.

Modern development teams often need to share JavaScript or JSX source code with project managers, clients, auditors, or educators who don't use code editors. However, raw .js and .jsx files are difficult to review outside tools like VS Code or WebStorm, while manually copying code into Word documents frequently breaks indentation, formatting, and readability.
Using Spire.Doc for Python together with Pygments, developers can convert JavaScript to Word in Python with syntax highlighting and customizable document formatting. This automated approach is useful for technical documentation, compliance archiving, educational materials, code reviews, and client deliverables.
In this article, you'll learn how to convert JavaScript and JSX files to Word documents in Python using Spire.Doc for Python, including basic conversion, advanced formatting techniques, batch processing, and PDF export.
Quick Navigation
- Understanding the Conversion Workflow
- Prerequisites
- Basic Implementation of JavaScript to Word Conversion
- Advanced Scenarios
- Common Pitfalls
- Conclusion
- FAQ
1. Understanding the Conversion Workflow
The conversion process uses Pygments to generate syntax-highlighted HTML, then imports this HTML into a Word document using Spire.Doc's HTML import functionality:
- Read source code from
.jsor.jsxfiles - Generate syntax-highlighted HTML using Pygments'
highlight()function - Import the HTML into Word using
AppendHTML()
This approach provides syntax coloring through Pygments' built-in styles, while Spire.Doc handles document structure including margins, headers, footers, and multi-format export. It provides a simple and flexible API for automating the conversion process.
2. Prerequisites
Before converting JavaScript files to Word documents in Python, you need to install Spire.Doc for Python and Pygments:
pip install spire.doc
pip install pygments
Verify the packages are available:
import spire.doc
from pygments import highlight
from pygments.formatters import HtmlFormatter
Alternatively, you can download Spire.Doc for Python and add it to your project.
3. Basic Implementation
The following example converts a JavaScript file to a Word document with syntax highlighting:
from spire.doc import *
from pygments import highlight
from pygments.lexers import JavascriptLexer
from pygments.formatters import HtmlFormatter
def convert_js_to_word(input_file: str, output_file: str) -> None:
"""Convert JavaScript file to Word document with syntax highlighting."""
with open(input_file, "r", encoding="utf-8") as file:
js_code = file.read()
document = Document()
section = document.AddSection()
section.PageSetup.Margins.All = 50
title_paragraph = section.AddParagraph()
title_text = title_paragraph.AppendText(f"Source Code: {input_file}")
title_text.CharacterFormat.FontName = "Arial"
title_text.CharacterFormat.FontSize = 14
title_text.CharacterFormat.Bold = True
title_paragraph.Format.AfterSpacing = 10
html_formatter = HtmlFormatter(
nowrap=True,
style='colorful',
noclasses=True
)
highlighted_html = highlight(js_code, JavascriptLexer(), html_formatter)
code_paragraph = section.AddParagraph()
code_paragraph.AppendHTML(f'<pre style="font-family: Consolas; font-size: 10pt;">{highlighted_html}</pre>')
document.SaveToFile(output_file, FileFormat.Docx)
document.Close()
print(f"Converted {input_file} to {output_file}")
convert_js_to_word("app.js", "JavaScriptCode.docx")

Key Components
- Document – Word document container for sections, paragraphs, and content
- Section – Document section with page setup properties (margins, orientation)
- Paragraph – Text container with formatting options
- AppendHTML() – Imports HTML content into the paragraph, including inline styles for colors and fonts
- highlight() – Pygments function that generates syntax-highlighted output
- HtmlFormatter – Pygments formatter producing HTML with inline styles (use
noclasses=True) - JavascriptLexer – Pygments lexer that identifies JavaScript syntax elements
Spire.Doc can import syntax-highlighted HTML generated by Pygments, allowing JavaScript code formatting and colors to be preserved in Word documents.
4. Advanced Scenarios
Convert JSX Files
For JSX files, it's recommended to use JsxLexer instead of JavascriptLexer to achieve more accurate syntax highlighting for component tags and embedded JSX expressions.
Example JSX input (App.jsx):
``jsx import React, { useState } from 'react';
const TodoList = () => { const [todos, setTodos] = useState([]);
return (
<div className="todo-container">
<h1>My Tasks</h1>
</div>
);
};
export default TodoList;
Use `JsxLexer` when generating syntax-highlighted HTML:
```python
from pygments.lexers import JsxLexer
highlighted_html = highlight(
jsx_code,
JsxLexer(),
html_formatter
)
Then convert the highlighted JSX content to Word using the same AppendHTML() workflow:
convert_js_to_word("App.jsx", "ReactComponent.docx")
The conversion result looks like this:

JsxLexer provides improved recognition for JSX tags, attributes, and embedded expressions compared to the standard JavaScript lexer, resulting in more accurate syntax coloring in the generated Word document.
Batch Convert Multiple Files
If you need to convert large numbers of JavaScript or JSX files, you can automate the process by scanning a folder and generating Word documents in batches.
import os
from pathlib import Path
def batch_convert_js_files(source_folder: str, output_folder: str) -> None:
"""Convert all JavaScript files in a folder to Word documents."""
Path(output_folder).mkdir(parents=True, exist_ok=True)
js_extensions = ('.js', '.jsx', '.mjs')
converted_count = 0
error_count = 0
for filename in os.listdir(source_folder):
if filename.lower().endswith(js_extensions):
input_path = os.path.join(source_folder, filename)
base_name = os.path.splitext(filename)[0]
output_path = os.path.join(output_folder, f"{base_name}.docx")
try:
convert_js_to_word(input_path, output_path)
converted_count += 1
except Exception as e:
print(f"Error converting {filename}: {str(e)}")
error_count += 1
print(f"\nBatch conversion complete:")
print(f" Converted: {converted_count} files")
print(f" Errors: {error_count} files")
batch_convert_js_files("src/scripts", "output/docs")
Add Line Numbers
Line numbers can improve readability during code reviews, audits, or technical documentation. Since Word HTML rendering may not fully support Pygments' built-in line number layouts, a practical approach is to prepend custom line numbers after syntax highlighting.
html_formatter = HtmlFormatter(
nowrap=True,
noclasses=True,
style="colorful"
)
highlighted_html = highlight(
js_code,
JavascriptLexer(),
html_formatter
)
highlighted_lines = highlighted_html.splitlines()
numbered_lines = []
for index, line in enumerate(highlighted_lines, start=1):
numbered_line = (
f'<span style="color: gray; font-weight: bold;">'
f'{index:4d} '
f'</span>{line}'
)
numbered_lines.append(numbered_line)
combined_html = (
'<pre style="font-family: Consolas; '
'font-size: 10pt; line-height: 1.4;">'
+ '\n'.join(numbered_lines) +
'</pre>'
)
paragraph.AppendHTML(combined_html)
The generated Word document with line numbers looks like this:

Add Headers and Footers
Headers and footers help organize generated Word documents by adding titles, page numbers, and document metadata. This is especially useful for formal reports or exported technical documentation.
def add_document_metadata(section: Section, document_title: str) -> None:
"""Add header and footer to document section."""
header = section.HeadersFooters.Header.AddParagraph()
header_text = header.AppendText(document_title)
header_text.CharacterFormat.FontName = "Arial"
header_text.CharacterFormat.FontSize = 10
header_text.CharacterFormat.TextColor = Color.get_Black()
header.Format.HorizontalAlignment = HorizontalAlignment.Left
header.Format.TextAlignment = TextAlignment.Top
header.Format.Borders.Bottom.BorderType = BorderStyle.Single
header.Format.Borders.Bottom.Color = Color.get_Black()
footer = section.HeadersFooters.Footer.AddParagraph()
footer.Format.HorizontalAlignment = HorizontalAlignment.Center
footer.Format.TextAlignment = TextAlignment.Bottom
page_field = footer.AppendField("page", FieldType.FieldPage)
page_field.CharacterFormat.FontName = "Arial"
page_field.CharacterFormat.FontSize = 9
footer.AppendText(" of ")
total_pages_field = footer.AppendField("numPages", FieldType.FieldNumPages)
total_pages_field.CharacterFormat.FontName = "Arial"
total_pages_field.CharacterFormat.FontSize = 9
document = Document()
document.LoadFromFile("CodeWithLines.docx")
section = document.Sections[0]
add_document_metadata(section, "JavaScript Source Code Documentation")
document.SaveToFile("CodeWithHeadersFooters.docx", FileFormat.Docx)
The generated Word document with headers and footers looks like this:

For more advanced customization options, refer to our guide on how to add headers and footers to Word documents in Python.
Export to PDF Format
In addition to DOCX output, Spire.Doc can export syntax-highlighted JavaScript code directly to PDF format. This is useful when distributing read-only documentation or sharing code outside Microsoft Word environments.
def convert_js_to_pdf(input_file: str, output_file: str) -> None:
"""Convert JavaScript file directly to PDF."""
with open(input_file, "r", encoding="utf-8") as file:
js_code = file.read()
document = Document()
section = document.AddSection()
section.PageSetup.Margins.All = 50
html_formatter = HtmlFormatter(noclasses=True, style='colorful')
highlighted_html = highlight(js_code, JavascriptLexer(), html_formatter)
paragraph = section.AddParagraph()
paragraph.AppendHTML(f'<pre style="font-family: Consolas; font-size: 10pt;">{highlighted_html}</pre>')
document.SaveToFile(output_file, FileFormat.PDF)
document.Close()
convert_js_to_pdf("app.js", "JavaScriptCode.pdf")
For more advanced PDF conversion techniques, including layout control and document formatting, see our detailed guide on converting Word documents to PDF in Python.
Customize Syntax Highlighting Style
Pygments provides multiple built-in color schemes:
def convert_with_custom_style(input_file: str, output_file: str, style_name: str = 'monokai') -> None:
"""Convert JavaScript to Word with custom highlighting style."""
with open(input_file, "r", encoding="utf-8") as file:
js_code = file.read()
document = Document()
section = document.AddSection()
section.PageSetup.Margins.All = 50
html_formatter = HtmlFormatter(
noclasses=True,
style=style_name,
nowrap=True
)
highlighted_html = highlight(js_code, JavascriptLexer(), html_formatter)
paragraph = section.AddParagraph()
paragraph.AppendHTML(f'<pre style="font-family: Consolas; font-size: 10pt;">{highlighted_html}</pre>')
document.SaveToFile(output_file, FileFormat.Docx)
document.Close()
convert_with_custom_style("app.js", "CodeMonokai.docx", style_name='monokai')
Available styles include: 'monokai', 'colorful', 'vim', 'vs', 'tango', 'friendly', 'default'
5. Common Pitfalls
Missing HtmlFormatter Configuration
Problem: Default HtmlFormatter generates CSS classes instead of inline styles, which Word cannot process without external stylesheets.
Solution: Always use noclasses=True:
html_formatter = HtmlFormatter(noclasses=True, style='colorful')
highlighted_html = highlight(js_code, JavascriptLexer(), html_formatter)
Encoding Errors with Special Characters
Problem: Reading files without UTF-8 encoding causes character corruption on some platforms.
Solution: Explicitly specify UTF-8 encoding:
with open(input_file, "r", encoding="utf-8") as file:
js_code = file.read()
For files with BOM (Byte Order Mark), use utf-8-sig:
with open(input_file, "r", encoding="utf-8-sig") as file:
js_code = file.read()
Indentation Loss
Problem: Not wrapping highlighted code in <pre> tags causes indentation to disappear.
Solution: Wrap syntax-highlighted HTML in <pre> tags:
highlighted_html = highlight(js_code, JavascriptLexer(), html_formatter)
paragraph.AppendHTML(f'<pre style="font-family: Consolas;">{highlighted_html}</pre>')
ModuleNotFoundError
Problem: Package not installed in current Python environment.
Solution:
pip install spire.doc
For virtual environments, ensure activation before installation:
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
pip install spire.doc
Performance with Large Files
Problem: Very large JavaScript files (10,000+ lines) may cause slow conversion.
Solution: Process files in chunks:
def convert_large_file(input_file: str, output_file: str, chunk_size: int = 500) -> None:
"""Convert large JavaScript file in chunks."""
with open(input_file, "r", encoding="utf-8") as file:
lines = file.readlines()
document = Document()
section = document.AddSection()
section.PageSetup.Margins.All = 50
html_formatter = HtmlFormatter(noclasses=True, style='colorful')
for i in range(0, len(lines), chunk_size):
chunk = ''.join(lines[i:i + chunk_size])
highlighted_html = highlight(chunk, JavascriptLexer(), html_formatter)
paragraph = section.AddParagraph()
paragraph.AppendHTML(f'<pre style="font-family: Consolas; font-size: 10pt;">{highlighted_html}</pre>')
document.SaveToFile(output_file, FileFormat.Docx)
document.Close()
Conclusion
This article demonstrated how to convert JavaScript and JSX files to Word documents in Python using Spire.Doc for Python and Pygments. By leveraging the highlight() function with HtmlFormatter and Spire.Doc's AppendHTML() method, developers can automate code documentation workflows with syntax highlighting.
Spire.Doc for Python provides document generation capabilities including table creation, image insertion, header/footer management, and multi-format export.
You can apply for a 30-day free license to evaluate all features.
7. FAQ
Can Spire.Doc convert JSX files to Word documents?
Yes. Pygments can highlight many JSX constructs using the JavaScript lexer, including component tags, props, and embedded expressions. However, JSX-specific syntax may not receive dedicated highlighting categories.
Does this solution require Microsoft Word installation?
No. Spire.Doc for Python operates independently without requiring Microsoft Word. The library generates DOCX files directly, making it suitable for server environments and CI/CD pipelines.
Can I convert JavaScript to formats other than DOCX?
Yes. Spire.Doc supports multiple export formats:
document.SaveToFile("output.pdf", FileFormat.PDF)
document.SaveToFile("output.html", FileFormat.Html)
document.SaveToFile("output.rtf", FileFormat.Rtf)
How do I handle TypeScript files (.ts, .tsx)?
Use TypescriptLexer:
from pygments.lexers import TypescriptLexer
highlighted_html = highlight(ts_code, TypescriptLexer(), html_formatter)
Is this approach suitable for enterprise-scale projects?
Yes. Python automation integrates with CI/CD pipelines and batch processing workflows. Local execution avoids security risks from uploading source code to online converters. Consider implementing logging, progress reporting, and error tracking for large deployments.
Can I customize syntax highlighting colors?
Yes. Pygments offers numerous built-in styles:
html_formatter = HtmlFormatter(noclasses=True, style='monokai')
Available styles: 'monokai', 'colorful', 'vim', 'vs', 'tango', 'friendly', 'default'