18.python打包win32print时报错,说找不到该模块

发布时间 2023-08-03 17:04:43作者: 种太阳

相关插件自己提前安装好。

代码:

  1 #encoding:utf-8
  2 
  3 from tkinter import *
  4 from tkinter import messagebox
  5 import win32print
  6 import time
  7 from tkinter import scrolledtext
  8 
  9 # 控制输入框只能输入数字且小于8位数
 10 def validate_op(input_text):
 11     if input_text.isdigit() or input_text == "":
 12         if len(input_text) <= 8:
 13             return True
 14     return False
 15 
 16 # 控制输入框只能输入数字且小于4位数
 17 def validate_password(input_text):
 18     if input_text.isdigit() or input_text == "":
 19         if len(input_text) <= 4:
 20             return True
 21     return False
 22 
 23 
 24 def get_printers():
 25     printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
 26     printer_list = []
 27     for printer in printers:
 28         printer_name = printer[2]
 29         printer_list.append(printer_name)
 30     return printer_list
 31 
 32 class Application(Frame):
 33     def __init__(self, master=None):
 34         super().__init__(master)
 35         self.master = master
 36         self.pack()
 37 
 38         self.createWidget()
 39 
 40     def createWidget(self):
 41         self.utk_l_title = Label(root,text="OBA RM LABEL 列印指令生成",bg="red",font=("Arial",16),width=30,height=2).pack()
 42         self.utk_l_DB = Label(root,text="请选择打印机:",font=("Arial",16)).place(x = 30,y = 70)
 43         #创建一个选择数据库下拉框
 44         
 45         
 46         PSHDB = ["请选择打印机"]
 47         # 调用函数获取打印机列表
 48         printer_list = get_printers()
 49         # 打印机列表打印输出
 50         for printer in printer_list:
 51             # print(printer)
 52             PSHDB.append(printer)
 53         self.PSHDBVariable = StringVar()
 54         self.PSHDBVariable.set(PSHDB[0])
 55         self.utk_o_DB = OptionMenu(root,self.PSHDBVariable, *PSHDB).place(x = 180,y = 70)
 56         #创建一个工号标签
 57         self.utk_l_op = Label(root,text="开始序号:",font=("Arial",16)).place(x = 30,y = 120)
 58         self.utk_l_op1 = Label(root, text="【年份+日期+0000】如 23080000", font=("Arial", 12)).place(x=290, y=125)
 59         #创建一个工号输入框
 60         # self.utk_e_op=Entry(root)
 61         self.utk_e_op = Entry(root, validate="key", validatecommand=(root.register(validate_op), '%P'))
 62         self.utk_e_op.place(x = 150,y = 125)
 63         self.utk_e_op.bind("<Return>", self.clear_entry)
 64         #创建一个密码标签
 65         self.utk_l_password = Label(root,text="打印数量:",font=("Arial",16)).place(x = 30,y = 170)
 66         self.utk_l_password1 = Label(root, text="【1~1000】", font=("Arial", 12)).place(x=290, y=170)
 67         #创建一个密码输入框
 68         self.utk_e_password = Entry(root, validate="key", validatecommand=(root.register(validate_password), '%P'))
 69         self.utk_e_password.place(x = 150,y = 175)
 70         self.utk_e_password.bind("<Return>", self.clear_entry)
 71         #创建一个登录按钮
 72         self.utk_b_login = Button(root,text="打印",font=("Arial",12),width=10,height=1)
 73         self.utk_b_login.place(x = 150,y = 210)
 74         self.utk_b_login["command"] = self.songhua
 75         #创建一个提示信息标签
 76         self.utk_l_info = Label(root,text="快乐工作,幸福生活!!!",font=("Arial",16))
 77         self.utk_l_info.place(x = 30,y = 250)
 78 
 79     def clear_entry(self, event):
 80         event.widget.delete(0, END)
 81 
 82     def songhua(self):
 83         """判断登录填写是否符合要求"""
 84         self.tnsName = self.PSHDBVariable.get().strip()
 85         self.name = self.utk_e_op.get().strip()
 86         self.password = self.utk_e_password.get().strip()
 87         if self.tnsName=="请选择打印机":
 88             messagebox.showwarning("警告", "必须选择打印机!!!")
 89         elif len(self.name)==0 and self.name=="":
 90             messagebox.showwarning("警告", "请输入开始序号")
 91         elif len(self.name)!=8:
 92             messagebox.showwarning("警告", "开始序号必须8位数")
 93         elif self.name.startswith('0'):
 94             messagebox.showwarning("警告", "输入的数不能以0开头")
 95         elif len(self.password)==0 and self.password=="":
 96             messagebox.showwarning("警告", "请输入打印数量")
 97         elif int(self.password) > 1000:
 98             messagebox.showwarning("警告", "打印数量必须在1~1000")
 99         elif int(self.password) < 0:
