简体   繁体   English

py2exe / py2app和docx不能一起使用

[英]py2exe/py2app and docx don't work together

Installed docx on Windows 7 here: Windows 7上的docx安装如下:

D:\\Program Files (x86)\\Python27\\Lib\\site-packages as shown below: D:\\ Program Files(x86)\\ Python27 \\ Lib \\ site-packages,如下所示:

在此处输入图片说明

Installed docx on OS X at /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/docx-0.0.2-py2.7.egg-info as shown below: 在OS X的/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/docx-0.0.2-py2.7.egg-info中安装了docx,如下所示: 在此处输入图片说明

Following is the sample script (named as docx_example.py), which runs absolutely fine on the python interpreter: 以下是示例脚本(名为docx_example.py),该脚本在python解释器上运行得非常好:

#!/usr/bin/env python
'''
This file makes an docx (Office 2007) file from scratch, showing off most of python-docx's features.

If you need to make documents from scratch, use this file as a basis for your work.

Part of Python's docx module - http://github.com/mikemaccana/python-docx
See LICENSE for licensing information.
'''
from docx import *

if __name__ == '__main__':        
    # Default set of relationshipships - these are the minimum components of a document
    relationships = relationshiplist()

    # Make a new document tree - this is the main part of a Word document
    document = newdocument()

    # This xpath location is where most interesting content lives 
    docbody = document.xpath('/w:document/w:body', namespaces=nsprefixes)[0]

    # Append two headings and a paragraph
    docbody.append(heading('''Welcome to Python's docx module''',1)  )   
    docbody.append(heading('Make and edit docx in 200 lines of pure Python',2))
    docbody.append(paragraph('The module was created when I was looking for a Python support for MS Word .doc files on PyPI and Stackoverflow. Unfortunately, the only solutions I could find used:'))

    # Add a numbered list
    for point in ['''COM automation''','''.net or Java''','''Automating OpenOffice or MS Office''']:
        docbody.append(paragraph(point,style='ListNumber'))
    docbody.append(paragraph('''For those of us who prefer something simpler, I made docx.''')) 

    docbody.append(heading('Making documents',2))
    docbody.append(paragraph('''The docx module has the following features:'''))

    # Add some bullets
    for point in ['Paragraphs','Bullets','Numbered lists','Multiple levels of headings','Tables','Document Properties']:
        docbody.append(paragraph(point,style='ListBullet'))

    docbody.append(paragraph('Tables are just lists of lists, like this:'))
    # Append a table
    docbody.append(table([['A1','A2','A3'],['B1','B2','B3'],['C1','C2','C3']]))

    docbody.append(heading('Editing documents',2))
    docbody.append(paragraph('Thanks to the awesomeness of the lxml module, we can:'))
    for point in ['Search and replace','Extract plain text of document','Add and delete items anywhere within the document']:
        docbody.append(paragraph(point,style='ListBullet'))

    # Search and replace
    print 'Searching for something in a paragraph ...',
    if search(docbody, 'the awesomeness'): print 'found it!'
    else: print 'nope.'

    print 'Searching for something in a heading ...',
    if search(docbody, '200 lines'): print 'found it!'
    else: print 'nope.'

    print 'Replacing ...',
    docbody = replace(docbody,'the awesomeness','the goshdarned awesomeness') 
    print 'done.'

    # Add a pagebreak
    docbody.append(pagebreak(type='page', orient='portrait'))

    docbody.append(heading('Ideas? Questions? Want to contribute?',2))
    docbody.append(paragraph('''Email <python.docx@librelist.com>'''))

    # Create our properties, contenttypes, and other support files
    coreprops = coreproperties(title='Python docx demo',subject='A practical example of making docx from Python',creator='Mike MacCana',keywords=['python','Office Open XML','Word'])
    appprops = appproperties()
    contenttypes = contenttypes()
    websettings = websettings()
    wordrelationships = wordrelationships(relationships)

    # Save our document
    savedocx(document,coreprops,appprops,contenttypes,websettings,wordrelationships,'docx_example.docx')

Following is the setup script (named as docx_setup.py) to create the standalone (.app in Mac OSX and .exe in Windows 7): 以下是用于创建独立(Mac OSX中的.app和Windows 7中的.exe)的安装脚本(命名为docx_setup.py):

