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

PyInstaller打包Python条码生成程序为exe时遇OSError问题求助

Python条码生成程序PyInstaller打包后OSError问题解决

问题重现

  • 本地运行.py或.ipynb脚本时功能正常,使用PyInstaller打包为exe可执行文件后,执行条码生成操作触发OSError: cannot open resource错误
  • 完整代码:
import tkinter as tk
from tkinter import filedialog, messagebox
from barcode import Code128
from barcode.writer import ImageWriter
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

class BarcodeGeneratorApp:
    def __init__(self, master):
        self.master = master
        self.master.title("Barcode Generator")

        self.label_numbers = tk.Label(self.master, text="Barcode:")
        self.label_numbers.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W)

        self.entry_numbers = tk.Entry(self.master)
        self.entry_numbers.grid(row=0, column=1, padx=10, pady=10, sticky=tk.W)

        self.generate_button = tk.Button(self.master, text="Generate Barcodes", command=self.generate_barcodes)
        self.generate_button.grid(row=1, column=0, columnspan=2, pady=10)

    def generate_barcodes(self):
        numbers = self.entry_numbers.get().split(',')

        folder_path = filedialog.askdirectory()

        for number in numbers:
            number = number.strip()
            if number:
                pdf_filename = f"{folder_path}/barcode_{number}_code128.pdf"
                self.generate_and_save_barcode_to_pdf(pdf_filename, number)

        messagebox.showinfo("Success", "Barcodes generated successfully.")

    def generate_and_save_barcode_to_pdf(self, pdf_filename, number):
        c = canvas.Canvas(pdf_filename, pagesize=letter)
        my_code = Code128(number, writer=ImageWriter())
        barcode_image = my_code.render()
        c.drawInlineImage(barcode_image, 100, 500, width=200, height=100)
        c.save()

if __name__ == "__main__":
    root = tk.Tk()
    app = BarcodeGeneratorApp(root)
    root.mainloop()
  • 报错堆栈:
Exception in Tkinter callback
Traceback (most recent call last):
  File "tkinter\__init__.py", line 1948, in __call__
  File "Fack.py", line 31, in generate_barcodes
  File "Fack.py", line 38, in generate_and_save_barcode_to_pdf
  File "barcode\codex.py", line 255, in render
  File "barcode\base.py", line 100, in render
  File "barcode\writer.py", line 269, in render
  File "barcode\writer.py", line 440, in _paint_text
  File "PIL\ImageFont.py", line 791, in truetype
  File "PIL\ImageFont.py", line 788, in freetype
  File "PIL\ImageFont.py", line 226, in __init__
OSError: cannot open resource

问题原因

报错根源是python-barcode库默认使用的系统字体在打包后无法被PyInstaller识别并打包,导致PIL加载字体资源失败。

解决步骤

步骤1:获取并复制默认字体文件

  1. 本地运行以下代码,查看python-barcode默认使用的字体路径:
from barcode.writer import ImageWriter
writer = ImageWriter()
print(writer.font_path)

通常默认字体为arial.ttf或DejaVuSans.ttf。
2. 找到对应字体文件,复制到项目根目录。

步骤2:修改代码手动指定字体路径

修改generate_and_save_barcode_to_pdf方法,初始化ImageWriter时显式指定字体路径:

import sys
import os

def get_font_path():
    if hasattr(sys, '_MEIPASS'):
        # 打包后运行时的临时目录路径
        return os.path.join(sys._MEIPASS, 'arial.ttf')
    else:
        # 本地运行时的字体路径
        return 'arial.ttf'

# 修改原方法
def generate_and_save_barcode_to_pdf(self, pdf_filename, number):
    c = canvas.Canvas(pdf_filename, pagesize=letter)
    writer = ImageWriter()
    writer.font_path = get_font_path()
    my_code = Code128(number, writer=writer)
    barcode_image = my_code.render()
    c.drawInlineImage(barcode_image, 100, 500, width=200, height=100)
    c.save()

步骤3:PyInstaller打包时包含字体文件

使用以下命令打包(Windows系统用;分隔路径,Linux/macOS用:):

pyinstaller --onefile --add-data "arial.ttf;." your_script_name.py

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:47:09