Spire.Office Knowledgebase Page 8 | E-iceblue

Convert JSON and Excel in Python using Spire.XLS – tutorial cover image

In many Python projects, especially those that involve APIs, data analysis, or business reporting, developers often need to convert Excel to JSON or JSON to Excel using Python code. These formats serve different but complementary roles: JSON is ideal for structured data exchange and storage, while Excel is widely used for sharing, editing, and presenting data in business environments.

This tutorial provides a complete, developer-focused guide to converting between JSON and Excel in Python. You'll learn how to handle nested data, apply Excel formatting, and resolve common conversion or encoding issues. We’ll use Python’s built-in json module to handle JSON data, and Spire.XLS for Python to read and write Excel files in .xlsx, .xls, and .csv formats — all without requiring Microsoft Excel or other third-party software.

Topics covered include:


Install Spire.XLS for Python

This library is used in this tutorial to generate and parse Excel files (.xlsx, .xls, .csv) as part of the JSON–Excel conversion workflow.

To get started, install the Spire.XLS for Python package from PyPI:

pip install spire.xls

You can also choose Free Spire.XLS for Python in smaller projects:

pip install spire.xls.free

Spire.XLS for Python runs on Windows, Linux, and macOS. It does not require Microsoft Excel or any COM components to be installed.

Why Choose Spire.XLS over Open-Source Libraries?

Many open-source Python libraries are great for general Excel tasks like simple data export or basic formatting. If your use case only needs straightforward table output, these tools often get the job done quickly.

However, when your project requires rich Excel formatting, multi-sheet reports, or an independent solution without Microsoft Office, Spire.XLS for Python stands out by offering a complete Excel feature set.

Capability Open-Source Libraries Spire.XLS for Python
Advanced Excel formatting Basic styling Full styling API for reports
No Office/COM dependency Fully standalone Fully standalone
Supports .xls, .xlsx, .csv .xlsx and .csv mostly; .xls may need extra packages Full support for .xls, .xlsx, .csv
Charts, images, shapes Limited or none Built-in full support

For developer teams that need polished Excel files — with complex layouts, visuals, or business-ready styling — Spire.XLS is an efficient, all-in-one alternative.


Convert JSON to Excel in Python

In this section, we’ll walk through how to convert structured JSON data into an Excel file using Python. This is especially useful when exporting API responses or internal data into .xlsx reports for business users or analysts.

Step 1: Prepare JSON Data

We’ll start with a JSON list of employee records:

[
  {"employee_id": "E001", "name": "Jane Doe", "department": "HR"},
  {"employee_id": "E002", "name": "Michael Smith", "department": "IT"},
  {"employee_id": "E003", "name": "Sara Lin", "department": "Finance"}
]

This is a typical structure returned by APIs or stored in log files. For more complex nested structures, see the real-world example section.

Step 2: Convert JSON to Excel in Python with Spire.XLS

from spire.xls import Workbook, FileFormat
import json

# Load JSON data from file
with open("employees.json", "r", encoding="utf-8") as f:
    data = json.load(f)

# Create a new Excel workbook and access the first worksheet
workbook = Workbook()
sheet = workbook.Worksheets[0]

# Write headers to the first row
headers = list(data[0].keys())
for col, header in enumerate(headers):
    sheet.Range[1, col + 1].Text = header

# Write data rows starting from the second row
for row_idx, row in enumerate(data, start=2):
    for col_idx, key in enumerate(headers):
        sheet.Range[row_idx, col_idx + 1].Text = str(row.get(key, ""))

# Auto-fit the width of all used columns
for i in range(1, sheet.Range.ColumnCount + 1):
    sheet.AutoFitColumn(i)

# Save the Excel file and release resources
workbook.SaveToFile("output/employees.xlsx", FileFormat.Version2016)
workbook.Dispose()

Code Explanation:

  • Workbook() initializes the Excel file with three default worksheets.
  • workbook.Worksheets[] accesses the specified worksheet.
  • sheet.Range(row, col).Text writes string data to a specific cell (1-indexed).
  • The first row contains column headers based on JSON keys, and each JSON object is written to a new row beneath it.
  • workbook.SaveToFile() saves the Excel workbook to disk. You can specify the format using the FileFormat enum — for example, Version97to2003 saves as .xls, Version2007 and newer save as .xlsx, and CSV saves as .csv.