import sys,os

# Globals: START
main_script='docx_example'
dist_dir_main_path=os.path.abspath('./docx-bin')
compression_level=2
optimization_level=2
bundle_parameter=1
skip_archive_parameter=False
emulation_parameter=False
module_cross_reference_parameter=False
ascii_parameter=False
includes_list=['lxml.etree','lxml._elementpath','gzip']
# Globals: STOP

# Global Functions: START
def isDarwin():
    return sys.platform=='darwin'

def isLinux():
    return sys.platform=='linux2'

def isWindows():
    return os.name=='nt'
# Global Functions: STOP

if isDarwin():
    from setuptools import setup

    # Setup distribution directory: START
    dist_dir=os.path.abspath('%s/osx' %(dist_dir_main_path))
    if os.path.exists(dist_dir):
        os.system('rm -rf %s' %(dist_dir))
    os.system('mkdir -p %s' %(dist_dir))
    # Setup distribution directory: STOP

    APP = ['%s.py' %(main_script)]
    OPTIONS={'argv_emulation': False,
             'dist_dir': dist_dir,
             'includes': includes_list
            }
    print 'Creating standalone now...'
    setup(app=APP,options={'py2app': OPTIONS},setup_requires=['py2app'])
    os.system('rm -rf build')
    os.system('tar -C %s -czf %s/%s.tgz %s.app' %(dist_dir,dist_dir,main_script,main_script))
    os.system('rm -rf %s/%s.app' %(dist_dir,main_script))    
    print 'Re-distributable Standalone file(s) created at %s/%s.zip. Unzip and start using!!!' %(dist_dir,main_script)    

elif isWindows():
    from distutils.core import setup
    import py2exe

    # Setup distribution directory: START
    dist_dir=os.path.abspath('%s/win' %(dist_dir_main_path))
    if os.path.exists(dist_dir):
        os.system('rmdir /S /Q %s' %(dist_dir))
    os.system('mkdir %s' %(dist_dir))
    # Setup distribution directory: STOP

    OPTIONS={'compressed': compression_level,
             'optimize': optimization_level,
             'bundle_files': bundle_parameter,
             'dist_dir': dist_dir,
             'xref': module_cross_reference_parameter,
             'skip_archive': skip_archive_parameter,
             'ascii': ascii_parameter,
             'custom_boot_script': '',
             'includes': includes_list
            }
    print 'Creating standalone now...'
    setup(options = {'py2exe': OPTIONS},zipfile = None,windows=[{'script': '%s.py' %(main_script)}])
    print 'Re-distributable Standalone file(s) created in the following location: %s' %(dist_dir)
    os.system('rmdir /S /Q build')

Now comes the real problem. 现在出现了真正的问题。

Following is the error posted on Mac OS X console after trying to use the docx_example.app, created using the command python docx_setup.py py2app: 以下是尝试使用通过命令python docx_setup.py py2app创建的docx_example.app后在Mac OS X控制台上发布的错误:

docx_example: Searching for something in a paragraph ... found it!
docx_example: Searching for something in a heading ... found it!
docx_example: Replacing ... done.
docx_example: Traceback (most recent call last):
docx_example:   File "/Users/admin/docx-bin/osx/docx_example.app/Contents/Resources/__boot__.py", line 64, in <module>
docx_example:     _run('docx_example.py')
docx_example:   File "/Users/admin/docx-bin/osx/docx_example.app/Contents/Resources/__boot__.py", line 36, in _run
docx_example:     execfile(path, globals(), globals())
docx_example:   File "/Users/admin/docx-bin/osx/docx_example.app/Contents/Resources/docx_example.py", line 75, in <module>
docx_example:     savedocx(document,coreprops,appprops,contenttypes,websettings,wordrelationships,'docx_example.docx')
docx_example:   File "docx.pyc", line 849, in savedocx
docx_example: AssertionError
docx_example: docx_example Error
docx_example Exited with code: 255

