You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用Reportlabs生成多页全页运输标签的代码优化方案咨询

问题描述

我是ReportLab的新手,想要生成如下样式的全页运输标签:
运输标签样例
目前我已经写出了可以实现需求的代码,但写法不够简洁高效:

import datetime

from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

year = datetime.date.today().year

# IIRNumber = str(int(input("Month (digit): "))) + "-" + str(int(input("Shipment Number (include zero if before 10): ")))
# VMBENumber = "VBME-" + str(year)[-2:] + "-" + str(int(input("Enter VBME Number (last four digits: ")))
# PONUmber = input("Enter PO number or V for Various: ")
IIRNumber = "08-09"
VMBENumber = "VBME-21-1458"
PONUmber = "9185555"

ShipmentNumber = int(input("How many pieces in the shipment?: "))
print(VMBENumber)
print(IIRNumber)
print(ShipmentNumber)


def textobject_demo():

    my_canvas = canvas.Canvas("PDFGenerated.pdf",
                              pagesize=letter)
    # Create text_object
    text_object = my_canvas.beginText()
    # Set text location (x, y)


    # Write a line of text + carriage return
    # Set font face and size
    text_object.setFont('Times-Roman', 12)
    text_object.setTextOrigin(150, 730)

    for i in range(1, ShipmentNumber + 1):

        # Write text to the canvas
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text='To: Voisey Bay Mine Site – EXPANSION PROJECT (VBME)')
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="             C/O Innu Mikun Hangar")
        text_object.textLine(text="             Happy Valley-Goose Bay, NL")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="                     CC0012- " + VMBENumber + " - " + IIRNumber)
        text_object.textLine(text="                     Product Description:" + PONUmber)
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="                         Box " + str(i) + " of " + str(ShipmentNumber))
        text_object.textLine(text="                         Gross Weight: 14 lbs")
        text_object.textLine(text="                         Net Weight: 14 lbs")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="                         Dimensions: 9 L x 9 W x 9” H")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="             Special Storage Instruction: NO")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="")
        text_object.textLine(text="             Attn:   IIR – REDPATH Canada Limited")
        text_object.textLine(text="                         Underground Garage ATTN: Mark / Shawn")
        text_object.textLine(text="")
        my_canvas.drawText(text_object)
        my_canvas.showPage()

    my_canvas.save()


if __name__ == '__main__':
    textobject_demo()

我希望优化现有实现逻辑,替代原先逐页复制粘贴信息的操作,实现批量生成运输标签的流程,请问有没有更优的实现方式?


优化方案

核心优化逻辑如下:

  • 把所有可变参数(运单编号、PO号、重量尺寸等)抽离出来,后续修改或批量传参不需要改动模板逻辑
  • 用模板字符串统一管理标签的全部内容,包括空行、缩进,替代原来手动写大量textLine("")的操作,调整排版更方便
  • 把字体、坐标、页尺寸这类样式参数统一设为全局常量,后续改样式不需要翻代码找对应位置
  • 每页单独生成文本对象,避免多页循环时出现坐标偏移的问题
  • 核心生成逻辑拆分为单页生成和批量生成两个函数,支持多批运单数据一次性生成全量标签

优化后代码如下:

import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

# --------------- 全局样式常量 ---------------
FONT_NAME = "Times-Roman"
FONT_SIZE = 12
TEXT_ORIGIN_X = 150
TEXT_ORIGIN_Y = 730
PAGE_SIZE = letter
OUTPUT_PATH = "运输标签.pdf"

# --------------- 标签模板 ---------------
LABEL_TEMPLATE = """


To: Voisey Bay Mine Site – EXPANSION PROJECT (VBME)


             C/O Innu Mikun Hangar
             Happy Valley-Goose Bay, NL



                     CC0012- {vmbe_number} - {iir_number}
                     Product Description: {po_number}



                         Box {current_box} of {total_box}
                         Gross Weight: {gross_weight} lbs
                         Net Weight: {net_weight} lbs



                         Dimensions: {dimensions}


             Special Storage Instruction: {storage_instruction}



             Attn:   IIR – REDPATH Canada Limited
                         Underground Garage ATTN: Mark / Shawn
"""

def generate_single_label(canvas, label_data):
    """生成单页运输标签"""
    text_obj = canvas.beginText()
    text_obj.setFont(FONT_NAME, FONT_SIZE)
    text_obj.setTextOrigin(TEXT_ORIGIN_X, TEXT_ORIGIN_Y)
    # 填充模板内容
    label_content = LABEL_TEMPLATE.format(**label_data)
    # 按行写入
    for line in label_content.split('\n'):
        text_obj.textLine(line)
    canvas.drawText(text_obj)
    canvas.showPage()

def batch_generate_labels(label_data_list):
    """批量生成运输标签"""
    my_canvas = canvas.Canvas(OUTPUT_PATH, pagesize=PAGE_SIZE)
    for data in label_data_list:
        generate_single_label(my_canvas, data)
    my_canvas.save()

if __name__ == '__main__':
    year = datetime.date.today().year
    # 示例输入,可替换为从Excel/表单批量读取数据
    IIRNumber = "08-09"
    VMBENumber = "VBME-21-1458"
    PONUmber = "9185555"
    ShipmentNumber = int(input("请输入货物总件数: "))
    # 组装单批运单的所有箱子标签数据
    label_list = []
    for i in range(1, ShipmentNumber+1):
        label_data = {
            "vmbe_number": VMBENumber,
            "iir_number": IIRNumber,
            "po_number": PONUmber,
            "current_box": i,
            "total_box": ShipmentNumber,
            "gross_weight": 14,
            "net_weight": 14,
            "dimensions": "9 L x 9 W x 9” H",
            "storage_instruction": "NO"
        }
        label_list.append(label_data)
    # 如果有多批运单,继续往label_list里加数据即可
    batch_generate_labels(label_list)
使用说明
  1. 样式调整:如果需要改字体、字号、标签起始位置,直接修改顶部的全局常量即可
  2. 排版调整:如果需要改标签的文字内容、空行、缩进,直接修改LABEL_TEMPLATE里的文本即可,和最终输出效果完全对应
  3. 批量生成:如果需要批量生成多批不同的运单标签,只需要把所有运单的数据按照指定格式组装成字典,加入label_list即可,支持对接Excel、数据库等数据源批量导入
  4. 输入逻辑:原来的交互式输入可以保留,也可以替换成从数据源批量读取的逻辑,不需要改动生成标签的核心代码

内容的提问来源于stack exchange,提问作者littlejiver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:48:03