Sounds promising.
Below is an example of a PollyReport.
Each band (B) contains a list of elements (E).
For each E you can define pos=(x,y), font=(name,size), text, key, align, width (among other parameters).
Note that an element's x,y is relative to the containing band's x,y (top left corner).
So maybe use a texpos box around a table with one row and try to get relative positions that way.
Note: 72dpi, so x=600 is 8.33 inches from the left edge of the band
H = ("Helvetica", 10)
HB = ("Helvetica-Bold", 10)
E = PR.Element
B = PR.Band
Rule = PR.Rule # horizontal line
R = "right"
rep = PR.Report(rr)
rep.titleband = B([ E((600, 0), ("Times-Bold", 20), "Picklist"),
E((36,30), H, f"Ship to\n{soi[4]} {soi[5]}\n{adr}"), E((380,30), H, now), # soi = sales order query results
E((480,30), H, f"Order\n{so}"), E((560,30), H, f"Doc.Date\n{dd}"), E((630,30), H, f"Allow partial\n{soi[2]}"),
E((480,60), H, f"MoT: {soi[7]}\nRemarks: {soi[3]}"),
])
rep.groupheaders = [ B([ Rule((36,0),650),], getvalue = lambda x: x[0] ), ]
rep.pageheader = B([
Rule((36,0),650),
E((90,0), H, "Item Number"), E((166,0), H, "Description"), E((410,0), HB, "Pick Qty", align=R),
E((450,0), H, "UoM"), E((538,0), H, "Bin Location", align=R), E((626,0), H, "OnHand", align=R),
E((680,0), H, "Picked", align=R),
Rule((36,12),650),
])
rep.pagefooter = B([ E((72*7, 0), H, sysvar = "pagenumber", format = lambda x: f"[{now}] Order {so} page {x}"), ])
rep.detailband = B([ E((52,0), H, getvalue=lambda r: r[1]+1, align=R),
E((90,0), H, key=2), E((166,0), H, key=8), E((410,0), HB, key=6, align=R),
E((450,0), H, key=9), E((573,0), H, key=11, width=42),
]
)
Regards,
Denes