Following is the error posted in docx_example.exe.log file in Windows 7 after trying to use the docx_example.exe, created using the command python docx_setup.py py2exe: 以下是尝试使用通过命令python docx_setup.py py2exe创建的docx_example.exe后,Windows 7中docx_example.exe.log文件中发布的错误:

Traceback (most recent call last):
  File "docx_example.py", line 75, in <module>
  File "docx.pyo", line 854, in savedocx
WindowsError: [Error 3] The system cannot find the path specified: 'D:\\docx_example\\docx_example.exe\\template'

As you can see, both OS X and Windows 7 are referring to something similar here. 如您所见,OS X和Windows 7都在此处指的是类似内容。 Please help. 请帮忙。

i have found a solution 我找到了解决方案

in api.py 在api.py中

From

_thisdir = os.path.split(__file__)[0]

To

_thisdir = 'C:\Python27\Lib\site-packages\docx'

Or whatever your docx file is 或任何您的docx文件

What's going on (at least for py2exe) is something similar to this question . 发生了什么(至少对于py2exe来说)类似于此问题

The documentation on data_files is here . 有关data_files的文档在此处

What you basically have to do is change 您基本上要做的就是改变

setup(options = {'py2exe': OPTIONS},zipfile = None,windows=[{'script': '%s.py' %(main_script)}])

to

data_files = [
    ('template', 'D:/Program Files (x86)/Python27/Lib/site-packages/docx-template/*'), 
]

setup(
    options={'py2exe': OPTIONS},
    zipfile=None,
    windows=[{'script': '%s.py' %(main_script)}],
    data_files=data_files
)

The exact place where the template files are may be wrong above, so you might need to adjust it. 上面的模板文件的确切位置可能有误,因此您可能需要对其进行调整。

But there may be several other sets of data_files you need to include. 但是可能还需要包含其他几组data_files。 You may want to go about retrieving them programatically with an os.listdir or os.walk type of command. 您可能需要使用os.listdiros.walk类型的命令以编程方式检索它们。

As mentioned in the other post, you will also have to change 如另一篇文章中所述,您还必须进行更改

bundle_parameter=1

to

bundle_parameter=2

at the top of the file. 在文件的顶部。

You can solve the entire problem by using this API which is based in python-docx . 您可以使用基于python-docx API来解决整个问题。 The advantage of the API is that this one doesnt have the savedoc function so you will not have any other AssertionError . 该API的优点是该API不具有savedoc函数,因此您不会有任何其他AssertionError

For the WindowsError: [Error 3] The system cannot find the path specified: 'D:\\\\docx_example\\\\docx_example.exe\\\\template' error you need to edit the api.py file of docx egg folder which is located in the Python folder of the system (in my computer: C:\\Python27\\Lib\\site-packages\\python_docx-0.3.0a5-py2.7.egg\\docx ) 对于WindowsError: [Error 3] The system cannot find the path specified: 'D:\\\\docx_example\\\\docx_example.exe\\\\template'错误,您需要编辑docx egg文件夹中的api.py文件。系统的Python文件夹(在我的计算机中: C:\\Python27\\Lib\\site-packages\\python_docx-0.3.0a5-py2.7.egg\\docx

Changing this: 改变这个:

_thisdir = os.path.split(__file__)[0]
_default_docx_path = os.path.join(_thisdir, 'templates', 'default.docx')

To this: 对此:

thisdir = os.getcwd()
_default_docx_path = os.path.join(thisdir, 'templates', 'default.docx')

The first one was taking the actual running program and adding it to the path to locate the templates folder. 第一个是获取实际正在运行的程序,并将其添加到路径中以找到templates文件夹。
C:\\myfiles\\myprogram.exe\\templates\\default.docx

The solution takes only the path, not the running program. 该解决方案仅采用路径,而不采用正在运行的程序。
C:\\myfiles\\templates\\default.docx

Hope it helps! 希望能帮助到你!

Instead of changing some library file, I find it easier and cleaner to tell python-docx explicitly where to look for the template, ie: 我发现无需更改某些库文件,而是更轻松,更清晰地明确告诉python-docx在哪里寻找模板,即:

document = Document('whatever/path/you/choose/to/some.docx')

This effectively solves the py2exe and docx path problem. 这有效地解决了py2exe和docx路径问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM