Skip to main content

PdfWriter

Struct PdfWriter 

Source
pub struct PdfWriter<W: Write> { /* private fields */ }

Implementations§

Source§

impl<W: Write> PdfWriter<W>

Source

pub fn new_with_writer(writer: W) -> Self

Source

pub fn with_config(writer: W, config: WriterConfig) -> Self

Source

pub fn write_document(&mut self, document: &mut Document) -> Result<()>

Source

pub fn write_incremental_update( &mut self, base_pdf_path: impl AsRef<Path>, document: &mut Document, ) -> Result<()>

Write an incremental update to an existing PDF (ISO 32000-1 §7.5.6)

This appends new/modified objects to the end of an existing PDF file without modifying the original content. The base PDF is copied first, then new pages are ADDED to the end of the document.

For REPLACING specific pages (e.g., form filling), use write_incremental_with_page_replacement.

§Arguments
  • base_pdf_path - Path to the existing PDF file
  • document - Document containing NEW pages to add
§Returns

Returns Ok(()) if the incremental update was written successfully

§Example - Adding Pages
use oxidize_pdf::{Document, Page, writer::{PdfWriter, WriterConfig}};
use std::fs::File;
use std::io::BufWriter;

let mut doc = Document::new();
doc.add_page(Page::a4()); // This will be added as a NEW page

let file = File::create("output.pdf").unwrap();
let writer = BufWriter::new(file);
let config = WriterConfig::incremental();
let mut pdf_writer = PdfWriter::with_config(writer, config);
pdf_writer.write_incremental_update("base.pdf", &mut doc).unwrap();
Source

pub fn write_incremental_with_page_replacement( &mut self, base_pdf_path: impl AsRef<Path>, document: &mut Document, ) -> Result<()>

Replaces pages in an existing PDF using incremental update structure (ISO 32000-1 §7.5.6).

§Use Cases

This API is ideal for:

  • Dynamic page generation: You have logic to generate complete pages from data
  • Template variants: Switching between multiple pre-generated page versions
  • Page repair: Regenerating corrupted or problematic pages from scratch
§Manual Content Recreation Required

IMPORTANT: This API requires you to manually recreate the entire page content. The replaced page will contain ONLY what you provide in document.pages.

If you need to modify existing content (e.g., fill form fields on an existing page), you must recreate the base content AND add your modifications.

§Example: Form Filling with Manual Recreation
use oxidize_pdf::{Document, Page, text::Font, writer::{PdfWriter, WriterConfig}};
use std::fs::File;
use std::io::BufWriter;

let mut filled_doc = Document::new();
let mut page = Page::a4();

// Step 1: Recreate the template content (REQUIRED - you must know this)
page.text()
    .set_font(Font::Helvetica, 12.0)
    .at(50.0, 700.0)
    .write("Name: _______________________________")?;

// Step 2: Add your filled data at the appropriate position
page.text()
    .set_font(Font::Helvetica, 12.0)
    .at(110.0, 700.0)
    .write("John Smith")?;

filled_doc.add_page(page);

let file = File::create("filled.pdf")?;
let writer = BufWriter::new(file);
let mut pdf_writer = PdfWriter::with_config(writer, WriterConfig::incremental());

pdf_writer.write_incremental_with_page_replacement("template.pdf", &mut filled_doc)?;
§ISO Compliance

This function implements ISO 32000-1 §7.5.6 incremental updates:

  • Preserves original PDF bytes (append-only)
  • Uses /Prev pointer in trailer
  • Maintains cross-reference chain
  • Compatible with digital signatures on base PDF
§Future: Automatic Overlay API

For automatic form filling (load + modify + save) without manual recreation, a future write_incremental_with_overlay() API is planned. This will require implementation of Document::load() and content overlay system.

§Parameters
  • base_pdf_path: Path to the existing PDF to modify
  • document: Document containing replacement pages (first N pages will replace base pages 0..N-1)
§Returns
  • Ok(()) if incremental update was written successfully
  • Err(PdfError) if base PDF cannot be read, parsed, or structure is invalid
Source

pub fn write_incremental_with_overlay<P: AsRef<Path>>( &mut self, base_pdf_path: P, overlay_fn: impl FnMut(&mut Page) -> Result<()>, ) -> Result<()>

Overlays content onto existing PDF pages using incremental updates (PLANNED).

STATUS: Not yet implemented. This API is planned for a future release.

§What This Will Do

When implemented, this function will allow you to:

  • Load an existing PDF
  • Modify specific elements (fill form fields, add annotations, watermarks)
  • Save incrementally without recreating entire pages
§Difference from Page Replacement
  • Page Replacement (write_incremental_with_page_replacement): Replaces entire pages with manually recreated content
  • Overlay (this function): Modifies existing pages by adding/changing specific elements
§Planned Usage (Future)
// This code will work in a future release
let mut pdf_writer = PdfWriter::with_config(writer, WriterConfig::incremental());

let overlays = vec![
    PageOverlay::new(0)
        .add_text(110.0, 700.0, "John Smith")
        .add_annotation(Annotation::text(200.0, 500.0, "Review this")),
];

pdf_writer.write_incremental_with_overlay("form.pdf", overlays)?;
§Implementation Requirements

This function requires:

  1. Document::load() - Load existing PDF into Document structure
  2. Page::from_parsed() - Convert parsed pages to writable format
  3. Content stream overlay system - Append to existing content streams
  4. Resource merging - Combine new resources with existing ones

Estimated implementation effort: 6-7 days

§Current Workaround

Until this is implemented, use write_incremental_with_page_replacement() with manual page recreation. See that function’s documentation for examples.

§Parameters
  • base_pdf_path: Path to the existing PDF to modify (future)
  • overlays: Content to overlay on existing pages (future)
§Returns

Currently always returns PdfError::NotImplemented

Source§

impl PdfWriter<BufWriter<File>>

Source

pub fn new(path: impl AsRef<Path>) -> Result<Self>

Auto Trait Implementations§

§

impl<W> Freeze for PdfWriter<W>
where W: Freeze,

§

impl<W> RefUnwindSafe for PdfWriter<W>
where W: RefUnwindSafe,

§

impl<W> Send for PdfWriter<W>
where W: Send,

§

impl<W> Sync for PdfWriter<W>
where W: Sync,

§

impl<W> Unpin for PdfWriter<W>
where W: Unpin,

§

impl<W> UnwindSafe for PdfWriter<W>
where W: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more