100             messagebox.showwarning("警告", "打印数量必须在1~1000")
101         else:
102             messagebox.showinfo("打印信息", "恭喜你,输入格式正确,"+self.tnsName+",开始序号:"+self.name+",打印数量是:"+self.password)
103             # self.linkOrcale(self.name,self.password,self.tnsName)
104             a = int(self.name)
105             b = ''
106             d = []
107             try:
108                 selected_printer = win32print.OpenPrinter(self.tnsName)  # 获取选择的打印机句柄
109                 win32print.StartDocPrinter(selected_printer, 1, ("Print Job", None, None))  # 开始打印任务
110                 file = open('data.txt', 'w')
111                 for i in range(int(self.password)):
112                     a +=1
113                     c = str(a)
114                     win32print.StartPagePrinter(selected_printer)  # 开始打印一页
115                     b = '^XA^FO158,170^A@N,35,33,MYRIAD_SET_BOLD_.FNT^FDRM0' + c + '^FS ^FO185,35^BXN,8,400,,,^FDRM0' + c + '^FS^PQ1^XZ'
116                     win32print.WritePrinter(selected_printer, b.encode('utf-8'))  # 发送ZPL代码到打印机
117                     win32print.EndPagePrinter(selected_printer)  # 结束打印一页
118                     time.sleep(1)  # 添加1秒的延迟
119                     # print(b)
120                     d.append(b)
121                     file.write(b+'\n')
122                 file.close()
123                 win32print.EndDocPrinter(selected_printer)  # 结束打印任务
124                 win32print.ClosePrinter(selected_printer)  # 关闭打印机
125                 # print(d)
126                 print("数据已成功保存到文件 data.txt 中")
127                 # self.print_label()
128             except Exception as e:
129                 # 处理异常情况
130                 messagebox.showwarning("警告", "打印出错了,请联系【XXX】")
131                 print("打印发生错误:", str(e))
132 
133     # 打印label
134     def print_label(self):
135         zpl_code = "^XA^FO50,50^A0N,50,50^FDHello, World!^FS^XZ"
136         selected_printer = win32print.OpenPrinter(self.tnsName)  # 获取选择的打印机句柄
137         win32print.StartDocPrinter(selected_printer, 1, ("Print Job", None, None))  # 开始打印任务
138         for _ in range(int(self.password)):
139             win32print.StartPagePrinter(selected_printer)  # 开始打印一页
140             win32print.WritePrinter(selected_printer, zpl_code.encode('utf-8'))  # 发送ZPL代码到打印机
141             win32print.EndPagePrinter(selected_printer)  # 结束打印一页
142             time.sleep(1)  # 添加1秒的延迟
143         win32print.EndDocPrinter(selected_printer)  # 结束打印任务
144         win32print.ClosePrinter(selected_printer)  # 关闭打印机
145 
146 
147 if __name__ == "__main__":
148     root = Tk()
149     root.geometry("550x300+200+300")
150     root.title("Label打印小工具")
151     app = Application(master=root)
152     root.mainloop()

 

解决方法:

pywin32-ctypes 如何打包python
 
 

2023/8/3 下午3:52:27

要使用 pywin32-ctypes 打包 Python 应用程序,可以使用常见的打包工具,如 PyInstaller 或 cx_Freeze。这些工具可以将您的Python脚本及其依赖项打包为可执行文件。

以下是使用 PyInstaller 打包 pywin32-ctypes 的步骤:

  1. 首先,确保您已经安装了 PyInstaller。您可以使用 pip 进行安装:

    Copy Code
    pip install pyinstaller
    
  2. 在命令行中,导航到您的 Python 脚本所在的目录。

  3. 使用以下命令运行 PyInstaller 来打包您的应用程序:

    Copy Code
    pyinstaller --hidden-import pywintypes your_script.py
    

    注意将 "your_script.py" 替换为您实际的脚本文件名。

  4. PyInstaller 将创建一个 "dist" 文件夹,并在其中生成打包后的应用程序。您可以在该文件夹中找到可执行文件。

请记住,pywin32-ctypes 依赖于 pywin32,因此您需要确保已经安装并正确配置了 pywin32。

使用 cx_Freeze 打包 pywin32-ctypes 的步骤类似,但具体命令略有不同。您可以参考 cx_Freeze 的文档进行操作。

值得注意的是,打包复杂的 Python 应用程序可能涉及其他的设置和配置,具体取决于您的应用程序的特定需求。因此,建议您阅读 PyInstaller 或 cx_Freeze 的官方文档,了解更多配置选项和最佳实践。

 

2023/8/3 下午3:54:16

pywin32 如何打包python
 
 

2023/8/3 下午3:54:32

要打包使用 pywin32 的 Python 应用程序,可以使用常见的打包工具,例如 PyInstaller 或 cx_Freeze。以下是使用 PyInstaller 打包 pywin32 的步骤:

  1. 确保您已经安装了 PyInstaller。您可以使用 pip 进行安装:

    Copy Code
    pip install pyinstaller
    
  2. 在命令行中,导航到您的 Python 脚本所在的目录。

  3. 运行以下命令来使用 PyInstaller 打包您的应用程序:

    Copy Code
    pyinstaller your_script.py
    

    注意将 "your_script.py" 替换为您实际的脚本文件名。

  4. PyInstaller 将创建一个 "dist" 文件夹,并在其中生成打包后的应用程序。您可以在该文件夹中找到可执行文件。

