表格渲染
Table API 提供全面的表格创建系统,支持表头、单元格样式、边框、背景、列对齐、内边距和行间条纹。
绑定覆盖。 底层的
Table/TableStyle/TableCell构建器 API 仅限 Rust。在 Python、Node、WASM、Go 和 C# 中,表格可以通过以下两种方式生成:(a) 将含有 GFM 或<table>块的 Markdown 或 HTML 字符串传给Pdf.from_markdown/Pdf.from_html/Pdf.from_html_css(v0.3.37+ 的纯 Rust HTML+CSS 流水线支持列宽和边框);或 (b) 通过FluentPageBuilder链式调用text、line与rect,直接绘制单元格。
快速示例
Rust
use pdf_oxide::writer::{Table, TableCell, TableStyle};
let table = Table::new(vec![
vec![TableCell::header("Name"), TableCell::header("Age"), TableCell::header("City")],
vec![TableCell::text("Alice"), TableCell::number("30"), TableCell::text("New York")],
vec![TableCell::text("Bob"), TableCell::number("25"), TableCell::text("London")],
vec![TableCell::text("Carol"), TableCell::number("35"), TableCell::text("Tokyo")],
])
.with_header_row()
.with_width(468.0); // Page width minus margins
Python
表格渲染通过 Rust API 可用。在 Python 中,使用 Pdf.from_markdown() 的 Markdown 表格:
from pdf_oxide import Pdf
markdown = """
# Employee Directory
| 名称 | Age | City |
|-------|-----|----------|
| Alice | 30 | New York |
| Bob | 25 | London |
| Carol | 35 | Tokyo |
"""
pdf = Pdf.from_markdown(markdown)
pdf.save("directory.pdf")
WASM
在 JavaScript 中,使用 WasmPdf.fromMarkdown() 或 WasmPdf.fromHtml() 的 Markdown 或 HTML 表格:
import { WasmPdf } from "pdf-oxide-wasm";
import { writeFileSync } from "fs";
const markdown = `# Employee Directory
| 名称 | Age | City |
|-------|-----|----------|
| Alice | 30 | New York |
| Bob | 25 | London |
| Carol | 35 | Tokyo |
`;
const pdf = WasmPdf.fromMarkdown(markdown);
writeFileSync("directory.pdf", pdf.toBytes());
完整 API 参考
Table – Table Container
构造
use pdf_oxide::writer::{Table, TableCell, TableRow};
// From Vec<Vec<TableCell>>
let table = Table::new(vec![
vec![TableCell::text("A"), TableCell::text("B")],
vec![TableCell::text("1"), TableCell::text("2")],
]);
// From TableRow objects
let table = Table::from_rows(vec![
TableRow::header(vec![TableCell::header("A"), TableCell::header("B")]),
TableRow::new(vec![TableCell::text("1"), TableCell::text("2")]),
]);
// Empty table with rows added later
let mut table = Table::empty();
table.add_row(TableRow::new(vec![TableCell::text("1"), TableCell::text("2")]));
配置方法
| Method | 描述 |
|---|---|
.with_header_row() |
将第一行标记为表头 |
.with_style(style) |
设置表格样式 |
.with_width(width) |
设置表格总宽度(磅) |
.with_column_widths(widths) |
设置列宽规格 |
.with_column_aligns(aligns) |
设置默认列对齐 |
属性
| Method | Returns | 描述 |
|---|---|---|
.num_columns() |
usize |
Number of columns |
.num_rows() |
usize |
Number of rows |
.is_empty() |
bool |
表格是否没有行 |
TableCell – Cell Content
use pdf_oxide::writer::{TableCell, CellAlign, CellVAlign, CellPadding, Borders};
// Basic cells
let cell = TableCell::text("Hello");
let empty = TableCell::empty();
// Semantic cell types
let header = TableCell::header("Column Name"); // Centered + bold
let number = TableCell::number("$1,234.56"); // Right-aligned
// Full configuration
let cell = TableCell::text("Important")
.colspan(2) // Span 2 columns
.rowspan(3) // Span 3 rows
.align(CellAlign::Center) // Horizontal alignment
.valign(CellVAlign::Middle) // Vertical alignment
.padding(CellPadding::uniform(8.0)) // Cell padding
.borders(Borders::all(TableBorderStyle::thick()))
.background(0.95, 0.95, 1.0) // Light blue background
.font("Helvetica-Bold", 14.0) // Custom font
.bold() // Bold text
.italic(); // Italic text
TableRow – Row Container
use pdf_oxide::writer::{TableRow, TableCell};
// Data row
let row = TableRow::new(vec![
TableCell::text("Alice"),
TableCell::number("30"),
]);
// Header row
let header = TableRow::header(vec![
TableCell::header("Name"),
TableCell::header("Age"),
]);
// Configured row
let row = TableRow::new(vec![TableCell::text("Total"), TableCell::number("$500")])
.min_height(30.0)
.background(0.9, 0.9, 0.9) // Gray background
.as_header();
TableStyle – Style Configuration
use pdf_oxide::writer::{
TableStyle, TableBorderStyle, Borders, CellPadding,
};
// Default style (thin borders, gray header, Helvetica 10pt)
let style = TableStyle::new();
// Custom style
let style = TableStyle::new()
.cell_padding(CellPadding::symmetric(8.0, 6.0))
.cell_borders(Borders::all(TableBorderStyle::medium()))
.outer_border(TableBorderStyle::thick())
.font("Times-Roman", 11.0)
.header_background(0.2, 0.4, 0.8) // Blue header
.striped(0.95, 0.95, 0.95); // Light gray stripes
// Preset styles
let minimal = TableStyle::minimal(); // No borders
let bordered = TableStyle::bordered(); // Thick outer, medium inner
TableBorderStyle – Border Appearance
use pdf_oxide::writer::TableBorderStyle;
let border = TableBorderStyle::new(0.5); // Custom width
let border = TableBorderStyle::thin(); // 0.25pt
let border = TableBorderStyle::medium(); // 0.5pt
let border = TableBorderStyle::thick(); // 1.0pt
let border = TableBorderStyle::none(); // No border
let border = TableBorderStyle::medium()
.with_color(0.0, 0.0, 0.8); // Blue border
Borders – Four-Side Border Configuration
use pdf_oxide::writer::{Borders, TableBorderStyle};
let borders = Borders::none();
let borders = Borders::all(TableBorderStyle::thin());
let borders = Borders::horizontal(TableBorderStyle::medium()); // Top + bottom
let borders = Borders::vertical(TableBorderStyle::medium()); // Left + right
// Individual sides
let borders = Borders::none()
.with_top(TableBorderStyle::thick())
.with_bottom(TableBorderStyle::thick())
.with_left(TableBorderStyle::thin())
.with_right(TableBorderStyle::thin());
CellPadding – Padding Configuration
use pdf_oxide::writer::CellPadding;
let padding = CellPadding::uniform(8.0); // All sides 8pt
let padding = CellPadding::symmetric(10.0, 6.0); // H=10, V=6
let padding = CellPadding::none(); // No padding
let padding = CellPadding {
top: 4.0, right: 8.0, bottom: 4.0, left: 8.0,
};
ColumnWidth – Column Width Specification
use pdf_oxide::writer::ColumnWidth;
let widths = vec![
ColumnWidth::Auto, // Automatic sizing
ColumnWidth::Fixed(150.0), // Fixed 150pt
ColumnWidth::Percent(30.0), // 30% of table width
ColumnWidth::Weight(2.0), // Proportional flex weight
];
CellAlign / CellVAlign – Alignment
use pdf_oxide::writer::{CellAlign, CellVAlign};
// Horizontal
let align = CellAlign::Left;
let align = CellAlign::Center;
let align = CellAlign::Right;
// Vertical
let valign = CellVAlign::Top;
let valign = CellVAlign::Middle;
let valign = CellVAlign::Bottom;
高级示例
财务报告表格
use pdf_oxide::writer::{
Table, TableCell, TableRow, TableStyle, TableBorderStyle,
Borders, CellPadding, CellAlign, ColumnWidth,
};
let style = TableStyle::new()
.cell_padding(CellPadding::symmetric(10.0, 6.0))
.cell_borders(Borders::horizontal(TableBorderStyle::thin()))
.outer_border(TableBorderStyle::medium())
.font("Helvetica", 10.0)
.header_background(0.15, 0.3, 0.55)
.striped(0.96, 0.96, 0.96);
let table = Table::from_rows(vec![
TableRow::header(vec![
TableCell::header("类别"),
TableCell::header("Q1"),
TableCell::header("Q2"),
TableCell::header("Q3"),
TableCell::header("Q4"),
TableCell::header("Total"),
]),
TableRow::new(vec![
TableCell::text("Revenue"),
TableCell::number("$32M"),
TableCell::number("$35M"),
TableCell::number("$38M"),
TableCell::number("$42M"),
TableCell::number("$147M").bold(),
]),
TableRow::new(vec![
TableCell::text("Expenses"),
TableCell::number("$24M"),
TableCell::number("$25M"),
TableCell::number("$27M"),
TableCell::number("$29M"),
TableCell::number("$105M").bold(),
]),
TableRow::new(vec![
TableCell::text("Net Income").bold(),
TableCell::number("$8M").bold(),
TableCell::number("$10M").bold(),
TableCell::number("$11M").bold(),
TableCell::number("$13M").bold(),
TableCell::number("$42M").bold(),
]).background(0.9, 0.95, 0.9),
])
.with_style(style)
.with_width(468.0)
.with_column_widths(vec![
ColumnWidth::Fixed(100.0),
ColumnWidth::Weight(1.0),
ColumnWidth::Weight(1.0),
ColumnWidth::Weight(1.0),
ColumnWidth::Weight(1.0),
ColumnWidth::Fixed(80.0),
])
.with_column_aligns(vec![
CellAlign::Left,
CellAlign::Right,
CellAlign::Right,
CellAlign::Right,
CellAlign::Right,
CellAlign::Right,
]);
带跨越单元格的表格
use pdf_oxide::writer::{Table, TableCell, TableRow};
let table = Table::from_rows(vec![
TableRow::header(vec![
TableCell::header("Product").colspan(2),
TableCell::header("Sales"),
]),
TableRow::new(vec![
TableCell::text("类别 A").rowspan(2),
TableCell::text("Widget X"),
TableCell::number("1,234"),
]),
TableRow::new(vec![
// First cell omitted due to rowspan above
TableCell::text("Widget Y"),
TableCell::number("567"),
]),
])
.with_header_row()
.with_width(400.0);
相关页面
- DocumentBuilder 底层 API – 页面级内容构建
- 图形、图案与着色 – 绘图原语
- 从 Markdown 创建 – Markdown 表格自动转换为 PDF