我正试图在一个用ReportLab生成的PDF文件中构建一个日程规划器。时间表将根据一天中的时间有不同的行:从上午8:00、上午8:15、上午8:30开始,依此类推
我做了一个循环,在这个循环中,小时数将自动计算,时间表将被填写。但是,由于我的表格太长,它不能完全放在页面中。(虽然日程安排应在晚上7:30结束,但在下午2:00被取消。)
理想的结果是,当表大约有20个活动时,会有一个分页符。在下一页,标题应与第一页完全相同,并在下一页,即表格的续页。该过程应在每次必要时重复,直到表格结束
Python代码如下所示:
from reportlab.pdfgen.canvas import Canvas
from datetime import datetime, timedelta
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, landscape
class Vendedor:
"""
Información del Vendedor: Nombre, sucursal, meta de venta
"""
def __init__(self, nombre_vendedor, sucursal, dia_reporte):
self.nombre_vendedor = nombre_vendedor
self.sucursal = sucursal
self.dia_reporte = dia_reporte
class Actividades:
"""
Información de las Actividades realizadas: Hora de actividad y duración, cliente atendido,
tipo de actividad, resultado, monto venta (mxn) + (usd), monto cotización (mxn) + (usd),
solicitud de apoyo y comentarios adicionales
"""
def __init__(self, hora_actividad, duracion_actividad, cliente, tipo_actividad, resultado,
monto_venta_mxn, monto_venta_usd, monto_cot_mxn, monto_cot_usd, requiero_apoyo, comentarios_extra):
self.hora_actividad = hora_actividad
self.duracion_actividad = duracion_actividad
self.cliente = cliente
self.tipo_actividad = tipo_actividad
self.resultado = resultado
self.monto_venta_mxn = monto_venta_mxn
self.monto_venta_usd = monto_venta_usd
self.monto_cot_mxn = monto_cot_mxn
self.monto_cot_usd = monto_cot_usd
self.requiero_apoyo = requiero_apoyo
self.comentarios_extra = comentarios_extra
class PDFReport:
"""
Crea el Reporte de Actividades diarias en archivo de formato PDF
"""
def __init__(self, filename):
self.filename = filename
vendedor = Vendedor('John Doe', 'Stack Overflow', datetime.now().strftime('%d/%m/%Y'))
file_name = 'cronograma_actividades.pdf'
document_title = 'Cronograma Diario de Actividades'
title = 'Cronograma Diario de Actividades'
nombre_colaborador = vendedor.nombre_vendedor
sucursal_colaborador = vendedor.sucursal
fecha_actual = vendedor.dia_reporte
canvas = Canvas(file_name)
canvas.setPageSize(landscape(letter))
canvas.setTitle(document_title)
canvas.setFont("Helvetica-Bold", 20)
canvas.drawCentredString(385+100, 805-250, title)
canvas.setFont("Helvetica", 16)
canvas.drawCentredString(385+100, 785-250, nombre_colaborador + ' - ' + sucursal_colaborador)
canvas.setFont("Helvetica", 14)
canvas.drawCentredString(385+100, 765-250, fecha_actual)
title_background = colors.fidblue
hour = 8
minute = 0
hour_list = []
data_actividades = [
{'Hora', 'Cliente', 'Resultado de \nActividad', 'Monto Venta \n(MXN)', 'Monto Venta \n(USD)',
'Monto Cotización \n(MXN)', 'Monto Cotización \n(USD)', 'Comentarios \nAdicionales'},
]
i = 0
for i in range(47):
if minute == 0:
if hour <= 12:
time = str(hour) + ':' + str(minute) + '0 a.m.'
else:
time = str(hour-12) + ':' + str(minute) + '0 p.m.'
else:
if hour <= 12:
time = str(hour) + ':' + str(minute) + ' a.m.'
else:
time = str(hour-12) + ':' + str(minute) + ' p.m.'
if minute != 45:
minute += 15
else:
hour += 1
minute = 0
hour_list.append(time)
# I TRIED THIS SOLUTION BUT THIS DIDN'T WORK
# if i % 20 == 0:
# canvas.showPage()
data_actividades.append([hour_list[i], i, i, i, i, i, i, i])
i += 1
table_actividades = Table(data_actividades, colWidths=85, rowHeights=30, repeatRows=1)
tblStyle = TableStyle([
('BACKGROUND', (0, 0), (-1, 0), title_background),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (1, 0), (1, -1), 'CENTER'),
('GRID', (0, 0), (-1, -1), 1, colors.black)
])
rowNumb = len(data_actividades)
for row in range(1, rowNumb):
if row % 2 == 0:
table_background = colors.lightblue
else:
table_background = colors.aliceblue
tblStyle.add('BACKGROUND', (0, row), (-1, row), table_background)
table_actividades.setStyle(tblStyle)
width = 150
height = 150
table_actividades.wrapOn(canvas, width, height)
table_actividades.drawOn(canvas, 65, (0 - height) - 240)
canvas.save()
我试图加上:
if i % 20 == 0:
canvas.showPage()
然而,这并没有达到预期的结果
其他简要说明:尽管我专门对表的列标题进行了编码。运行程序后,由于某种原因,列标题的顺序会被修改(请参见粘贴的图像)。你知道为什么会这样吗
data_actividades = [
{'Hora', 'Cliente', 'Resultado de \nActividad', 'Monto Venta \n(MXN)', 'Monto Venta \n(USD)',
'Monto Cotización \n(MXN)', 'Monto Cotización \n(USD)', 'Comentarios \nAdicionales'},
]
提前非常感谢您,祝您度过愉快的一天
您应该使用模板,正如官方文档第5章“鸭嘴兽-页面布局和排版使用脚本”中所建议的那样
基本思想是使用框架,并将所有要添加的信息添加到列表元素中。在我的例子中,我称之为“contents”,使用命令“
contents.append(FrameBreak())
”您可以离开框架并处理下一个框架,另一方面,如果您想更改模板的类型,可以使用命令”contents.append(NextPageTemplate('<template_name>'))
”我的建议:
对于您的案例,我使用了两个模板,第一个模板包含带有图纸信息的标题和表的第一部分,另一个模板对应于其余内容。这些模板的名称为firstpage和laterpage。代码如下:
结果
有了这个,你可以添加任意多的记录,我尝试了300条。这个表格不是完全可见的,因为为了方便起见,我制作了一个A4大小的pdf。但是,对于任何大小,原理都是相同的,因此您必须调整框架的大小和pdf页面的大小
额外,在每页添加页眉
因为现在只需要一个模板,所以应该删除“第一页”模板,因为它对于所有页面都是相同的。与您在开始时提出的方法相同,我每21条记录剪切一次表(包括表的标题),并将其分组到一个列表中,然后在每个循环中迭代添加带有徽标的标题。它也包含在逻辑切割句中,即记录数未达到21但记录数即将结束的情况。代码如下:
额外-结果:
相关问题 更多 >
编程相关推荐