How-to guides/Attachments

Embed a file attachment inside a PDF in Rust

Attach any file (XML, CSV, XLSX, images) as an embedded file stream inside a PDF. The attachment travels with the document and can be extracted by any conforming viewer.

rust
use pdfluent::{PdfDocument, FileAttachment};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut doc = PdfDocument::open("invoice.pdf")?;

    doc.attach_file(
        FileAttachment::from_file("invoice_data.xml")?
            .description("Machine-readable invoice data (ZUGFeRD)")
            .mime_type("application/xml"),
    )?;

    doc.save("invoice_with_attachment.pdf")?;
    println!("File attached.");
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Add PDFluent to your project

Add the pdfluent crate to Cargo.toml.

rust
[dependencies]
pdfluent = "0.9"
2

Open the PDF

Load the document that will receive the attachment.

rust
use pdfluent::PdfDocument;

let mut doc = PdfDocument::open("invoice.pdf")?;
3

Build the FileAttachment from a file on disk

FileAttachment::from_file() reads the file bytes, determines a filename, and sets a creation date. All fields can be overridden.

rust
use pdfluent::FileAttachment;

let attachment = FileAttachment::from_file("supporting_data.csv")?
    .description("Raw data used to generate the figures in this report")
    .mime_type("text/csv")
    .filename("data.csv");
4

Attach from in-memory bytes

If the file content is already in memory, use FileAttachment::from_bytes() instead.

rust
let xml_bytes = generate_xml_data(); // your function
let attachment = FileAttachment::from_bytes(xml_bytes)
    .filename("invoice.xml")
    .mime_type("application/xml")
    .description("ZUGFeRD structured invoice data");
5

Add the attachment to the document and save

attach_file() embeds the file in the document-level EmbeddedFiles name tree. Save afterwards.

rust
doc.attach_file(attachment)?;

// Verify
println!("Attached files: {}", doc.attachments().len());

doc.save("invoice_with_attachment.pdf")?;

Notes and tips

  • Attached files are stored as EmbeddedFile streams in the PDF. They are not visible on any page unless you also add a FileAttachment annotation.
  • MIME type is optional but recommended. PDF/A-3 requires it for embedded files.
  • Multiple files can be attached. Call attach_file() once per file.
  • Attached file size adds directly to the PDF file size. Compress large attachments before embedding.

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions