cx_freeze和docx - 冻结时的问题

时间:2016-09-07 07:21:39

标签: python python-3.x cx-freeze python-docx

我有一个简单的程序,它从用户那里获取输入,然后使用selenium进行抓取。由于用户没有安装Python环境,我想将其转换为* .exe。我通常使用cx_freeze,并且已成功将.py程序转换为.exe。起初它缺少一些模块(如lxml),但我能够解决它。现在我觉得我只对docx包有问题。

这就是我在程序中启动新文档的方式(我想这就是导致我出现问题的原因):

doc = Document()
#then I do some stuff to it and add paragraph and in the end...
doc.save('results.docx')

当我从python运行它时一切正常但是当我转换为exe时我得到了这个错误:

Traceback (most recent call last):
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>

    exec(code, m.__dict__)
  File "tribunalRio.py", line 30, in <module>
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\api.py", line 25, in Document
    document_part = Package.open(docx).main_document_part
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\package.py", line 116, in open
    pkg_reader = PackageReader.from_file(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\pkgreader.py", line 32, in from_file
    phys_reader = PhysPkgReader(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\phys_pkg.py", line 31, in __new__
    "Package not found at '%s'" % pkg_file
docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:\Users\tyszkap\Dropbox (Dow Jones)\Python Projects\build\exe.win-a
md64-3.4\library.zip\docx\templates\default.docx'

这是我的setup.py程序:

from cx_Freeze import setup, Executable

executable = Executable( script = "tribunalRio.py" )

# Add certificate to the build
options = {
    "build_exe": {'include_files' : ['default.docx'],
        'packages' : ["lxml._elementpath", "inspect", "docx", "selenium"]
    }
}

setup(
    version = "0",
    requires = [],
    options = options,
    executables = [executable])

我认为明确地将default.docx添加到包中可以解决问题(我甚至尝试将它添加到library.zip但它给了我更多的错误)但它没有。我看过这个post,但我不知道它们是什么意思:

  

在我的函数中复制docx document.py模块(而不是   使用Document()

有什么想法吗?我知道冻结不是最好的解决方案,但我真的不想为这么简单的程序构建一个Web界面...

编辑:

我刚试过this solution

def find_data_file(filename):
    if getattr(sys, 'frozen', False):
        # The application is frozen
        datadir = os.path.dirname(sys.executable)
    else:
        # The application is not frozen
        # Change this bit to match where you store your data files:
        datadir = os.path.dirname(__file__)

    return os.path.join(datadir, filename)

doc = Document(find_data_file('default.docx'))

但再次收到Traceback错误(但文件位于此位置......):

Traceback (most recent call last):
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>

    exec(code, m.__dict__)
  File "tribunalRio.py", line 43, in <module>
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\api.py", line 25, in Document
    document_part = Package.open(docx).main_document_part
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\package.py", line 116, in open
    pkg_reader = PackageReader.from_file(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\pkgreader.py", line 32, in from_file
    phys_reader = PhysPkgReader(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\phys_pkg.py", line 31, in __new__
    "Package not found at '%s'" % pkg_file
docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:\Users\tyszkap\Dropbox (Dow Jones)\Python Projects\build\exe.win-a
md64-3.4\default.docx'

我做错了什么?

2 个答案:

答案 0 :(得分:0)

我希望你会发现问题与你的冻结操作有关,而不是将默认的Document()模板放在预期的位置。它作为包数据存储在python-docx包中docx/templates/default.docx(请参阅setup.py:https://github.com/python-openxml/python-docx/blob/master/setup.py#L37

我不知道如何解决这个问题,但这就是问题所在。

答案 1 :(得分:0)

我遇到了同样的问题,并通过执行以下操作设法绕过它。首先,我找到了site-packages中的default.docx文件。然后,我将它复制到与.py文件相同的目录中。我还启动了带有Document()的.docx文件,该文件有一个docx = ...标志,我为其分配了值os.path.join(os.getcwd(), 'default.docx'),现在它看起来像doc = Document(docx=os.path.join(os.getcwd(), 'default.docx'))。最后一步是将文件包含在冻结过程中。 Etvoilà!到目前为止我没有问题。