A complete project report often includes more than the PDF itself. It may also come with Excel spreadsheets used for calculations, original images, or supplementary notes. When these files are sent separately, recipients have to download and organize them individually—and may overlook a file along the way.
PDF attachments offer another way to organize these materials: embed supporting files directly in the PDF so the main document and related resources can be delivered together. For example, you can attach a source workbook to a financial report, sample files to a product manual, or supplementary materials to a contract.
This article explains how to use Spire.PDF for Python to perform two tasks: add attachments to a PDF and extract attachments from a PDF.
Think of a PDF with attachments as a document with its own built-in folder: the pages display the main content, while the attachments hold the supporting files.
Embedding a file this way differs from inserting an image or adding a hyperlink:
| Operation | How the file is stored in the PDF | What readers see |
|---|---|---|
| Insert an image into a page | The image becomes part of the page content | The image is visible when the page is opened |
| Add a file hyperlink | Usually, only the destination URL or path is stored | Clicking the link opens the destination |
| Add an attachment | The file itself is embedded in the PDF | The file can be viewed or saved using a reader that supports attachments |
Therefore, attaching an Excel file to a PDF does not convert its worksheets into PDF pages . After extracting the attachment, recipients can still open and edit the original workbook in Excel.
Attachment support varies between PDF readers. To access attachments, use a desktop reader with an attachments panel, such as Adobe Acrobat. Some browser-based PDF viewers may not provide an option to access embedded files.
Spire.PDF for Python is a library for creating and processing PDF documents. This article uses its attachment APIs to work directly with files stored inside a PDF, without manually opening a reader to add or export them.
First, install the library:
pip install Spire.PDF
Import the required modules in your code:
from spire.pdf import *
from spire.pdf.common import *
The following examples demonstrate how to add and extract attachments. Before running them, replace the file paths with the actual paths on your computer.
Suppose you have a PDF report and want to deliver its source data, Report.xlsx, and a supporting image, Logo.png, together. Embedding them as attachments allows recipients to keep the main document and both supporting files in a single PDF.
The process consists of four steps:
from spire.pdf import *
from spire.pdf.common import *
doc = PdfDocument()
doc.LoadFromFile("Input.pdf")
attachment_one = PdfAttachment("Report.xlsx")
attachment_two = PdfAttachment("Logo.png")
doc.Attachments.Add(attachment_one)
doc.Attachments.Add(attachment_two)
doc.SaveToFile("Attachments.pdf")
doc.Close()
PdfAttachment("Report.xlsx") creates an attachment object from the specified file. Calling doc.Attachments.Add() then adds it to the current PDF. To attach more files, create additional attachment objects and add them to the collection.
Attachments do not take up page space or change the layout of the main content. When you open the saved Attachments.pdf, its pages may look exactly like those in the original document. However, a reader that supports attachments will list the embedded files in its “Attachments” or “Attached Files” panel.
This example uses different input and output filenames, so the original Input.pdf is preserved, while the version containing attachments is saved as Attachments.pdf.
File size is another consideration. Attachments contain the actual file data, so large workbooks or high-resolution images may significantly increase the PDF’s size. If you plan to send the PDF by email or upload it to a system, check the file size limits of that delivery channel.
After receiving a PDF with attachments, you may need to edit an embedded workbook, organize supporting images, or pass the files to another program. You can extract the attachments as separate files for these purposes.
Extracting attachments does not require parsing PDF pages or performing OCR. The program reads the document’s attachment collection directly and writes the stored file data to disk.
The process is as follows:
Before running the code, create the Output\ExtractedFiles folder.
from spire.pdf import *
from spire.pdf.common import *
doc = PdfDocument()
doc.LoadFromFile("Attachments.pdf")
collection = doc.Attachments
if collection.Count > 0:
for i in range(collection.Count):
attachment = collection.get_Item(i)
fileName = attachment.FileName
data = attachment.Data
data.Save("Output\\ExtractedFiles\\" + fileName)
doc.Close()
doc.Attachments returns the document’s attachment collection, and collection.Count indicates how many attachments it contains. If there are no attachments, the example skips the save operation.
During iteration, get_Item(i) retrieves an attachment by index, FileName provides its filename, and Data.Save(path) writes its data to the specified location.
For the PDF created in the previous example, the output directory will contain Report.xlsx and Logo.png after extraction. You can open these files in their respective applications without accessing them through a PDF reader.
First, check the output directory. The example assumes that Output\ExtractedFiles already exists. In an actual project, you can use Python’s os.makedirs() to create the directory automatically before extraction.
Next, handle duplicate filenames. Different PDFs may contain attachments named Report.xlsx. Saving them all to the same folder could cause files to be overwritten. When extracting attachments in batches, create a separate subfolder for each PDF. For attachments with identical names within the same PDF, you can add an index to the beginning of each filename.
Also, sanitize filenames before saving. When processing PDFs from external sources, use os.path.basename() to obtain the filename portion of an attachment’s name, then combine it with the target directory. This avoids using path information from the attachment name directly as the save location.
Q1. Why do the PDF pages look the same after adding attachments?
Attachments are stored inside the document and are not part of the content displayed on its pages. Use a reader that supports attachments and check its attachments panel.
Q2. Do I still need to send the original files after attaching them?
Once the attachments have been saved inside the PDF, recipients can extract them from it. Before delivery, however, open the output PDF and confirm that all the required files have been added.
Q3. Is extracting attachments the same as extracting images from a PDF?
No. Extracting attachments retrieves independent files embedded in the PDF. Extracting page images retrieves image resources used by the pages. An image displayed on a PDF page does not necessarily belong to the attachment collection.
Q4. Can I process multiple PDFs in batches?
Yes. Place the processing logic for a single PDF inside a loop that iterates through the input files. For batch extraction, create separate output directories based on the PDF filenames to help track the source of each attachment and reduce filename conflicts.
PDF attachments provide a practical way to keep the main document and its supporting materials together. The pages retain their readable layout, while original workbooks, images, and supplementary files travel with the document.
With Spire.PDF for Python, you can add attachments using PdfAttachment and doc.Attachments.Add(), or iterate through doc.Attachments to save existing attachments as separate files. In practical use, pay attention to reader compatibility, file size, and the handling of output directories and filenames during extraction.