Skip to content

Latest commit

 

History

History
78 lines (71 loc) · 2.93 KB

example-report.md

File metadata and controls

78 lines (71 loc) · 2.93 KB

Report

The Table component is a data-oriented component that allows for the creation of simple text reports like this, or even complex bespoke layouts with graphical elements for something like company invoices. Table is generic over its data types, so TableColumns and TableGroups can be defined in a type-safe manner using Swift KeyPaths.

In this example, the table is grouped by state in alphabetical ordering. Group headers and footers are passed an array of data rows that constitute the group and can use that array for computing summary data; here, a row count is reported in the group foter.

In this report, you will see that there is no "row print" element. That is because without an explicit row: parameter passed to Table, a default row is printed based upon the TableColumns definitions which define the column widths (proportionally) and a string formatter for non-string data types.

PDF

example-report.pdf

Code

struct ExampleReport: Block {
    let data: [CustomerData]

    var body: some Block {
        Table(data) {
            TableColumn("Last Name", value: \.lastName, width: 20)
            TableColumn("First Name", value: \.firstName, width: 20)
            TableColumn("Address", value: \.address, width: 35)
            TableColumn("City", value: \.city, width: 25)
            TableColumn("State", value: \.state, width: 10)
            TableColumn("Zip", value: \.zip, width: 10)
            TableColumn("DOB", value: \.dob, format: .mmddyy, width: 10, alignment: .trailing)
        } groups: {
            TableGroup(on: \.state, order: <, spacing: .pt(12)) { _, value in
                Text(stateName(abberviation: value))
                    .fontSize(12)
                    .bold()
                    .padding(.trailing, .max)
                TableColumnTitles()
            } footer: { rows, value in
                Divider(thickness: .pt(0.75), padding: .pt(2))
                Text("\(rows.count) records for \(stateName(abberviation: value))")
                    .bold()
                    .padding(.leading, .max)
            }
        } pageHeader: { 
            PageNumberReader { proxy in
                HStack(spacing: .flex) {
                    Text("Donor Report")
                    Text("Page \(proxy.pageNo)")
                }
                .fontSize(12)
                .bold()
                .padding(.bottom, 12)
                if pageNo > 1 {
                    TableColumnTitles()
                }
            }
        }
        .font(.system(size: 8))
    }
}

struct CustomerData {
    let firstName: String
    let lastName: String
    let address: String
    let city: String
    let state: String
    let zip: String
    let dob: Date
}

func stateName(abberviation: String) -> String {
    switch abberviation {
    case "CA":
        "California"
    case "NY":
        "New York"
    case "TX":
        "Texas"
    default:
        "Unknown"
    }
}