Phase 4 Implementation:
- Table helper (src/table.zig):
- Table.init() with TableOptions (col_widths, colors, fonts)
- header(), row(), rowStyled(), footer() methods
- setColumnAlign() for per-column alignment
- separator() and space() utilities
- Pagination module (src/pagination.zig):
- Pagination.addPageNumbers() with {PAGE}/{PAGES} format
- addHeader() with optional separator line
- addFooter() and addFooterWithLine()
- Position enum (bottom_left, bottom_center, etc.)
- Links visual styling (src/links.zig, src/page.zig):
- PageLinks struct for link storage
- Page.drawLink() - blue underlined text
- Page.writeLink() - link at current position
- Examples:
- table_demo.zig - 3 table styles (product, invoice, employee)
- pagination_demo.zig - 5 pages with headers/footers/numbers
~70 tests passing, 6 examples working.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
157 lines
5.7 KiB
Zig
157 lines
5.7 KiB
Zig
//! Table Demo - Demonstrates the Table helper for easy table creation
|
|
//!
|
|
//! Shows how to create formatted tables with headers, data rows,
|
|
//! alternating colors, and custom styling.
|
|
|
|
const std = @import("std");
|
|
const pdf = @import("zpdf");
|
|
|
|
pub fn main() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
std.debug.print("zpdf - Table Demo\n", .{});
|
|
|
|
var doc = pdf.Pdf.init(allocator, .{});
|
|
defer doc.deinit();
|
|
|
|
doc.setTitle("Table Demo");
|
|
doc.setAuthor("zpdf");
|
|
|
|
var page = try doc.addPage(.{});
|
|
page.setMargins(50, 50, 50);
|
|
|
|
// Title
|
|
try page.setFont(.helvetica_bold, 24);
|
|
page.setFillColor(pdf.Color.rgb(41, 98, 255));
|
|
page.setXY(50, 800);
|
|
try page.cell(0, 30, "Table Helper Demo", pdf.Border.none, .center, false);
|
|
page.ln(50);
|
|
|
|
// =========================================================================
|
|
// Example 1: Simple Product Table
|
|
// =========================================================================
|
|
try page.setFont(.helvetica_bold, 14);
|
|
page.setFillColor(pdf.Color.black);
|
|
try page.cell(0, 20, "Example 1: Product Inventory", pdf.Border.none, .left, false);
|
|
page.ln(25);
|
|
|
|
const col_widths = [_]f32{ 200, 80, 80, 80 };
|
|
var table = pdf.Table.init(page, .{
|
|
.x = 50,
|
|
.y = page.getY(),
|
|
.col_widths = &col_widths,
|
|
});
|
|
|
|
// Set column alignments
|
|
table.setColumnAlign(0, .left); // Product name
|
|
table.setColumnAlign(1, .center); // SKU
|
|
table.setColumnAlign(2, .right); // Quantity
|
|
table.setColumnAlign(3, .right); // Price
|
|
|
|
try table.header(&.{ "Product", "SKU", "Qty", "Price" });
|
|
try table.row(&.{ "Widget Pro", "WP-001", "150", "$29.99" });
|
|
try table.row(&.{ "Gadget Plus", "GP-042", "75", "$49.99" });
|
|
try table.row(&.{ "Super Tool", "ST-108", "200", "$19.99" });
|
|
try table.row(&.{ "Mega Device", "MD-255", "50", "$99.99" });
|
|
try table.row(&.{ "Mini Helper", "MH-033", "300", "$9.99" });
|
|
try table.footer(&.{ "Total Items", "", "775", "" });
|
|
|
|
// =========================================================================
|
|
// Example 2: Invoice-style Table
|
|
// =========================================================================
|
|
page.setXY(50, table.getY() - 40);
|
|
try page.setFont(.helvetica_bold, 14);
|
|
page.setFillColor(pdf.Color.black);
|
|
try page.cell(0, 20, "Example 2: Invoice Items", pdf.Border.none, .left, false);
|
|
page.ln(25);
|
|
|
|
const invoice_widths = [_]f32{ 250, 60, 80, 100 };
|
|
var invoice_table = pdf.Table.init(page, .{
|
|
.x = 50,
|
|
.y = page.getY(),
|
|
.col_widths = &invoice_widths,
|
|
.header_bg = pdf.Color.rgb(51, 51, 51),
|
|
.header_fg = pdf.Color.white,
|
|
.odd_row_bg = pdf.Color.rgb(250, 250, 250),
|
|
});
|
|
|
|
invoice_table.setColumnAlign(0, .left);
|
|
invoice_table.setColumnAlign(1, .center);
|
|
invoice_table.setColumnAlign(2, .right);
|
|
invoice_table.setColumnAlign(3, .right);
|
|
|
|
try invoice_table.header(&.{ "Description", "Qty", "Unit Price", "Total" });
|
|
try invoice_table.row(&.{ "Web Development Services", "40", "$75.00", "$3,000.00" });
|
|
try invoice_table.row(&.{ "UI/UX Design Package", "1", "$1,500.00", "$1,500.00" });
|
|
try invoice_table.row(&.{ "Server Hosting (Annual)", "1", "$480.00", "$480.00" });
|
|
try invoice_table.row(&.{ "SSL Certificate", "1", "$50.00", "$50.00" });
|
|
try invoice_table.row(&.{ "Technical Support (hours)", "10", "$50.00", "$500.00" });
|
|
|
|
try invoice_table.separator();
|
|
invoice_table.space(5);
|
|
|
|
// Subtotal, Tax, Total using styled rows
|
|
try invoice_table.rowStyled(
|
|
&.{ "", "", "Subtotal:", "$5,530.00" },
|
|
pdf.Color.white,
|
|
pdf.Color.black,
|
|
.helvetica,
|
|
10,
|
|
);
|
|
try invoice_table.rowStyled(
|
|
&.{ "", "", "Tax (8%):", "$442.40" },
|
|
pdf.Color.white,
|
|
pdf.Color.black,
|
|
.helvetica,
|
|
10,
|
|
);
|
|
try invoice_table.rowStyled(
|
|
&.{ "", "", "Total:", "$5,972.40" },
|
|
pdf.Color.rgb(41, 98, 255),
|
|
pdf.Color.white,
|
|
.helvetica_bold,
|
|
11,
|
|
);
|
|
|
|
// =========================================================================
|
|
// Example 3: Compact Data Table
|
|
// =========================================================================
|
|
page.setXY(50, invoice_table.getY() - 40);
|
|
try page.setFont(.helvetica_bold, 14);
|
|
page.setFillColor(pdf.Color.black);
|
|
try page.cell(0, 20, "Example 3: Employee Directory", pdf.Border.none, .left, false);
|
|
page.ln(25);
|
|
|
|
const emp_widths = [_]f32{ 120, 150, 100, 120 };
|
|
var emp_table = pdf.Table.init(page, .{
|
|
.x = 50,
|
|
.y = page.getY(),
|
|
.col_widths = &emp_widths,
|
|
.header_bg = pdf.Color.rgb(76, 175, 80),
|
|
.body_font_size = 9,
|
|
.header_font_size = 10,
|
|
.padding = 3,
|
|
});
|
|
|
|
try emp_table.header(&.{ "Name", "Email", "Department", "Phone" });
|
|
try emp_table.row(&.{ "John Smith", "john@company.com", "Engineering", "+1-555-0101" });
|
|
try emp_table.row(&.{ "Sarah Johnson", "sarah@company.com", "Marketing", "+1-555-0102" });
|
|
try emp_table.row(&.{ "Mike Wilson", "mike@company.com", "Sales", "+1-555-0103" });
|
|
try emp_table.row(&.{ "Emily Davis", "emily@company.com", "HR", "+1-555-0104" });
|
|
try emp_table.row(&.{ "Chris Brown", "chris@company.com", "Finance", "+1-555-0105" });
|
|
|
|
// Footer
|
|
page.setXY(50, 50);
|
|
try page.setFont(.helvetica, 9);
|
|
page.setFillColor(pdf.Color.medium_gray);
|
|
try page.cell(0, 15, "Generated with zpdf - Table Helper Demo", pdf.Border.none, .center, false);
|
|
|
|
// Save
|
|
const filename = "table_demo.pdf";
|
|
try doc.save(filename);
|
|
|
|
std.debug.print("Created: {s}\n", .{filename});
|
|
std.debug.print("Done!\n", .{});
|
|
}
|