The generated Excel file (employees.xlsx) with columns employee_id, name, and department.

Export JSON to Excel in Python

You can also convert the Excel worksheet to a CSV file using Spire.XLS for Python if you need a plain text output format.


Convert Excel to JSON in Python

This part explains how to convert Excel data back into structured JSON using Python. This is a common need when importing .xlsx files into web apps, APIs, or data pipelines that expect JSON input.

Step 1: Load the Excel File

First, we use Workbook.LoadFromFile() to load the Excel file, and then select the worksheet using workbook.Worksheets[0]. This gives us access to the data we want to convert into JSON format.

from spire.xls import Workbook

# Load the Excel file
workbook = Workbook()
workbook.LoadFromFile("products.xlsx")
sheet = workbook.Worksheets[0]

Step 2: Extract Excel Data and Write to JSON

import json

# Get the index of the last row and column
rows = sheet.LastRow
cols = sheet.LastColumn

# Extract headers from the first row
headers = [sheet.Range[1, i + 1].Text for i in range(cols)]
data = []

# Map each row to a dictionary using headers
for r in range(2, rows + 1):
    row_data = {}
    for c in range(cols):
        value = sheet.Range[r, c + 1].Text
        row_data[headers[c]] = value
    data.append(row_data)

# Write JSON output
with open("products_out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

Code Explanation:

  • sheet.LastRow and sheet.LastColumn detect actual used cell range.
  • The first row is used to extract field names (headers).
  • Each row is mapped to a dictionary, forming a list of JSON objects.
  • sheet.Range[row, col].Text returns the cell’s displayed text, including any formatting (like date formats or currency symbols). If you need the raw numeric value or a real date object, you can use .Value, .NumberValue, or .DateTimeValue instead.

The JSON file generated from the Excel data using Python:

Excel to JSON using Python

If you’re not yet familiar with how to read Excel files in Python, see our full guide: How to Read Excel Files in Python Using Spire.XLS.


Real-World Example: Handling Nested JSON and Formatting Excel

In real-world Python applications, JSON data often contains nested dictionaries or lists, such as contact details, configuration groups, or progress logs. At the same time, the Excel output is expected to follow a clean, readable layout suitable for business or reporting purposes.

In this section, we'll demonstrate how to flatten nested JSON data and format the resulting Excel sheet using Python and Spire.XLS. This includes merging cells, applying styles, and auto-fitting columns — all features that help present complex data in a clear tabular form.

Let’s walk through the process using a sample file: projects_nested.json.

Step 1: Flatten Nested JSON

Sample JSON file (projects_nested.json):

[
  {
    "project_id": "PRJ001",
    "title": "AI Research",
    "manager": {
      "name": "Dr. Emily Wang",
      "email": "emily@lab.org"
    },
    "phases": [
      {"phase": "Design", "status": "Completed"},
      {"phase": "Development", "status": "In Progress"}
    ]
  },
  {
    "project_id": "PRJ002",
    "title": "Cloud Migration",
    "manager": {
      "name": "Mr. John Lee",
      "email": "john@infra.net"
    },
    "phases": [
      {"phase": "Assessment", "status": "Completed"}
    ]
  }
]

We'll flatten all nested structures, including objects like manager, and summarize lists like phases into string fields. Each JSON record becomes a single flat row, with even complex nested data compactly represented in columns using readable summaries.

import json

# Helper: Flatten nested data and summarize list of dicts into strings
# e.g., [{"a":1},{"a":2}] → "a: 1; a: 2"
def flatten(data, parent_key='', sep='.'):
    items = {}
    for k, v in data.items():
        new_key = f"{parent_key}{sep}{k}" if parent_key else k
        if isinstance(v, dict):
            items.update(flatten(v, new_key, sep=sep))
        elif isinstance(v, list):
            if all(isinstance(i, dict) for i in v):
                items[new_key] = "; ".join(
                    ", ".join(f"{ik}: {iv}" for ik, iv in i.items()) for i in v
                )
            else:
                items[new_key] = ", ".join(map(str, v))
        else:
            items[new_key] = v
    return items

# Load and flatten JSON
with open("projects_nested.json", "r", encoding="utf-8") as f:
    raw_data = json.load(f)

flat_data = [flatten(record) for record in raw_data]

# Collect all unique keys from flattened data as headers
all_keys = set()
for item in flat_data:
    all_keys.update(item.keys())
headers = list(sorted(all_keys))  # Consistent, sorted column order

This version of flatten() converts lists of dictionaries into concise summary strings (e.g., "phase: Design, status: Completed; phase: Development, status: In Progress"), making complex structures more compact for Excel output.

Step 2: Format and Export Excel with Spire.XLS

Now we’ll export the flattened project data to Excel, and use formatting features in Spire.XLS for Python to improve the layout and readability. This includes setting fonts, colors, merging cells, and automatically adjusting column widths for a professional report look.

from spire.xls import Workbook, Color, FileFormat

# Create workbook and worksheet
workbook = Workbook()
sheet = workbook.Worksheets[0]
sheet.Name = "Projects"

# Title row: merge and style
col_count = len(headers)
sheet.Range[1, 1, 1, col_count].Merge()
sheet.Range[1, 1].Text = "Project Report (Flattened JSON)"
title_style = sheet.Range["A1"].Style
title_style.Font.IsBold = True
title_style.Font.Size = 14
title_style.Font.Color = Color.get_White()
title_style.Color = Color.get_DarkBlue()

# Header row from flattened keys
for col, header in enumerate(headers):
    cell = sheet.Range[2, col + 1]
    cell.BorderAround() # Add outside borders to a cell or cell range
    #cell.BorderInside() # Add inside borders to a cell range
    cell.Text = header
    style = cell.Style
    style.Font.IsBold = True
    style.Color = Color.get_LightGray()

# Data rows
for row_idx, row in enumerate(flat_data, start=3):
    for col_idx, key in enumerate(headers):
        sheet.Range[row_idx, col_idx + 1].Text = str(row.get(key, ""))

# Auto-fit columns and rows
for col in range(len(headers)):
    sheet.AutoFitColumn(col + 1)
for row in range(len(flat_data)):
    sheet.AutoFitRow(row + 1)

# Save Excel file
workbook.SaveToFile("output/projects_formatted.xlsx", FileFormat.Version2016)
workbook.Dispose()

This produces a clean, styled Excel sheet from a nested JSON file, making your output suitable for reports, stakeholders, or dashboards.

Code Explanation

  • sheet.Range[].Merge(): merges a range of cells into one. Here we use it for the report title row (A1:F1).
  • .Style.Font / .Style.Color: allow customizing font properties (bold, size, color) and background fill of a cell.
  • .BorderAround() / .BorderInside(): add outside/inside borders to a cell range.
  • AutoFitColumn(n): automatically adjusts the width of column n to fit its content.

The Excel file generated after flattening the JSON data using Python:

Nested JSON converted to formatted Excel in Python


Common Errors and Fixes in JSON ↔ Excel Conversion

Converting between JSON and Excel may sometimes raise formatting, encoding, or data structure issues. Here are some common problems and how to fix them:

Error Fix
JSONDecodeError or malformed input Ensure valid syntax; avoid using eval(); use json.load() and flatten nested objects.
TypeError: Object of type ... is not JSON serializable Use json.dump(data, f, default=str) to convert non-serializable values.
Excel file not loading or crashing Ensure the file is not open in Excel; use the correct extension (.xlsx or .xls).
UnicodeEncodeError or corrupted characters Set encoding="utf-8" and ensure_ascii=False in json.dump().

Conclusion

With Spire.XLS for Python, converting between JSON and Excel becomes a streamlined and reliable process. You can easily transform JSON data into well-formatted Excel files, complete with headers and styles, and just as smoothly convert Excel sheets back into structured JSON. The library helps you avoid common issues such as encoding errors, nested data complications, and Excel file format pitfalls.

Whether you're handling data exports, generating reports, or processing API responses, Spire.XLS provides a consistent and efficient way to work with .json and .xlsx formats in both directions.

Want to unlock all features without limitations? Request a free temporary license for full access to Spire.XLS for Python.

FAQ

Q1: How to convert JSON into Excel using Python?

You can use the json module in Python to load structured JSON data, and then use a library like Spire.XLS to export it to .xlsx. Spire.XLS allows writing headers, formatting Excel cells, and handling nested JSON via flattening. See the JSON to Excel section above for step-by-step examples.

Q2: How do I parse JSON data in Python?

Parsing JSON in Python is straightforward with the built-in json module. Use json.load() to parse JSON from a file, or json.loads() to parse a JSON string. After parsing, the result is usually a list of dictionaries, which can be iterated and exported to Excel or other formats.

Q3: Can I export Excel to JSON with Spire.XLS in Python?

Yes. Spire.XLS for Python lets you read Excel files and convert worksheet data into a list of dictionaries, which can be written to JSON using json.dump(). The process includes extracting headers, detecting used rows and columns, and optionally handling formatting. See Excel to JSON for detailed implementation.

Generate QR Codes Using Python Library

QR codes have transformed how we bridge physical and digital experiences—from marketing campaigns to secure data sharing. For developers looking to generate QR codes in Python , Spire.Barcode for Python provides a complete toolkit for seamless QR code generation, offering both simplicity for basic needs and advanced customization for professional applications.

This step-by-step guide walks you through the entire QR code generation process in Python. You'll learn to programmatically create scannable codes, customize their appearance, embed logos, and optimize error correction - everything needed to implement robust QR code generation solutions for any business or technical requirement.

Table of Contents

  1. Introduction to Spire.Barcode for Python
  2. Setting Up the Environment
  3. Basic Example: Generating QR Codes in Python
  4. Customizing QR Code Appearance
  5. Generating QR Code with Logo
  6. Wrapping up
  7. FAQs

1. Introduction to Spire.Barcode for Python

Spire.Barcode for Python is a powerful library that enables developers to generate and read various barcode types, including QR codes, in Python applications. This robust solution supports multiple barcode symbologies while offering extensive customization options for appearance and functionality.

Key features of Spire.Barcode include:

  • Support for QR Code generation with customizable error correction levels
  • Flexible data encoding options (numeric, alphanumber, byte/binary)
  • Comprehensive appearance customization (colors, sizes, fonts)
  • High-resolution output capabilities
  • Logo integration within QR codes

2. Setting Up the Environment

Before we dive into generating QR codes, you need to set up your Python environment. Ensure you have Python installed, and then install the Spire.Barcode library using pip:

pip install spire.barcode

For the best results, obtain a free temporary license from our website. This will allow you to create professional QR code images without evaluation messages, enhancing both user experience and quality of the generated codes.

3. Basic Example: Generating QR Codes in Python

Now that we have everything set up, let's generate our first QR code. Below is the step-by-step process:

  1. Initial Setup :

    • Import the Spire.Barcode library.
    • Activate the library with a valid license key to remove the
  2. Configure Barcode Settings :

    • Create a BarcodeSettings object to control QR code properties.
    • Set barcode type to QR code.
    • Configure settings such as data mode and error correction level.
    • Define the content to encode.
    • Configure visual aspects like module width and text display options.
  3. Generate Barcode Image :

    • Create a BarCodeGenerator object with the configured settings.
    • Convert the configured QR code into an image object in memory.
  4. Save Image to File :

    • Write the generated QR code image to a specified file path in PNG format.

The following code snippet demonstrates how to generate QR codes in Python:

from spire.barcode import *

# Function to write all bytes to a file
def WriteAllBytes(fname: str, data):
    with open(fname, "wb") as fp:
        fp.write(data)
    fp.close()

# Apply license key for the barcode generation library
License.SetLicenseKey("your license key")

# Create a BarcodeSettings object to configure barcode properties
barcodeSettings = BarcodeSettings()

# Set the type of barcode to QR code
barcodeSettings.Type = BarCodeType.QRCode

# Set the data mode for QR code (automatic detection of data type)
barcodeSettings.QRCodeDataMode = QRCodeDataMode.Auto

# Set the error correction level (M means medium level of error correction)
barcodeSettings.QRCodeECL = QRCodeECL.M

# Set the data that will be encoded in the QR code
barcodeSettings.Data2D = "visit us at www.e-iceblue.com"

# Set the width of each module (the square bars) in the barcode
barcodeSettings.X = 3

# Hide the text that typically accompanies the barcode
barcodeSettings.ShowText = False

# Create a BarCodeGenerator object with the specified settings
barCodeGenerator = BarCodeGenerator(barcodeSettings)

# Generate the image for the barcode based on the settings
image = barCodeGenerator.GenerateImage()

# Write the generated PNG image to disk at the specified path
WriteAllBytes("output/QRCode.png", image)

Key Concepts:

A. QRCodeDataMode (Data Encoding Scheme)

Controls how the input data is encoded in the QR code:

Mode Best For Example Use Cases
Auto Let library detect automatically General purpose (default choice)
Numeric Numbers only (0-9) Product codes, phone numbers
AlphaNumber A-Z, 0-9, and some symbols URLs, simple messages
Byte Binary/Unicode data Complex text, special characters

Why it matters:

  • Different modes have different storage capacities.
  • Numeric mode can store more digits than other modes.
  • Auto mode is safest for mixed content.

B. QRCodeECL (Error Correction Level)

Determines how much redundancy is built into the QR code:

Level Recovery Capacity Use Case
L (Low) 7% damage recovery Small codes, short URLs
M (Medium) 15% damage recovery General purpose (recommended)
Q (Quartile) 25% damage recovery Codes with logos or decorations
H (High) 30% damage recovery Critical applications

Visual Impact:

Higher ECLs:

  • Increase QR code complexity (more modules/squares).
  • Make the code more scannable when damaged.
  • Are essential when adding logos (use at least Q or H).

Output:

A QR code generated by Spire.Barcode for Python

4. Customizing QR Code Appearance

Once you've generated a basic QR code, you can further customize its appearance to make it more visually appealing or to fit your brand. Here are some customization options:

4.1 Adjusting DPI Settings

The DPI (dots per inch) settings control the image quality of the QR code. Higher DPI values result in sharper images suitable for printing, while lower values (72-150) are typically sufficient for digital use.

barcodeSettings.DpiX = 150
barcodeSettings.DpiY = 150

4.2 Changing Foreground and Background Colors

You can customize your QR code’s color scheme. The ForeColor determines the color of the QR code modules (squares), while BackColor sets the background color. Ensure sufficient contrast for reliable scanning.

barcodeSettings.BackColor = Color.get_GhostWhite()
barcodeSettings.ForeColor = Color.get_Purple()

4.3 Displaying the Encoded Data

If you want users to see the encoded information without scanning, set the following properties:

barcodeSettings.ShowTextOnBottom = True
barcodeSettings.TextColor = Color.get_Purple()
barcodeSettings.SetTextFont("Arial", 13, FontStyle.Bold)

4.4 Adding Text Under QR Code

You can also add custom text under the QR code, which could be a call-to-action or instructions.

barcodeSettings.ShowBottomText = True
barcodeSettings.BottomText = "Scan Me"
barcodeSettings.SetBottomTextFont("Arial", 13, FontStyle.Bold)
barcodeSettings.BottomTextColor = Color.get_Black()

4.5 Setting Margins and Border

Defining margins and border styles enhances the presentation of the QR code. Here’s how to do it:

barcodeSettings.LeftMargin = 2
barcodeSettings.RightMargin = 2
barcodeSettings.TopMargin = 2
barcodeSettings.BottomMargin = 2

barcodeSettings.HasBorder = True
barcodeSettings.BorderWidth = 0.5
barcodeSettings.BorderColor = Color.get_Black()

5. Generating QR Code with Logo

For branding purposes, you might want to add a logo to your QR code. Spire.Barcode makes this process seamless while maintaining scannability. Here’s how:

barcodeSettings.SetQRCodeLogoImage("C:\\Users\\Administrator\\Desktop\\logo.png")

When adding a logo:

  • Use a simple, high-contrast logo for best results.
  • Test the scannability after adding the logo.
  • The QR code's error correction (set earlier) helps compensate for the obscured area.

The logo will be centered within the QR code, and Spire.Barcode will automatically resize it to ensure the QR code remains scannable.

Output:

QR code with a logo at the center

6. Wrapping up

Generating QR codes in Python using Spire.Barcode is a straightforward process that offers extensive customization options. From basic QR codes to branded versions with logos and custom styling, the library provides all the tools needed for professional barcode generation.

Key Benefits:

  • Spire.Barcode simplifies QR code generation with a clean API.
  • Extensive customization options allow for branded, visually appealing QR codes.
  • Error correction ensures reliability even with added logos.
  • High-resolution output supports both digital and print use cases.

Whether you're building an inventory system, creating marketing materials, or developing a mobile app integration, Spire.Barcode provides a robust solution for all your QR code generation needs in Python.

7. FAQs

Q1: What is a QR code?

A QR code (Quick Response code) is a type of matrix barcode that can store URLs and other information. It is widely used for quickly linking users to websites, apps, and digital content through mobile devices.

Q2: Can I generate QR codes without a license key?

Yes, you can generate QR codes without a license key; however, the generated barcode will display an evaluation message along with our company logo, which may detract from the user experience.

Q3: Can I generate different types of barcodes with Spire.Barcode?

Yes, Spire.Barcode supports various barcode types, not just QR codes. Detailed documentation can be found here: How to Generate Barcode in Python

Q4: How can I implement a QR code generator in Python using Spire.Barcode?

To implement a QR code generator in Python with Spire.Barcode, create a BarcodeSettings object to configure the QR code properties. Then, use the BarCodeGenerator class to generate the QR code image by calling the GenerateImage() method.

Q5: Can I scan or read QR code using Spire.Barcode?

Yes, you can scan and read QR codes using Spire.Barcode for Python. The library provides functionality for both generating and decoding QR codes. Follow this guide: How to Read Barcode Using Python

Get a Free License

To fully experience the capabilities of Spire.Barcode for Python without any evaluation limitations, you can request a free 30-day trial license.

Illustration showing Python code adding text to a PDF file

Adding text to a PDF is a common task in Python — whether you're generating reports, adding annotations, filling templates, or labeling documents. This guide will walk you through how to write text in a PDF file using Python, including both creating new PDF documents and updating existing ones.

We’ll be using a dedicated Python PDF library - Spire.PDF for Python, which allows precise control over text placement, font styling, and batch processing. The examples are concise, beginner-friendly, and ready for real-world projects.

Sections Covered

  1. Setup: Install the PDF Library in Python
  2. Add Text to a New PDF
  3. Add Text to an Existing PDF
  4. Control Text Style, Position, Transparency, and Rotation
  5. Common Pitfalls and Cross-Platform Tips
  6. Conclusion
  7. FAQ

Setup: Install the PDF Library in Python

To get started, install Spire.PDF for Python, a flexible and cross-platform PDF library.

pip install Spire.PDF

Or use Free Spire.PDF for Python:

pip install spire.pdf.free

Why use this library?

  • Works without Adobe Acrobat or Microsoft Office
  • Add and format text at exact positions
  • Supports both new and existing PDF editing
  • Runs on Windows, macOS, and Linux

Add Text to a New PDF Using Python

If you want to create a PDF from text using Python, the example below shows how to insert a line of text into a blank PDF page using custom font and position settings.

Example: Create and write text to a blank PDF

from spire.pdf import PdfDocument, PdfTrueTypeFont, PdfFontStyle, PdfSolidBrush, PdfRGBColor, PointF, RectangleF, \
    PdfStringFormat, PdfTextAlignment, PdfVerticalAlignment

# Create a new PDF document and add a new page
pdf = PdfDocument()
page = pdf.Pages.Add()

text = ("This report summarizes the sales performance of various products in the first quarter of 2025. " +
        "Below is a breakdown of the total sales by product category, " +
        "followed by a comparison of sales in different regions.")

# Set the font, brush, and point
font = PdfTrueTypeFont("Arial", 14.0, PdfFontStyle.Regular, True)
brush = PdfSolidBrush(PdfRGBColor(0, 0, 0))  # black
point = PointF(50.0, 100.0)

# Set the layout area and string format
layoutArea = RectangleF(50.0, 50.0, page.GetClientSize().Width - 100.0, page.GetClientSize().Height)
stringFormat = PdfStringFormat(PdfTextAlignment.Left, PdfVerticalAlignment.Top)

page.Canvas.DrawString(text, font, brush, layoutArea, stringFormat, False)

pdf.SaveToFile("output/new.pdf")
pdf.Close()

Technical Notes

  • PdfTrueTypeFont() loads a TrueType font from the system with customizable size and style (e.g., regular, bold). It ensures consistent text rendering in the PDF.
  • PdfSolidBrush() defines the fill color for text or shapes using RGB values. In this example, it's set to black ((0, 0, 0)).
  • RectangleF(x, y, width, height) specifies a rectangular layout area for drawing text. It enables automatic line wrapping and precise control of text boundaries.
  • PdfStringFormat() controls the alignment of the text inside the rectangle. Here, text is aligned to the top-left (Left and Top).
  • DrawString() draws the specified text within the defined layout area without affecting existing content on the page.

Example output PDF showing wrapped black text starting at coordinates (50, 50).

Generated PDF showing wrapped black text block starting at position (50, 50)

Tip: To display multiple paragraphs or line breaks, consider adjusting the Y-coordinate dynamically or using multiple DrawString() calls with updated positions.

If you want to learn how to convert TXT files to PDF directly using Python, please check: How to Convert Text Files to PDF Using Python.


Add Text to an Existing PDF in Python

Need to add text to an existing PDF using Python? This method lets you load a PDF, access a page, and write new text anywhere on the canvas.

This is helpful for:

  • Adding comments or annotations
  • Labeling document versions
  • Filling pre-designed templates

Example: Open an existing PDF and insert text

from spire.pdf import PdfDocument, PdfFontStyle, PdfSolidBrush, PdfRGBColor, PointF, PdfFont, PdfFontFamily

pdf = PdfDocument()
pdf.LoadFromFile("input.pdf")
page = pdf.Pages[0]

font = PdfFont(PdfFontFamily.TimesRoman, 12.0, PdfFontStyle.Bold)
brush = PdfSolidBrush(PdfRGBColor(255, 0, 0))  # red
location = PointF(150.0, 110.0)

page.Canvas.DrawString("This document is approved.", font, brush, location)

pdf.SaveToFile("output/modified.pdf")
pdf.Close()

Technical Notes

  • LoadFromFile() loads an existing PDF into memory.
  • You can access specific pages via pdf.Pages[index].
  • New content is drawn on top of the existing layout, non-destructively.
  • The text position is again controlled via PointF(x, y).

Modified PDF page with newly added red text annotation on the first page.

Modified PDF with added red text label on the first page

Use different x, y coordinates to insert content at custom positions.

Related article: Replace Text in PDF with Python


Control Text Style, Positioning, Transparency, and Rotation

When adding text to a PDF, you often need more than just plain content—you may want to customize the font, color, placement, rotation, and transparency, especially for annotations or watermarks.

Spire.PDF for Python offers fine-grained control for these visual elements, whether you’re building structured reports or stamping dynamic text overlays.

Set Font Style and Color

# Create PdfTrueTypeFont
font = PdfTrueTypeFont("Calibri", 16.0, PdfFontStyle.Italic, True)

# Create PdfFont
font = PdfFont(PdfFontFamily.TimesRoman, 16.0, PdfFontStyle.Italic)

# Create PdfBrush to specify text drawing color
brush = PdfSolidBrush(PdfRGBColor(34, 139, 34))  # forest green

PdfTrueTypeFont will embed the font into the PDF file. To reduce file size, you may use PdfFont, which uses system fonts without embedding them.

Apply Transparency and Rotation

You can adjust transparency and rotation when drawing text to achieve effects like watermarks or angled labels.

# Save the current canvas state
state = page.Canvas.Save()

# Set semi-transparency (0.0 = fully transparent, 1.0 = fully opaque)
page.Canvas.SetTransparency(0.4)

# Move the origin to the center of the page
page.Canvas.TranslateTransform(page.Size.Width / 2, page.Size.Height / 2)

# Rotate the canvas -45 degrees (counterclockwise)
page.Canvas.RotateTransform(-45)

# Draw text at new origin
page.Canvas.DrawString("DRAFT", font, brush, PointF(-50, -20))

Example: Add a Diagonal Watermark to the Center of the Page

The following example demonstrates how to draw a centered, rotated, semi-transparent watermark using all the style controls above:

from spire.pdf import PdfDocument, PdfTrueTypeFont, PdfFontStyle, PdfSolidBrush, PdfRGBColor, PointF
from spire.pdf.common import Color

pdf = PdfDocument()
pdf.LoadFromFile("input1.pdf")
page = pdf.Pages[0]

text = "Confidential"
font = PdfTrueTypeFont("Arial", 40.0, PdfFontStyle.Bold, True)
brush = PdfSolidBrush(PdfRGBColor(Color.get_DarkBlue()))  # gray

# Measure text size to calculate center
size = font.MeasureString(text)
x = (page.Canvas.ClientSize.Width - size.Width) / 2
y = (page.Canvas.ClientSize.Height - size.Height) / 2

state = page.Canvas.Save()
page.Canvas.SetTransparency(0.3)
page.Canvas.TranslateTransform(x + size.Width / 2, y + size.Height / 2)
page.Canvas.RotateTransform(-45.0)
page.Canvas.DrawString(text, font, brush, PointF(-size.Width / 2, -size.Height / 2))
page.Canvas.Restore(state)

pdf.SaveToFile("output/with_watermark.pdf")
pdf.Close()

PDF page displaying a centered, rotated, semi-transparent watermark text.

Screenshot showing several PDF files with uniform footer text added programmatically

This approach works well for dynamic watermarking, diagonal stamps like "VOID", "COPY", or "ARCHIVED", and supports full automation.

Make sure all files are closed and not in use to avoid PermissionError.

For more details on inserting watermarks into PDF with Python, please refer to: How to Insert Text Watermarks into PDFs Using Python.


Common Pitfalls and Cross-Platform Considerations

Even with the right API, issues can arise when deploying PDF text operations across different environments or font configurations. Here are some common problems and how to resolve them:

Issue Cause Recommended Fix
Text appears in wrong position Hardcoded coordinates not accounting for page size Use ClientSize and MeasureString() for dynamic layout
Font not rendered Font lacks glyphs or isn't supported Use PdfTrueTypeFont to embed supported fonts like Arial Unicode
Unicode text not displayed Font does not support full Unicode range Use universal fonts (e.g., Arial Unicode, Noto Sans)
Text overlaps existing content Positioning too close to body text Adjust Y-offsets or add padding with MeasureString()
Watermark text appears on output You are using the paid version without a license Use the free version or apply for a temporary license
Font file too large Embedded font increases PDF size Use PdfFont for system fonts (non-embedded), if portability is not a concern
Inconsistent results on macOS/Linux Fonts not available or different metrics Ship fonts with your application, or use built-in cross-platform fonts

Conclusion

With Spire.PDF for Python, adding text to PDFs—whether creating new files, updating existing ones, or automating batch edits—can be done easily and precisely. From annotations to watermarks, the library gives you full control over layout and styling.

You can start with the free version right away, or apply for a temporary license to unlock full features.


FAQ

How to add text to a PDF using Python?

Use a PDF library such as Spire.PDF to insert text via the DrawString() method. You can define font, position, and styling.

Can I write text into an existing PDF file with Python?

Yes. Load the file with LoadFromFile(), then use DrawString() to add text at a specific location.

How do I generate a PDF from text using Python?

Create a new document and use drawing methods to write content line by line with precise positioning.

Can I add the same text to many PDFs automatically?

Yes. Use a loop to process multiple files and insert text programmatically using a template script.

Page 8 of 329
page 8