Rust PDF生成库printpdf的使用:高效创建、编辑和操作PDF文档的Rust解决方案
Rust PDF生成库printpdf的使用:高效创建、编辑和操作PDF文档的Rust解决方案
printpdf是一个用于生成、读取、渲染和优化PDF文档的Rust库。
特性
- 页面、书签、链接注释(读写)
- 图层(读写)
- 图形:线条、形状、贝塞尔曲线、SVG内容(读写)
- 图像编码/解码(读取支持:实验性/写入支持需
image
) - 嵌入式字体、Unicode支持(读取支持:实验性/写入)
- 最小化文件大小(自动子集化字体)
- 将PDF页面渲染为SVG文件:实验性
- 从PDF页面提取文本(自动解码Unicode、换行符、文本位置:实验性)
- 简单页面布局的基本HTML排版(使用
azul-layout
+kuchiki
HTML解析器) - 高级图形 - 套印、混合等
- 高级排版 - 字符/单词缩放和间距、上标、下标等
- 嵌入SVG(内部使用
svg2pdf
库)
不支持的功能包括:
- 渐变
- 图案
- 文件附件
- 开放印前接口
- 图像半色调
- 各种PDF标准的符合性/错误检查
- 嵌入式JavaScript
基本示例
use printpdf::*;
fn main() {
let mut doc = PdfDocument::new("My first PDF");
let page1_contents = vec![Op::Marker { id: "debugging-marker".to_string() }];
let page1 = PdfPage::new(Mm(10.0), Mm(250.0), page1_contents);
let pdf_bytes: Vec<u8> = doc
.with_pages(vec![page1])
.save(&PdfSaveOptions::default());
}
完整示例代码
use printpdf::*;
fn main() {
// 创建新PDF文档
let mut doc = PdfDocument::new("My PDF Document");
// 添加页面
let page1 = PdfPage::new(Mm(210.0), Mm(297.0), vec![]); // A4尺寸
// 添加图形
let line = Line {
points: vec![
(Point::new(Mm(50.0), Mm(50.0)), false),
(Point::new(Mm(50.0), Mm(100.0)), false),
(Point::new(Mm(100.0), Mm(100.0)), false),
(Point::new(Mm(100.0), Mm(50.0)), false),
],
is_closed: true,
};
// 添加文本
let font_bytes = include_bytes!("Roboto-Regular.ttf");
let font = ParsedFont::from_bytes(font_bytes, 0, &mut Vec::new()).unwrap();
let font_id = doc.add_font(&font);
// 页面内容操作
let page_contents = vec![
// 绘制图形
Op::SetOutlineColor { col: Color::Rgb(Rgb::new极好的!下面我将整理一个综合性的printpdf完整示例,结合了文本、图形、图片和页面布局功能:
```rust
use printpdf::*;
use std::fs::File;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建新PDF文档
let (doc, page1, layer1) = PdfDocument::new(
"PDF文档示例",
Mm(210.0), // A4宽度
Mm(297.0), // A4高度
"主图层"
);
// 获取当前页面的图层
let layer = doc.get_page(page1).get_layer(layer1);
// 1. 添加文本
let font = doc.add_external_font(File::open("fonts/Roboto-Regular.ttf")?)?;
layer.use_text("PDF文档标题", 48.0, Mm(50.0), Mm(250.0), &font);
layer.use_text("这是使用printpdf生成的PDF文档", 14.0, Mm(20.0), Mm(220.0), &font);
// 2. 绘制图形
// 绘制矩形
layer.set_outline_color(Color::Rgb(Rgb::new(0.0, 0.0, 1.0, None)));
layer.set_outline_thickness(2.0);
layer.add_shape(Line {
points: vec![
(Point::new(Mm(20.0), Mm(180.0)), false),
(Point::new(Mm(20.0), Mm(200.0)), false),
(Point::new(Mm(100.0), Mm(200.0)), false),
(Point::new(Mm(100.0), Mm(180.0)), false),
],
is_closed: true,
});
// 3. 添加图片
#[cfg(feature = "image")]
{
let image = Image::try_from(include_bytes!("assets/rust-logo.png"))?;
let image_layer = doc.get_page(page1).add_layer("图片图层");
image_layer.add_image(image, None, None, None, None, None, None)?;
}
// 保存PDF文件
doc.save(&mut File::create("output.pdf")?)?;
Ok(())
}
这个综合示例展示了:
- 创建新PDF文档并设置A4页面尺寸
- 添加文本内容并使用外部字体
- 绘制蓝色边框的矩形
- 添加图片(需要启用image特性)
- 将最终PDF保存到文件
要运行此示例,需要:
- 在Cargo.toml中添加printpdf依赖
- 准备Roboto-Regular.ttf字体文件
- 如需图片支持,启用printpdf的image特性
1 回复
Rust PDF生成库printpdf的使用指南
介绍
printpdf是一个纯Rust实现的PDF生成库,它允许开发者高效地创建、编辑和操作PDF文档。这个库提供了简单易用的API,支持文本、图像、矢量图形等多种PDF元素的添加和操作。
主要特性包括:
- 纯Rust实现,无外部依赖
- 支持创建多页PDF文档
- 可添加文本、图像、矢量图形
- 支持自定义字体
- 可设置页面大小和方向
- 支持图层操作
基本使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
printpdf = "0.5.0"
创建简单PDF文档
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
fn main() {
// 创建新PDF文档
let (doc, page1, layer1) = PdfDocument::new(
"PDF_Document_title",
Mm(210.0), // A4宽度
Mm(297.0), // A4高度
"Layer 1"
);
// 获取当前图层
let current_layer = doc.get_page(page1).get_layer(layer1);
// 添加文本
current_layer.use_text("Hello, printpdf!", 48.0, Mm(10.0), Mm(200.0), &Font::default());
// 保存到文件
doc.save(&mut BufWriter::new(File::create("test.pdf").unwrap())).unwrap();
}
添加图像
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
use image::io::Reader as ImageReader;
fn main() {
let (doc, page1, layer1) = PdfDocument::new("PDF with Image", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
// 加载图像
let img = ImageReader::open("example.png").unwrap().decode().unwrap();
// 添加图像到PDF
let image = Image::try_from(img).unwrap();
image.add_to_layer(current_layer.clone(), None, None, None, None, None, None);
doc.save(&mut BufWriter::new(File::create("image.pdf").unwrap())).unwrap();
}
绘制图形
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
fn main() {
let (doc, page1, layer1) = PdfDocument::new("PDF with Shapes", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
// 绘制矩形
let line = Line {
points: vec![
(Point::new(Mm(20.0), Mm(20.0)), false),
(Point::new(Mm(20.0), Mm(50.0)), false),
(Point::new(Mm(50.0), Mm(50.0)), false),
(Point::new(Mm(50.0), Mm(20.0)), false),
(Point::new(Mm(20.0), Mm(20.0)), false),
],
is_closed: true,
has_fill: true,
has_stroke: true,
is_clipping_path: false,
};
current_layer.add_shape(line);
doc.save(&mut BufWriter::new(File::create("shapes.pdf").unwrap())).unwrap();
}
高级功能
使用自定义字体
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
fn main() {
let (doc, page1, layer1) = PdfDocument::new("PDF with Custom Font", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
// 加载字体文件
let font_data = std::fs::read("custom_font.ttf").unwrap();
let font = doc.add_external_font(font_data.as_slice()).unwrap();
// 使用自定义字体
current_layer.use_text("Custom Font Text", 48.0, Mm(10.0), Mm(200.0), &font);
doc.save(&mut BufWriter::new(File::create("custom_font.pdf").unwrap())).unwrap();
}
创建多页文档
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
fn main() {
let (doc, page1, layer1) = PdfDocument::new("Multi-page PDF", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
current_layer.use_text("Page 1", 48.0, Mm(10.0), Mm(200.0), &Font::default());
// 添加第二页
let (page2, layer2) = doc.add_page(Mm(210.0), Mm(297.0), "Layer 1");
let current_layer2 = doc.get_page(page2).get_layer(layer2);
current_layer2.use_text("Page 2", 48.0, Mm(10.0), Mm(200.0), &Font::default());
doc.save(&mut BufWriter::new(File::create("multi_page.pdf").unwrap())).unwrap();
}
完整示例
以下是一个综合示例,展示如何创建一个包含文本、图像和图形的多页PDF文档:
use printpdf::*;
use std::fs::File;
use std::io::BufWriter;
use image::io::Reader as ImageReader;
fn main() {
// 创建多页PDF文档
let (doc, page1, layer1) = PdfDocument::new("Comprehensive PDF Example", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
// 第一页添加文本
current_layer.use_text("First Page - Title", 36.0, Mm(50.0), Mm(250.0), &Font::default());
// 第一页添加矩形
let rect = Line {
points: vec![
(Point::new(Mm(30.0), Mm(30.0)), false),
(Point::new(Mm(30.0), Mm(100.0)), false),
(Point::new(Mm(100.0), Mm(100.0)), false),
(Point::new(Mm(100.0), Mm(30.0)), false),
(Point::new(Mm(30.0), Mm(30.0)), false),
],
is_closed: true,
has_fill: true,
has_stroke: true,
is_clipping_path: false,
};
current_layer.add_shape(rect);
// 添加第二页
let (page2, layer2) = doc.add_page(Mm(210.0), Mm(297.0), "Layer 1");
let current_layer2 = doc.get_page(page2).get_layer(layer2);
// 第二页添加文本
current_layer2.use_text("Second Page - Image Example", 36.0, Mm(50.0), Mm(250.0), &Font::default());
// 第二页添加图像
if let Ok(img) = ImageReader::open("example.png").unwrap().decode() {
let image = Image::try_from(img).unwrap();
image.add_to_layer(
current_layer2.clone(),
Some(Mm(30.0)), // x坐标
Some(Mm(30.0)), // y坐标
Some(Mm(100.0)), // 宽度
Some(Mm(100.0)), // 高度
None, // 旋转
None // 透明度
);
}
// 保存PDF文件
doc.save(&mut BufWriter::new(File::create("comprehensive.pdf").unwrap())).unwrap();
}
注意事项
- printpdf目前主要专注于PDF生成,对PDF编辑功能支持有限
- 对于复杂布局,可能需要手动计算坐标位置
- 性能方面,对于非常大的文档可能需要优化
- 某些高级PDF特性可能不支持
printpdf是一个功能强大且易于使用的PDF生成库,特别适合需要以编程方式生成PDF文档的Rust应用程序。