我正在使用reportlab库,并且对使用SimpleDocTemplate添加图像有疑问。
我有动态内容,但我不知道它占用了多少空间。发生的事情是,我想在页面底部添加一个徽标(总是在同一位置)。我这样做的方法是将内容添加到列表中:例如[文本,分隔符,表格,分隔符,徽标],然后构建它。徽标的位置取决于其他变量。
您能帮我实现这种行为吗?
我知道可以使用绝对定位(例如在canvas类中使用drawImage)完成此操作,但我不知道如何将执行此操作的方式与此结合。
预先感谢
答案 0 :(得分:0)
我得到了我生成的报告的标题,就像这样的代码一样(其中PageTemplate为每篇论文生成标题。
from reportlab.platypus import Table, TableStyle, Paragraph
from reportlab.platypus.frames import Frame
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, tr, param1, param2, plugin_dir, **kw):
self.allowSplitting = 0
BaseDocTemplate.__init__(self, filename, **kw)
self.tr = tr
self.plugin_dir = plugin_dir
frame = Frame(self.leftMargin, self.bottomMargin, self.width, self.height - 2 * cm, id='normal')
template = PageTemplate(id='test', frames=frame, onPage=partial(self.header, param1=param1, param2=param2))
self.addPageTemplates(template)
def header(self, canvas, doc, param1, param2):
canvas.saveState()
canvas.drawString(30, 750, self.tr('Simple report from GeoDataFarm'))
canvas.drawString(30, 733, self.tr('For the growing season of ') + str(param1))
canvas.drawImage(self.plugin_dir + '\\img\\icon.png', 500, 765, width=50, height=50)
canvas.drawString(500, 750, 'Generated:')
canvas.drawString(500, 733, param2)
canvas.line(30, 723, 580, 723)
#w, h = content.wrap(doc.width, doc.topMargin)
#content.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)
canvas.restoreState()
doc = MyDocTemplate(report_name, self.tr, self.plugin_dir, '2018', '2018-09-21')
story = []
data_tbl = [['col1', 'col2'],[1, 2],[3, 4]]
table = Table(data_tbl, repeatRows=1, hAlign='LEFT', colWidths=[380/l_heading] * l_heading)
table.setStyle(TableStyle([('FONTSIZE', (0, 0), (l_heading, 0), 16)]))
story.append(table)
doc.build(story)
答案 1 :(得分:0)
您可能希望将图像放在页脚中(更接近axel_ande的答案)。这样一来,图片将在每个页面上都放置在同一位置,但只定义一次。
如果要在页面底部放置图像,而在页脚中放置不是,则可以尝试使用extension Settings {
var paths: [[String]] {
switch self {
case .settings(let settings):
// For each key, prepend it to all its children's keys until you get to a value
let result: [[[String]]] = settings.map { kv in
let key = kv.key
let value = kv.value
switch value {
case .value:
return [[key]] // Base case
case .settings:
return value.paths.map { [key] + $0 } // Recurse and add our key
}
}
// The result of that is [[[String]]] because we looped twice over something
// that was already an array. We want to flatten it back down one layer to [[String]]
return Array(result.joined())
case .value:
return [] // This isn't the base case; this is just in case you call .paths on a value.
}
}
}
for path in result.paths {
print("\(path): \(result[path]!)")
}
==>
["pro15", "prob16"]: true
["pro3", "pro4"]: true
["pro3", "pro10"]: true
["pro3", "pro7"]: true
["pro3", "pro8"]: true
["pro3", "pro5"]: true
["pro3", "pro6"]: true
["prob19", "prob20", "prob21", "prob22"]: false
["prob23"]: true
["prob24"]: true
["MyApp", "pro1", "enable"]: true
["MyApp", "pro2", "enable"]: true
["prob16", "prob17", "prob18"]: true
["pro11", "pro13"]: false
["pro11", "pro14"]: false
["pro11", "pro12"]: false
包装对象:
TopPadder
我在浏览the code时偶然发现了这一点,我唯一能找到的文档是在release notes中。在我的示例中,我只包装了一个表,因此示例代码是独立的。
希望这会有所帮助!