Skip to main content
 首页 » 编程设计

python之Django 和 python-docx

2024年08月28日28jpfss

我正在尝试通过 python-docx 创建一个 docx 文件和 Django 。

直接使用 python 运行示例脚本 (example-makedocument.py) 是可行的。又名“工作副本”。它按预期生成示例 docx 文件。

然后我所做的是尝试将该 example-makedocument.py 代码移动到 Django View 中。这篇文章底部的代码是该 View 的代码。您会看到我预先做了一些小修改,但总体上没有变化。

运行此 View 时,出现无法找到图像文件的错误。

[Errno 2] No such file or directory: 'image1.png' 

我有:

  • 确保文件夹/文件结构与工作副本相同(它需要其子文件夹才能正常工作)
  • 我已尝试将 docx.py template_dir 硬编码到保存文件夹/文件的位置(我已检查这些结果指向与工作副本相同的最终路径)<
  • 我已经从示例中删除了图像,但这会导致错误 local variable 'contenttypes' referenced before assignment

我认为它与路径有关,但我不确定为什么/如何?谁能帮忙?

完整的 python-docx 代码可用 here .

我的看法:

from myapp.libs.docx.docx import * 
# ** commented out below line, replaced with above ** 
#from docx import * 
 
def export_docx(request): 
 
# ** commented out below line ** 
#if __name__ == '__main__': 
    # Default set of relationshipships - 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 
    body = document.xpath('/w:document/w:body', namespaces=nsprefixes)[0] 
 
    # Append two headings and a paragraph 
    body.append(heading("Welcome to Python's docx module", 1)) 
    body.append(heading('Make and edit docx in 200 lines of pure Python', 2)) 
    body.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 
    points = [ 'COM automation' 
             , '.net or Java' 
             , 'Automating OpenOffice or MS Office' 
             ] 
    for point in points: 
        body.append(paragraph(point, style='ListNumber')) 
    body.append(paragraph('For those of us who prefer something simpler, I ' 
                          'made docx.')) 
    body.append(heading('Making documents', 2)) 
    body.append(paragraph('The docx module has the following features:')) 
 
    # Add some bullets 
    points = ['Paragraphs', 'Bullets', 'Numbered lists', 
              'Multiple levels of headings', 'Tables', 'Document Properties'] 
    for point in points: 
        body.append(paragraph(point, style='ListBullet')) 
 
    body.append(paragraph('Tables are just lists of lists, like this:')) 
    # Append a table 
    tbl_rows = [ ['A1', 'A2', 'A3'] 
               , ['B1', 'B2', 'B3'] 
               , ['C1', 'C2', 'C3'] 
               ] 
    body.append(table(tbl_rows)) 
 
    body.append(heading('Editing documents', 2)) 
    body.append(paragraph('Thanks to the awesomeness of the lxml module, ' 
                          'we can:')) 
    points = [ 'Search and replace' 
             , 'Extract plain text of document' 
             , 'Add and delete items anywhere within the document' 
             ] 
    for point in points: 
        body.append(paragraph(point, style='ListBullet')) 
 
    # Add an image 
    relationships, picpara = picture(relationships, 'image1.png', 
                                     'This is a test description') 
    body.append(picpara) 
 
    # Search and replace 
    print 'Searching for something in a paragraph ...', 
    if search(body, 'the awesomeness'): 
        print 'found it!' 
    else: 
        print 'nope.' 
 
    print 'Searching for something in a heading ...', 
    if search(body, '200 lines'): 
        print 'found it!' 
    else: 
        print 'nope.' 
 
    print 'Replacing ...', 
    body = replace(body, 'the awesomeness', 'the goshdarned awesomeness') 
    print 'done.' 
 
    # Add a pagebreak 
    body.append(pagebreak(type='page', orient='portrait')) 
 
    body.append(heading('Ideas? Questions? Want to contribute?', 2)) 
    body.append(paragraph('Email <python.docx@librelist.com>')) 
 
    # Create our properties, contenttypes, and other support files 
    title    = 'Python docx demo' 
    subject  = 'A practical example of making docx from Python' 
    creator  = 'Mike MacCana' 
    keywords = ['python', 'Office Open XML', 'Word'] 
 
    coreprops = coreproperties(title=title, subject=subject, creator=creator, 
                               keywords=keywords) 
    appprops = appproperties() 
    contenttypes = contenttypes() 
    websettings = websettings() 
    wordrelationships = wordrelationships(relationships) 
 
    # Save our document 
    savedocx(document, coreprops, appprops, contenttypes, websettings, 
             wordrelationships, 'Welcome to the Python docx module.docx') 

========

已更新。下面提供了我找到的解决方案的详细信息。

docx.py 代码假定路径与实际路径不同。这导致 image1.png 文件“丢失”。完成以下步骤为我解决了这个问题。

  1. 编辑了 docx.py 文件并添加了一个变量:

    docx_dir = '/path/to/docx/folder'

  2. 编辑以下行 (docx.py) 以使用上述变量(显示大约行号,与原始来源略有不同)

    1. shutil.copyfile(join(docx_dir, picname), join(media_dir, picname))
    2. pixelwidth, pixelheight = Image.open(join(docx_dir, picname)).size[0:2]
  3. 以上解决了路径问题。但现在我遇到了错误local variable 'contenttypes' referenced before assignment。我发现错误已解决,与路径无关,而是名称重复(我不完全理解为什么仍然如此)。

注意:下面的代码位于我的 View 中,或者..如果与 example-makedocument.py

中的原始源进行比较

之前:

contenttypes = contenttypes() 
websettings = websettings() 
wordrelationships = wordrelationships(relationships) 

之后:

contentt = contenttypes() 
webs = websettings() 
wordr = wordrelationships(relationships) 
 
# Save our document 
savedocx(document, coreprops, appprops, contentt, webs, 
         wordr, 'Welcome to the Python docx module.docx') 

请您参考如下方法:

image1.png 必须在运行的 Python 程序的当前目录中,或者作为运行程序的当前目录的相对路径给出,或者不太便携,但可能更容易制作工作,它可以作为绝对路径给出。

特别是,我认为您可能会发现这篇文章中给出的答案最有帮助:Python's working directory when running with WSGI and Apache (用于动态找出 image.png 的绝对路径。