请注意,pywin32 需要依赖于 Windows 上的一些系统库和组件。因此,在打包之前,请确保您的开发环境和目标环境都具备适当的依赖项和运行时支持。您可能还需要将 pywin32 相关的 DLL 文件(例如 pythoncomXX.dll 和 pywintypesXX.dll)复制到您的打包后的应用程序目录中,以确保它们可以正确加载。

使用 cx_Freeze 打包 pywin32 的步骤类似,但具体命令略有不同。您可以参考 cx_Freeze 的文档进行操作。

请注意,打包复杂的 Python 应用程序可能涉及其他的设置和配置,具体取决于您的应用程序的特定需求。因此,建议您阅读 PyInstaller 或 cx_Freeze 的官方文档,了解更多配置选项和最佳实践。

 

2023/8/3 下午3:55:18

能否将这两个文件一起打包pythoncomXX.dll 和 pywintypesXX.dll
 
 

2023/8/3 下午3:55:31

当使用 PyInstaller 或 cx_Freeze 进行打包时,可以将 pythoncomXX.dllpywintypesXX.dll 这两个文件与您的 Python 应用程序一起打包。

对于 PyInstaller,您可以将这两个文件放置在与您的 Python 脚本相同的目录中,然后运行以下命令进行打包:

Copy Code
pyinstaller --add-data "pythoncomXX.dll;." --add-data "pywintypesXX.dll;." your_script.py

请将 XX 替换为适用于您的 Python 版本的数字。这会将这两个 DLL 文件复制到生成的可执行文件所在的目录。

对于 cx_Freeze,您可以通过修改 setup.py 文件来指定需要包含在打包中的文件。在 build_exe_options 中添加类似以下的代码:

pythonCopy Code
build_exe_options = {
    'include_files': ['path/to/pythoncomXX.dll', 'path/to/pywintypesXX.dll'],
    # 其他的配置项...
}

然后,在命令行中运行 python setup.py build 来执行打包操作。

请确保替换 XX 为适用于您的 Python 版本的数字,并将文件路径替换为实际的路径。

这样,这两个 DLL 文件将与您的 Python 应用程序一起打包,并被复制到生成的可执行文件所在的目录中,以便正确加载和使用 pywin32 功能。

 

2023/8/3 下午4:17:52

path/to/pythoncomXX.dll 这个文件在哪,没找到
 
 

2023/8/3 下午4:18:08

对不起,我之前的回答可能造成了困惑。实际上,在打包 pywin32 应用程序时,并没有一个固定的 pythoncomXX.dll 文件路径。这是因为 pythoncomXX.dll 是根据您当前使用的 Python 版本和安装位置进行命名的。

正确的做法是在您的 Python 安装目录下搜索 pythoncom*.dll,找到与您正在使用的 Python 版本相对应的 pythoncomXX.dll 文件,然后将其复制到您的项目目录中进行打包。

请按照以下步骤操作:

  1. 在命令行中输入以下命令,找到 pythoncom*.dll 文件:

    Copy Code
    dir /s /b pythoncom*.dll
    
  2. 找到与您当前使用的 Python 版本相匹配的 pythoncomXX.dll 文件。

    • 文件名应该类似于 pythoncom37.dll(以 Python 3.7 为例)。
    • 还可以检查文件属性中的详细信息以确认版本匹配。
  3. 将找到的 pythoncomXX.dll 文件复制到您的项目目录中,或者根据需要放置在与您的 Python 脚本相同的目录中。

  4. 使用 PyInstaller 或 cx_Freeze 的命令行选项,将 pythoncomXX.dllpywintypesXX.dll 与您的 Python 脚本一起打包(具体命令参见前面的回答)。

这样,您将能够将正确版本的 pythoncomXX.dllpywintypesXX.dll 文件与您的应用程序一起打包,并在运行时加载所需的 pywin32 功能。

 

打包代码setup.py:

 1 from cx_Freeze import setup, Executable
 2 
 3 # 定义包含所有依赖项的列表
 4 build_exe_options = {"packages": [], "excludes": ['pywin32'], 'include_files': ['pythoncom310.dll', 'pywintypes310.dll']}
 5 
 6 # 创建可执行文件
 7 exe = Executable(
 8     script="printLabel.py",  # 指定要打包的脚本文件
 9     base="Win32GUI",  # 使用GUI界面
10 )
11 
12 setup(
13     name="PrintLabel",  # 项目名称
14     version="1.0",  # 版本号
15     description="Label打印小工具",  # 描述信息
16     options={"build_exe": build_exe_options},
17     executables=[exe],
18 )

 

控制台打包指令:python setup.py build

F:\资料整合\编程资料\编程项目\自己编写的小程序\PYTHON\pythonPrintLabel>python setup.py build