用Rust生成PDF文件的方法有哪些
最近在做一个Rust项目,需要生成PDF文件,但不太清楚有哪些可用的库或方法。想请教大家:
- Rust生态中有哪些成熟的PDF生成库?
- 这些库各自有什么优缺点?比如性能、功能完整性、易用性等方面
- 是否有推荐的最佳实践或示例代码?
- 如果需要支持中文等特殊字符,哪些库比较合适?
- 除了专门的PDF库,是否可以通过其他方式(如HTML转PDF)来实现?
希望能得到一些实际使用经验分享,谢谢!
2 回复
在Rust中生成PDF的常用方法:
- printpdf - 最流行的库,支持文本、图像、矢量图形
use printpdf::*;
// 创建文档、页面、图层
// 添加文本和图形
- lopdf - 底层PDF操作库
- 直接操作PDF对象
- 适合需要精细控制的场景
- pdf-writer - 纯写入库
- 无依赖,轻量级
- 只生成不解析
- wkhtmltopdf的Rust绑定
- 通过HTML转PDF
- 适合已有HTML内容的情况
- 组合方案
- 先用其他库生成内容
- 再用PDF库输出
建议:
- 新手用printpdf,文档完善
- 需要高性能用lopdf
- 从HTML转换用wkhtmltopdf
记得在Cargo.toml添加相应依赖,根据需求选择合适的库。
在Rust中生成PDF文件,主要有以下几种方法:
1. printpdf 库(推荐)
最流行的Rust PDF生成库,功能完善:
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
fn create_pdf() -> Result<(), Box<dyn std::error::Error>> {
let (doc, page1, layer1) = PdfDocument::new("PDF_Document_title", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
// 添加文本
let font = doc.add_builtin_font(BuiltinFont::Helvetica)?;
current_layer.use_text("Hello PDF!", 48.0, Mm(20.0), Mm(270.0), &font);
// 添加图形
current_layer.set_outline_color(Color::Rgb(Rgb::new(1.0, 0.0, 0.0, None)));
current_layer.set_line_width(2.0);
current_layer.add_line(Mm(50.0), Mm(50.0), Mm(150.0), Mm(150.0));
doc.save(&mut BufWriter::new(File::create("test.pdf")?))?;
Ok(())
}
2. lopdf 库
轻量级PDF处理库,支持生成和修改:
use lopdf::{Document, Object, ObjectId};
use std::collections::BTreeMap;
fn create_lopdf_pdf() -> Result<(), Box<dyn std::error::Error>> {
let mut doc = Document::with_version("1.5");
// 创建页面
let pages_id = doc.new_object_id();
let font_id = doc.add_object(dictionary! {
"Type" => "Font",
"Subtype" => "Type1",
"BaseFont" => "Helvetica",
});
let content = "BT /F1 24 Tf 100 700 Td (Hello World) Tj ET";
let content_id = doc.add_object(content.as_bytes().to_vec());
let page_id = doc.add_object(dictionary! {
"Type" => "Page",
"Parent" => pages_id,
"Contents" => content_id,
"Resources" => dictionary! {
"Font" => dictionary! {
"F1" => font_id,
},
},
"MediaBox" => vec![0.into(), 0.into(), 595.into(), 842.into()],
});
doc.save("test_lopdf.pdf")?;
Ok(())
}
3. pdf-writer 库
专注于PDF生成的底层库:
use pdf_writer::{Content, Finish, Name, Pdf, Rect, Ref, Str};
fn create_pdf_writer() -> Result<(), Box<dyn std::error::Error>> {
let mut pdf = Pdf::new();
let catalog_id = Ref::new(1);
let page_tree_id = Ref::new(2);
let page_id = Ref::new(3);
let content_id = Ref::new(4);
let font_id = Ref::new(5);
pdf.catalog(catalog_id)
.pages(page_tree_id)
.finish();
pdf.pages(page_tree_id)
.kids([page_id])
.count(1)
.finish();
pdf.page(page_id)
.parent(page_tree_id)
.contents(content_id)
.media_box(Rect::new(0.0, 0.0, 595.0, 842.0))
.resources()
.fonts()
.pair(Name(b"F1"), font_id)
.finish()
.finish();
// 写入内容流
let mut content = Content::new();
content.begin_text();
content.set_font(Name(b"F1"), 24.0);
content.next_line(100.0, 700.0);
content.show(Str(b"Hello PDF Writer"));
content.end_text();
pdf.stream(content_id, &content.finish());
pdf.font(font_id)
.type_(Name(b"Font"))
.subtype(Name(b"Type1"))
.base_font(Name(b"Helvetica"))
.finish();
std::fs::write("test_pdf_writer.pdf", pdf.finish())?;
Ok(())
}
4. 其他选择
- rust-pdf:另一个PDF生成库
- wkhtmltopdf:通过调用外部工具转换HTML为PDF
- WeasyPrint:类似wkhtmltopdf的替代方案
选择建议
- printpdf:适合大多数应用场景,API友好
- lopdf:需要同时读写PDF文件时使用
- pdf-writer:对性能要求高或需要精细控制时使用
在Cargo.toml中添加相应依赖即可开始使用这些库。

