A Rust library for PDF document manipulation.
```rust
extern crate lopdf; use lopdf::{Document, Object, Stream}; use lopdf::content::{Content, Operation};
let mut doc = Document::withversion("1.5"); let pagesid = doc.newobjectid(); let fontid = doc.addobject(dictionary! { "Type" => "Font", "Subtype" => "Type1", "BaseFont" => "Courier", }); let resourcesid = doc.addobject(dictionary! { "Font" => dictionary! { "F1" => fontid, }, }); let content = Content { operations: vec![ Operation::new("BT", vec![]), Operation::new("Tf", vec!["F1".into(), 48.into()]), Operation::new("Td", vec![100.into(), 600.into()]), Operation::new("Tj", vec![Object::stringliteral("Hello World!")]), Operation::new("ET", vec![]), ], }; let contentid = doc.addobject(Stream::new(dictionary! {}, content.encode().unwrap())); let pageid = doc.addobject(dictionary! { "Type" => "Page", "Parent" => pagesid, "Contents" => contentid, }); let pages = dictionary! { "Type" => "Pages", "Kids" => vec![pageid.into()], "Count" => 1, "Resources" => resourcesid, "MediaBox" => vec![0.into(), 0.into(), 595.into(), 842.into()], }; doc.objects.insert(pagesid, Object::Dictionary(pages)); let catalogid = doc.addobject(dictionary! { "Type" => "Catalog", "Pages" => pagesid, }); doc.trailer.set("Root", catalog_id); doc.compress(); doc.save("example.pdf").unwrap(); ```
rust
let mut doc = Document::load("example.pdf")?;
doc.version = "1.4".to_string();
doc.replace_text(1, "Hello World!", "Modified text!");
doc.save("modified.pdf")?;
Why keeping everything in memory as high-level objects until finally serializing the entire document?
Normally a PDF document won't be very large, ranging form tens of KB to hundreds of MB. Memory size is not a bottle neck for today's computer. By keep the whole document in memory, stream length can be pre-calculated, no need to use a reference object for the Length entry, the resulting PDF file is smaller for distribution and faster for PDF consumers to process.
Producing is a one-time effort, while consuming is many more.