Unire PDF in Rust con lopdf
lopdf è una libreria per Rust che ci consente di manipolare file PDF.
In questo articolo vediamo come unire più PDF.
Possiamo installare la libreria con cargo:
cargo add lopdf
Qui sotto un esempio di codice completo:
use std::collections::BTreeMap;
use lopdf::{Document, Object, ObjectId};
fn main() {
let docs = vec![
Document::load("prova1.pdf").unwrap(),
Document::load("prova2.pdf").unwrap(),
Document::load("prova3.pdf").unwrap(),
];
let mut max_id = 1;
let mut documents_pages = BTreeMap::new();
let mut documents_objects = BTreeMap::new();
for mut document in docs {
document.renumber_objects_with(max_id);
max_id = document.max_id + 1;
documents_pages.extend(
document
.get_pages()
.into_iter()
.map(|(_, object_id)| {
(
object_id,
document.get_object(object_id).unwrap().to_owned(),
)
})
.collect::<BTreeMap<ObjectId, Object>>(),
);
documents_objects.extend(document.objects);
}
let mut document = Document::with_version("1.5");
let mut catalog_object: Option<(ObjectId, Object)> = None;
let mut pages_object: Option<(ObjectId, Object)> = None;
for (object_id, object) in documents_objects.iter() {
match object.type_name().unwrap_or("") {
"Catalog" => {
catalog_object = Some((
if let Some((id, _)) = catalog_object {
id
} else {
*object_id
},
object.clone(),
));
}
"Pages" => {
if let Ok(dictionary) = object.as_dict() {
let mut dictionary = dictionary.clone();
if let Some((_, ref object)) = pages_object {
if let Ok(old_dictionary) = object.as_dict() {
dictionary.extend(old_dictionary);
}
}
pages_object = Some((
if let Some((id, _)) = pages_object {
id
} else {
*object_id
},
Object::Dictionary(dictionary),
));
}
}
"Page" => {}
"Outlines" => {}
"Outline" => {}
_ => {
document.objects.insert(*object_id, object.clone());
}
}
}
if pages_object.is_none() {
println!("Nessuna pagina trovata!");
return;
}
for (object_id, object) in documents_pages.iter() {
if let Ok(dictionary) = object.as_dict() {
let mut dictionary = dictionary.clone();
dictionary.set("Parent", pages_object.as_ref().unwrap().0);
document
.objects
.insert(*object_id, Object::Dictionary(dictionary));
}
}
if catalog_object.is_none() {
println!("Nessun catalogo trovato!");
return;
}
let catalog_object = catalog_object.unwrap();
let pages_object = pages_object.unwrap();
if let Ok(dictionary) = pages_object.1.as_dict() {
let mut dictionary = dictionary.clone();
dictionary.set("Count", documents_pages.len() as u32);
dictionary.set(
"Kids",
documents_pages
.into_iter()
.map(|(object_id, _)| Object::Reference(object_id))
.collect::<Vec<_>>(),
);
document
.objects
.insert(pages_object.0, Object::Dictionary(dictionary));
}
if let Ok(dictionary) = catalog_object.1.as_dict() {
let mut dictionary = dictionary.clone();
dictionary.set("Pages", pages_object.0);
dictionary.remove(b"Outlines");
document
.objects
.insert(catalog_object.0, Object::Dictionary(dictionary));
}
document.trailer.set("Root", catalog_object.0);
document.max_id = document.objects.len() as u32;
document.renumber_objects();
document.compress();
document.save("merged.pdf").unwrap();
}
Enjoy!
rust cargo lopdf pdf
Commentami!