1.简介

做了一个excel的风控模板,里面含有宏,我用python的第三方xlwings部署到linux后发现,linux环境并不支持xlwings。

Python 程序都是脚本的方式,一般是在解析器里运行,如果要发布出去,需要提前安装解析器才可以运行。那么只能退而求其次,把所有代码封装成一个.exe文件直接给运营,当他有需要的时候直接点击exe就可以获得想要的exe报表。

PyInstaller 是一个十分有用的第三方库,可以用来打包 python 应用程序,打包完的程序就可以在没有安装 Python 解释器的机器上运行了。

它能够在 Windows、Linux、 Mac OS X 等操作系统下将 Python 源文件打包,通过对源文件打包, Python 程序可以在没有安装 Python 的环境中运行,也可以作为一个 独立文件方便传递和管理。

PyInstaller 支持 Python 2.7 / 3.4-3.7。可以在 Windows、Mac OS X 和 Linux 上使用,但是并不是跨平台的,而是说你要是希望打包成 .exe 文件,需要在 Windows 系统上运行 PyInstaller 进行打包工作。

pip install pyinstaller

 

将 Python 程序打包成 .exe 文件_python将 Python 程序打包成 .exe 文件_可执行文件_02
pyinstaller -h
usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]
                   [--add-data <SRC;DEST or SRC:DEST>]
                   [--add-binary <SRC;DEST or SRC:DEST>] [-p DIR]
                   [--hidden-import MODULENAME]
                   [--additional-hooks-dir HOOKSPATH]
                   [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
                   [--key KEY] [-d {all,imports,bootloader,noarchive}] [-s]
                   [--noupx] [--upx-exclude FILE] [-c] [-w]
                   [-i <FILE.ico or FILE.exe,ID or FILE.icns>]
                   [--version-file FILE] [-m <FILE or XML>] [-r RESOURCE]
                   [--uac-admin] [--uac-uiaccess] [--win-private-assemblies]
                   [--win-no-prefer-redirects]
                   [--osx-bundle-identifier BUNDLE_IDENTIFIER]
                   [--runtime-tmpdir PATH] [--bootloader-ignore-signals]
                   [--distpath DIR] [--workpath WORKPATH] [-y]
                   [--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL]
                   scriptname [scriptname ...]

positional arguments:
  scriptname            name of scriptfiles to be processed or exactly one
                        .spec-file. If a .spec-file is specified, most options
                        are unnecessary and are ignored.

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         Show program version info and exit.
  --distpath DIR        Where to put the bundled app (default: .\dist)
  --workpath WORKPATH   Where to put all the temporary work files, .log, .pyz
                        and etc. (default: .\build)
  -y, --noconfirm       Replace output directory (default:
                        SPECPATH\dist\SPECNAME) without asking for
                        confirmation
  --upx-dir UPX_DIR     Path to UPX utility (default: search the execution
                        path)
  -a, --ascii           Do not include unicode encoding support (default:
                        included if available)
  --clean               Clean PyInstaller cache and remove temporary files
                        before building.
  --log-level LEVEL     Amount of detail in build-time console messages. LEVEL
                        may be one of TRACE, DEBUG, INFO, WARN, ERROR,
                        CRITICAL (default: INFO).

What to generate:
  -D, --onedir          Create a one-folder bundle containing an executable
                        (default)
  -F, --onefile         Create a one-file bundled executable.
  --specpath DIR        Folder to store the generated spec file (default:
                        current directory)
  -n NAME, --name NAME  Name to assign to the bundled app and spec file
                        (default: first script's basename)

What to bundle, where to search:
  --add-data <SRC;DEST or SRC:DEST>
                        Additional non-binary files or folders to be added to
                        the executable. The path separator is platform
                        specific, ``os.pathsep`` (which is ``;`` on Windows
                        and ``:`` on most unix systems) is used. This option
                        can be used multiple times.
  --add-binary <SRC;DEST or SRC:DEST>
                        Additional binary files to be added to the executable.
                        See the ``--add-data`` option for more details. This
                        option can be used multiple times.
  -p DIR, --paths DIR   A path to search for imports (like using PYTHONPATH).
                        Multiple paths are allowed, separated by ';', or use
                        this option multiple times
  --hidden-import MODULENAME, --hiddenimport MODULENAME
                        Name an import not visible in the code of the
                        script(s). This option can be used multiple times.
  --additional-hooks-dir HOOKSPATH
                        An additional path to search for hooks. This option
                        can be used multiple times.
  --runtime-hook RUNTIME_HOOKS
                        Path to a custom runtime hook file. A runtime hook is
                        code that is bundled with the executable and is
                        executed before any other code or module to set up
                        special features of the runtime environment. This
                        option can be used multiple times.
  --exclude-module EXCLUDES
                        Optional module or package (the Python name, not the
                        path name) that will be ignored (as though it was not
                        found). This option can be used multiple times.
  --key KEY             The key used to encrypt Python bytecode.

How to generate:
  -d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive}
                        Provide assistance with debugging a frozen
                        application. This argument may be provided multiple
                        times to select several of the following options.

                        - all: All three of the following options.

                        - imports: specify the -v option to the underlying
                          Python interpreter, causing it to print a message
                          each time a module is initialized, showing the
                          place (filename or built-in module) from which it
                          is loaded. See
                          https://docs.python.org/3/using/cmdline.html#id4.

                        - bootloader: tell the bootloader to issue progress
                          messages while initializing and starting the
                          bundled app. Used to diagnose problems with
                          missing imports.

                        - noarchive: instead of storing all frozen Python
                          source files as an archive inside the resulting
                          executable, store them as files in the resulting
                          output directory.

  -s, --strip           Apply a symbol-table strip to the executable and
                        shared libs (not recommended for Windows)
  --noupx               Do not use UPX even if it is available (works
                        differently between Windows and *nix)
  --upx-exclude FILE    Prevent a binary from being compressed when using upx.
                        This is typically used if upx corrupts certain
                        binaries during compression. FILE is the filename of
                        the binary without path. This option can be used
                        multiple times.

Windows and Mac OS X specific options:
  -c, --console, --nowindowed
                        Open a console window for standard i/o (default). On
                        Windows this option will have no effect if the first
                        script is a '.pyw' file.
  -w, --windowed, --noconsole
                        Windows and Mac OS X: do not provide a console window
                        for standard i/o. On Mac OS X this also triggers
                        building an OS X .app bundle. On Windows this option
                        will be set if the first script is a '.pyw' file. This
                        option is ignored in *NIX systems.
  -i <FILE.ico or FILE.exe,ID or FILE.icns>, --icon <FILE.ico or FILE.exe,ID or FILE.icns>
                        FILE.ico: apply that icon to a Windows executable.
                        FILE.exe,ID, extract the icon with ID from an exe.
                        FILE.icns: apply the icon to the .app bundle on Mac OS
                        X

Windows specific options:
  --version-file FILE   add a version resource from FILE to the exe
  -m <FILE or XML>, --manifest <FILE or XML>
                        add manifest FILE or XML to the exe
  -r RESOURCE, --resource RESOURCE
                        Add or update a resource to a Windows executable. The
                        RESOURCE is one to four items,
                        FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file
                        or an exe/dll. For data files, at least TYPE and NAME
                        must be specified. LANGUAGE defaults to 0 or may be
                        specified as wildcard * to update all resources of the
                        given TYPE and NAME. For exe/dll files, all resources
                        from FILE will be added/updated to the final
                        executable if TYPE, NAME and LANGUAGE are omitted or
                        specified as wildcard *.This option can be used
                        multiple times.
  --uac-admin           Using this option creates a Manifest which will
                        request elevation upon application restart.
  --uac-uiaccess        Using this option allows an elevated application to
                        work with Remote Desktop.

Windows Side-by-side Assembly searching options (advanced):
  --win-private-assemblies
                        Any Shared Assemblies bundled into the application
                        will be changed into Private Assemblies. This means
                        the exact versions of these assemblies will always be
                        used, and any newer versions installed on user
                        machines at the system level will be ignored.
  --win-no-prefer-redirects
                        While searching for Shared or Private Assemblies to
                        bundle into the application, PyInstaller will prefer
                        not to follow policies that redirect to newer
                        versions, and will try to bundle the exact versions of
                        the assembly.

Mac OS X specific options:
  --osx-bundle-identifier BUNDLE_IDENTIFIER
                        Mac OS X .app bundle identifier is used as the default
                        unique program name for code signing purposes. The
                        usual form is a hierarchical name in reverse DNS
                        notation. For example:
                        com.mycompany.department.appname (default: first
                        script's basename)

Rarely used special options:
  --runtime-tmpdir PATH
                        Where to extract libraries and support files in
                        `onefile`-mode. If this option is given, the
                        bootloader will ignore any temp-folder location
                        defined by the run-time OS. The ``_MEIxxxxxx``-folder
                        will be created here. Please use this option only if
                        you know what you are doing.
  --bootloader-ignore-signals
                        Tell the bootloader to ignore signals rather than
                        forwarding them to the child process. Useful in
                        situations where e.g. a supervisor process signals
                        both the bootloader and child (e.g. via a process
                        group) to avoid signalling the child twice.

                        forwarding them to the child process. Useful in
                        situations where e.g. a supervisor process signals
                        both the bootloader and child (e.g. via a process
                        group) to avoid signalling the child twice.
pyinstaller -h

 

2.参数介绍

 参数如下:

 

参数 说明
-F, –onefile
打包一个单个文件,如果你的代码都写在一个.py文件的话,可以用这个,如果是多个.py文件就别用
-D, –onedir 打包多个文件,在dist中生成很多依赖文件,适合以框架形式编写工具代码,我个人比较推荐这样,代码易于维护
-K, –tk 在部署时包含 TCL/TK
-a, –ascii 不包含编码.在支持Unicode的python版本上默认包含所有的编码.
-d, –debug 产生debug版本的可执行文件
-w,–windowed,–noconsole 使用Windows子系统执行.当程序启动的时候不会打开命令行(只对Windows有效)
-c,–console,-nowindowed 使用控制台子系统执行(默认)(只对Windows有效)pyinstaller -c xxxx.pypyinstaller xxxx.py --console
-s,-strip 可执行文件和共享库将run through strip.注意Cygwin的strip往往使普通的win32 Dll无法使用.
-X, –upx 如果有UPX安装(执行Configure.py时检测),会压缩执行文件(Windows系统中的DLL也会)(参见note)

-o DIR, 

-out=DIR

指定spec文件的生成目录,如果没有指定,而且当前目录是PyInstaller的根目录,会自动创建一个用于输出(spec和生成的可执行文件)的目录.如果没有指定,而当前目录不是PyInstaller的根目录,则会输出到当前的目录下.

-p DIR, 

-path=DIR

设置导入路径(和使用PYTHONPATH效果相似).可以用路径分割符(Windows使用分号,Linux使用冒号)分割,指定多个目录.也可以使用多个-p参数来设置多个导入路径,让pyinstaller自己去找程序需要的资源
–icon=<FILE.ICO> 将file.ico添加为可执行文件的资源(只对Windows系统有效),改变程序的图标 pyinstaller -i ico路径 xxxxx.py
–icon=<FILE.EXE,N> 将file.exe的第n个图标添加为可执行文件的资源(只对Windows系统有效)

-v FILE, 

-version=FILE

将verfile作为可执行文件的版本资源(只对Windows系统有效)

-n NAME, 

-name=NAME

可选的项目(产生的spec的)名字.如果省略,第一个脚本的主文件名将作为spec的名字

 

常用参数

-F 表示打包成单独的 .exe 文件,这时生成的 .exe 文件会比较大,而且运行速度回较慢。仅仅一个 helloworld 程序,生成的文件就 5MB 大。
-i 还可以指定可执行文件的图标 -w 表示去掉控制台窗口,这在 GUI 界面时非常有用。

细节解释

将 Python 程序打包成 .exe 文件_python将 Python 程序打包成 .exe 文件_可执行文件_02
选项
一般选项
-h, --help 显示此帮助消息并退出
-v, --version 显示程序版本信息并退出。
--distpath DIR 放置捆绑应用的位置(默认值:./ did)
--workpath WORKPATH 在哪里放置所有临时工作文件,。log,.pyz等(默认值:./ build)
-y, --noconfirm 替换输出目录(默认值:SPECPATH / dist / SPECNAME)而不要求确认
--upx-dir UPX_DIR UPX实用程序的路径(默认:搜索执行路径)
-a, --ascii 不包括unicode编码支持(默认值:如果可用,则包含)
--clean 在构建之前清理PyInstaller缓存并删除临时文件。
--log-level LEVEL 构建时控制台消息中的详细信息量。LEVEL可能是TRACE,DEBUG,INFO,WARN,ERROR,CRITICAL之一(默认值:INFO)。

生成什么
-D, --onedir 创建包含可执行文件的单文件夹包(默认)
-F, --onefile 创建一个文件捆绑的可执行文件。
--specpath DIR 用于存储生成的spec文件的文件夹(默认值:当前目录)
-n NAME, --name NAME 要分配给捆绑应用程序和规范文件的名称(默认值:第一个脚本的基本名称)

捆绑什么,搜索到哪里
--add-data <SRC;DEST or SRC:DEST> 要添加到可执行文件的其他非二进制文件或文件夹。路径分隔符是特定于平台的os.pathsep(;在Windows上和:大多数unix系统上)。此选项可以多次使用。
--add-binary <SRC;DEST or SRC:DEST> 要添加到可执行文件的其他二进制文件。有关--add-data详细信息,请参阅该选项。此选项可以多次使用。
-p DIR, --paths DIR 搜索导入的路径(如使用PYTHONPATH)。允许多个路径,以“:”分隔,或多次使用此选项
--hidden-import MODULENAME, --hiddenimport MODULENAME 命名在脚本代码中不可见的导入。此选项可以多次使用。
--additional-hooks-dir HOOKSPATH 搜索挂钩的其他路径。此选项可以多次使用。
--runtime-hook RUNTIME_HOOKS 自定义运行时挂接文件的路径。运行时挂钩是与可执行文件捆绑在一起的代码,在任何其他代码或模块之前执行,以设置运行时环境的特殊功能。此选项可以多次使用。
--exclude-module EXCLUDES 将被忽略的可选模块或包(Python名称,而不是路径名)(好像没有找到)。此选项可以多次使用。
--key KEY 用于加密Python字节码的密钥。
细节

 

3.运行原理

PyInstaller 运行时会对脚本进行解析,并做出如下动作:

  1. 在脚本目录生成 eee.spec 文件;
  2. 创建一个 build 目录;
  3. 写入一些日志文件和中间流程文件到 build 目录;
  4. 创建 dist 目录;
  5. 生成可执行文件到 dist 目录;
 pyinstaller -F .\eee.py

将 Python 程序打包成 .exe 文件_python_05

将 Python 程序打包成 .exe 文件_bundle_06

dest 目录中可以找到可执行 .exe 文件

将 Python 程序打包成 .exe 文件_sed_07

 

 注意事项

1、直接运行最终的 .exe 程序,可能会出现一闪而过的情况。这种情况下有两种可能1.是程序运行结束(比如直接打印的 123 )2.程序出现错误退出

  这种情况下,建议在命令行 cmd 下运行 .exe 文件,这时就会有文本输出到窗口

2、写代码的时候应当有个良好的习惯,需要具体导入,不要 import 整个库,可能一个 100KB 的代码打包出来有 500MB

3、需要使用外部数据源的,是不会自动导入的,需要手动复制。否则 exe 文件运行时命令窗口会报错找不到这个文件

 

4.使用外部数据源

要把这些资源文件包含进去,可以给pyinstaller添加选项,也可以修改spec文件。

还是分为两种,生成oefolder和onefile

4.1生成并修改spec文件

onefolder

pyi-makespec transc_transfer_reject_report.py

1.文件.py与外部数据源放在同一个目录底下,生成spec文件:

 将 Python 程序打包成 .exe 文件_bundle_08

 

2.修改test.spec

添加过程还是很简单的,看图中红框部分就是。前面pyinstaller 自动生成的spec文件中,datas原本是空的:
datas=[] 一个空的list,把要添加的资源文件以tuple的形式传入。
tuple的第一个元素是资源文件的路径,第二个元素是打包后存放资源的文件夹。比如:
('text.exe', '.')
就是把 'Xgo_Report_transc.xlsx' 打包后放到.目录下面。
打包后的目录跟Python代码的目录结构一直即可,'Xgo_Report_transc.xlsx' 原先放在.下面可以让程序运行,
那么打包后也放在.下面即可。在spec文件中添加好要包含的资源文件再次打包就可以把资源文件打包到最终的exe文件

将 Python 程序打包成 .exe 文件_sed_09

3.导包成exe文件

pyinstaller transc_transfer_reject_report.spec

 一些第三方包依赖的事情就需要自己去解决。在.py文件中手动import然后自己再执行1-3操作

4.执行exe文件

 

onefile

 

 

pyi-makespec -F transc_transfer_reject_report.py

 

修改相应的spec表的依赖

pyinstaller transc_transfer_reject_report.spec

 

 

           请看这位大佬的博客

 

4.2给pyinstaller添加选项

 其中,最后的“--clean”命令是清缓存,

--add-data <SRC;DEST or SRC:DEST> #增加非二进制文件到目录下,windows以;分隔而且得用双引号包含,而*NIX以:分隔
--add-binary <SRC;DEST or SRC:DEST> #增加二进制文件到目录下

命令如下:

pyinstaller --add-data=transc_stats_sql.sql;.  --add-data=transfer_reject_stats.sql;. 
            --add-binary=Xgo_Report_transc.xlsx;.  --add-binary=Xgo_Report_transfer_reject.xlsx;. --onefile --clean transc_transfer_reject_report.py

看到其他博客踩坑:

将 Python 程序打包成 .exe 文件_可执行文件_10

 

 

4.4依赖报错

我用到了sqlalchemy第三方库,但是打包的时候并没有一起把他的依赖包pymysql一起打包进去。

所以最终报错,只能在原py文件中import pymysql然后重新执行4.1-4.3操作!

大多数人都以为是才智成就了科学家,他们错了,是品格。---爱因斯坦