use pdf_oxide::geometry::Rect;
use pdf_oxide::writer::{CellAlign, ColumnWidth, DocumentBuilder, Table, TableCell};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut doc = DocumentBuilder::new();
doc.letter_page()
.font("Helvetica", 11.0)
.text("Sample results")
.paragraph(
"Table 1 summarizes the measurements collected during the trial. \
Each row corresponds to one specimen; values are averaged over \
three independent runs.",
)
.table(
Table::new(vec![
vec![
TableCell::text("Specimen"),
TableCell::text("Length (mm)"),
TableCell::text("Mass (g)").align(CellAlign::Right),
TableCell::text("Yield (%)").align(CellAlign::Right),
],
vec![
TableCell::text("A-101"),
TableCell::text("12.4"),
TableCell::text("3.51").align(CellAlign::Right),
TableCell::text("88.2").align(CellAlign::Right),
],
vec![
TableCell::text("A-102"),
TableCell::text("13.0"),
TableCell::text("3.77").align(CellAlign::Right),
TableCell::text("91.5").align(CellAlign::Right),
],
vec![
TableCell::text("B-201"),
TableCell::text("9.8"),
TableCell::text("2.44").align(CellAlign::Right),
TableCell::text("76.0").align(CellAlign::Right),
],
vec![
TableCell::text("B-202"),
TableCell::text("10.2"),
TableCell::text("2.60").align(CellAlign::Right),
TableCell::text("79.8").align(CellAlign::Right),
],
])
.with_header_row()
.with_style({
let mut st = pdf_oxide::writer::TableStyle::default();
st.header_background = None; st
})
.with_column_widths(vec![
ColumnWidth::Fixed(120.0),
ColumnWidth::Fixed(110.0),
ColumnWidth::Fixed(100.0),
ColumnWidth::Fixed(100.0),
]),
)
.at(72.0, 660.0)
.paragraph(
"The yield percentages increase monotonically with specimen length \
within each batch. Batch B shows systematically lower yields than \
batch A across all measured lengths.",
)
.done();
let out = "tests/fixtures/ruled_table.pdf";
doc.save(out)?;
println!("wrote {out}");
let mut pdf = pdf_oxide::api::Pdf::open(out)?;
let page_rect = Rect::new(0.0, 0.0, 612.0, 792.0);
for i in 0..pdf.page_count()? {
for (name, tables) in [
("default", pdf.extract_tables_in_rect(i, page_rect)),
(
"strict",
pdf.extract_tables_with_config(
i,
pdf_oxide::structure::spatial_table_detector::TableDetectionConfig::strict(),
)
.map(|ts| {
ts.into_iter()
.filter(|t| t.bbox.map_or(false, |b| b.intersects(&page_rect)))
.collect()
}),
),
] {
match tables {
Ok(ts) => {
println!("page {} [{name}]: {} table(s)", i + 1, ts.len());
for t in &ts {
println!(
" {} rows x {} cols, header={}",
t.rows.len(),
t.col_count,
t.has_header
);
if let Some(b) = t.bbox {
println!(
" bbox = ({:.0},{:.0} {:.0}x{:.0})",
b.x,
b.y,
b.width,
b.height
);
}
for r in &t.rows {
let cells: Vec<&str> =
r.cells.iter().map(|c| c.text.as_str()).collect();
println!(" hdr={} {cells:?}", r.is_header);
}
}
}
Err(e) => println!("page {} [{name}]: ERR {e}", i + 1),
}
}
}
Ok(())
}