//! Template Demo - Using predefined document templates //! //! Run with: zig build template_demo && ./zig-out/bin/template_demo const std = @import("std"); const zcatpdf = @import("zcatpdf"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); std.debug.print("=== zcatpdf Template Demo ===\n\n", .{}); // Create invoice using template try createInvoiceFromTemplate(allocator); // Create letter using template try createLetterFromTemplate(allocator); std.debug.print("\nTemplate demo completed successfully!\n", .{}); } fn createInvoiceFromTemplate(allocator: std.mem.Allocator) !void { std.debug.print("Creating invoice from template...\n", .{}); // Get the invoice template var tmpl = try zcatpdf.Template.invoiceTemplate(allocator); defer tmpl.deinit(); std.debug.print(" Template: {s}\n", .{tmpl.name}); std.debug.print(" Page size: {d:.0} x {d:.0} points\n", .{ tmpl.page_width, tmpl.page_height }); // Create PDF based on template var pdf = zcatpdf.Pdf.init(allocator, .{}); defer pdf.deinit(); pdf.setTitle("Invoice from Template"); var page = try pdf.addPageCustom(tmpl.page_width, tmpl.page_height); // Use template regions to position content if (tmpl.getRegion("header")) |region| { std.debug.print(" Header region: ({d:.0}, {d:.0}) {d:.0}x{d:.0}\n", .{ region.x, region.y, region.width, region.height }); try page.setFont(.helvetica_bold, 20); try page.drawText(region.x, region.y, "ACME Corporation"); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y - 15, "123 Business Street"); try page.drawText(region.x, region.y - 27, "Tech City, TC 12345"); } if (tmpl.getRegion("invoice_info")) |region| { std.debug.print(" Invoice info region: ({d:.0}, {d:.0})\n", .{ region.x, region.y }); try page.setFont(.helvetica_bold, 14); try page.drawText(region.x, region.y, "INVOICE #2024-001"); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y - 15, "Date: December 9, 2024"); try page.drawText(region.x, region.y - 27, "Due: December 23, 2024"); } if (tmpl.getRegion("customer")) |region| { std.debug.print(" Customer region: ({d:.0}, {d:.0})\n", .{ region.x, region.y }); try page.setFont(.helvetica_bold, 12); try page.drawText(region.x, region.y, "Bill To:"); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y - 15, "Customer Company Ltd."); try page.drawText(region.x, region.y - 27, "456 Client Avenue"); try page.drawText(region.x, region.y - 39, "Business Town, BT 67890"); } if (tmpl.getRegion("items")) |region| { std.debug.print(" Items region: ({d:.0}, {d:.0}) {d:.0}x{d:.0}\n", .{ region.x, region.y, region.width, region.height }); // Draw table header page.setFillColor(zcatpdf.Color.hex(0xE0E0E0)); try page.fillRect(region.x, region.y + region.height - 25, region.width, 25); page.setFillColor(zcatpdf.Color.black); try page.setFont(.helvetica_bold, 10); try page.drawText(region.x + 5, region.y + region.height - 17, "Description"); try page.drawText(region.x + 250, region.y + region.height - 17, "Qty"); try page.drawText(region.x + 320, region.y + region.height - 17, "Price"); try page.drawText(region.x + 420, region.y + region.height - 17, "Total"); // Draw table rows try page.setFont(.helvetica, 10); const items = [_]struct { desc: []const u8, qty: []const u8, price: []const u8, total: []const u8 }{ .{ .desc = "Web Development Services", .qty = "40", .price = "$75.00", .total = "$3,000.00" }, .{ .desc = "UI/UX Design", .qty = "20", .price = "$85.00", .total = "$1,700.00" }, .{ .desc = "Server Hosting (1 year)", .qty = "1", .price = "$500.00", .total = "$500.00" }, }; var y_offset: f32 = region.y + region.height - 45; for (items) |item| { try page.drawText(region.x + 5, y_offset, item.desc); try page.drawText(region.x + 250, y_offset, item.qty); try page.drawText(region.x + 320, y_offset, item.price); try page.drawText(region.x + 420, y_offset, item.total); y_offset -= 20; } // Draw table border page.setStrokeColor(zcatpdf.Color.black); try page.drawRect(region.x, region.y, region.width, region.height); } if (tmpl.getRegion("totals")) |region| { std.debug.print(" Totals region: ({d:.0}, {d:.0})\n", .{ region.x, region.y }); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y + 60, "Subtotal:"); try page.drawText(region.x + 100, region.y + 60, "$5,200.00"); try page.drawText(region.x, region.y + 45, "Tax (10%):"); try page.drawText(region.x + 100, region.y + 45, "$520.00"); try page.setLineWidth(1); try page.drawLine(region.x, region.y + 35, region.x + region.width, region.y + 35); try page.setFont(.helvetica_bold, 12); try page.drawText(region.x, region.y + 20, "TOTAL:"); try page.drawText(region.x + 100, region.y + 20, "$5,720.00"); } if (tmpl.getRegion("footer")) |region| { std.debug.print(" Footer region: ({d:.0}, {d:.0})\n", .{ region.x, region.y }); try page.setFont(.helvetica, 8); page.setFillColor(zcatpdf.Color.hex(0x666666)); try page.drawText(region.x, region.y + 20, "Payment Terms: Net 14 days"); try page.drawText(region.x, region.y + 8, "Thank you for your business!"); } try pdf.save("template_invoice.pdf"); std.debug.print(" Saved: template_invoice.pdf\n", .{}); } fn createLetterFromTemplate(allocator: std.mem.Allocator) !void { std.debug.print("\nCreating letter from template...\n", .{}); // Get the letter template var tmpl = try zcatpdf.Template.letterTemplate(allocator); defer tmpl.deinit(); std.debug.print(" Template: {s}\n", .{tmpl.name}); // Create PDF based on template var pdf = zcatpdf.Pdf.init(allocator, .{}); defer pdf.deinit(); pdf.setTitle("Letter from Template"); var page = try pdf.addPageCustom(tmpl.page_width, tmpl.page_height); // Sender if (tmpl.getRegion("sender")) |region| { try page.setFont(.helvetica_bold, 11); try page.drawText(region.x, region.y, "John Smith"); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y - 14, "123 Sender Street"); try page.drawText(region.x, region.y - 26, "City, ST 12345"); try page.drawText(region.x, region.y - 38, "john@example.com"); } // Date if (tmpl.getRegion("date")) |region| { try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y, "December 9, 2024"); } // Recipient if (tmpl.getRegion("recipient")) |region| { try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y, "Ms. Jane Doe"); try page.drawText(region.x, region.y - 14, "456 Recipient Avenue"); try page.drawText(region.x, region.y - 26, "Town, ST 67890"); } // Subject if (tmpl.getRegion("subject")) |region| { try page.setFont(.helvetica_bold, 11); try page.drawText(region.x, region.y, "Re: Project Proposal Discussion"); } // Body if (tmpl.getRegion("body")) |region| { try page.setFont(.helvetica, 10); const line_height: f32 = 14; var y = region.y + region.height; try page.drawText(region.x, y, "Dear Ms. Doe,"); y -= line_height * 2; try page.drawText(region.x, y, "I am writing to follow up on our recent conversation regarding the"); y -= line_height; try page.drawText(region.x, y, "proposed collaboration between our organizations. I believe there is"); y -= line_height; try page.drawText(region.x, y, "significant potential for a mutually beneficial partnership."); y -= line_height * 2; try page.drawText(region.x, y, "As discussed, I have prepared a detailed proposal outlining the scope"); y -= line_height; try page.drawText(region.x, y, "of work, timeline, and expected outcomes. I would be happy to schedule"); y -= line_height; try page.drawText(region.x, y, "a meeting at your earliest convenience to discuss this further."); y -= line_height * 2; try page.drawText(region.x, y, "Please do not hesitate to contact me if you have any questions or"); y -= line_height; try page.drawText(region.x, y, "require additional information."); y -= line_height * 2; try page.drawText(region.x, y, "Thank you for your time and consideration."); } // Signature if (tmpl.getRegion("signature")) |region| { try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y + 50, "Sincerely,"); try page.setFont(.helvetica_bold, 10); try page.drawText(region.x, region.y + 20, "John Smith"); try page.setFont(.helvetica, 10); try page.drawText(region.x, region.y + 6, "Senior Consultant"); } try pdf.save("template_letter.pdf"); std.debug.print(" Saved: template_letter.pdf\n", .{}); }