【问题标题】:Rendering docx files as django templates in Google App Engine在 Google App Engine 中将 docx 文件呈现为 django 模板
【发布时间】:2014-12-14 03:08:48
【问题描述】:

我正在尝试使用 Django 模板呈现存储在 google 驱动器中的 word 文档文件 (docx) 的内容。 word文档文件(docx)是带有django变量的模板。 将文件转换为 google docs 格式将使 docx 文件失去其字体和样式格式,因此我试图在 google 应用引擎中实现以下步骤

  1. 使用其 downloadUrl 从谷歌驱动器下载 docx 文件
  2. 将下载的文件传递到python-docx模块中以提取文本
  3. 将提取的文本传递给 Django 以呈现 Django 变量
  4. 使用 python-docx 将文本写回 docx
  5. 最后将 docx 文件上传到另一个 google drive 帐户。

我在尝试将下载的文件传递到 python-docx 时遇到问题here
以下是我在谷歌应用引擎中的代码

    downloadUrl = searchResult.get('items')[1]['downloadUrl']
    if downloadUrl:
      resp, tempContent = drive_service._http.request(downloadUrl)
      if resp.status == 200:
        f  = StringIO.StringIO(tempContent)
        document = Document(f)
        para = document.paragraphs()
        print para
        f.close()

上面的代码给出了以下错误:

      para = document.paragraphs()
      TypeError: 'list' object is not callable

这是我在 Django 模板中渲染提取的文本的代码

        myTemplate = Template(tempContent)
        c = Context({ 
                     "salutation": "William", 
                     "inventionTitle":"Biometric KeyLock"
                     })
        fullContent =  myTemplate.render(c)

下载文件的mimetype是:

application/vnd.openxmlformatsofficedocument.wordprocessingml.document

我的问题是,我不知道如何处理下载的文件。我想在不丢失格式的情况下替换存储在谷歌驱动器中的 word docx 中的占位符/变量,然后将其上传回谷歌驱动器。

如果有更好的实现方式,请告诉我。

谢谢。

【问题讨论】:

  • 错误信息告诉你所有你需要知道的:document.paragraphs不是一个方法,不要试图调用它。但在完成这项工作之前,您还有一大堆工作需要解决:就在我的脑海中,您希望如何将数据返回到 word doc 的正确位置?
  • 感谢 Daniel,但根据文档 >>> def paragraphs(self): """ 与文档中的段落相对应的 |Paragraph| 实例列表,按文档顺序排列。注意段落在 <w:ins><w:del> 等修订标记内不会出现在此列表中。""" return self._document_part.paragraphs`
  • 链接到 [python-docx] (python-docx.readthedocs.org/en/latest/_modules/docx/…) 的文档

标签: python django google-app-engine ms-word django-templates


【解决方案1】:

类似...的错误

  TypeError: 'list' object is not callable

...一般意味着你有一个列表([]),它不是一个可调用对象,这意味着你不能在它后面加上括号来调用它:

>>> []()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable

那个对象很可能就是你想要的数据负载。试着去掉括号,让我们知道你得到了什么!

para = document.paragraphs

每个段落都可能是一个您可以操作的对象,即合并/渲染带有上下文的 Django/Jinja2 模板等。例如,如果您想要文本,您可能必须使用 .text 提取它,在Paragraph object docs page:

中指定
for para in document.paragraphs:
    print(para.text)

我没有使用 python-docx 的经验,但如果你能做这样的事情会很酷:

for para in document.paragraphs:
    myTemplate = Template(para.text)
    c = Context({ 
                 "salutation": "William", 
                 "inventionTitle":"Biometric KeyLock"
                 })
    para.text = myTemplate.render(c)

但实际上,这可能行不通,因为您可能只在一个段落中有各种文本格式,这意味着您可能需要开始调查“runs”文本区域一组共同的属性。另请参阅docs page on Runs

要保留格式,您可能必须将整个文档作为一个整体来查看,并对模板变量执行单独的 search-n-replace。虽然这个问题不涉及Google Slides API,但其文本在文档中的结构方式类似于 Word 和 Google Docs,因此其text concepts guide 可能是一个有用的参考。

最后,提醒一下 Drive API v2 不再是最新的 API 版本。它现在在 v3 上,downloadUrl 已被弃用。要查看替代方案,请查看Drive API v2-v3 migration guide。要查看您可能会使用的一些实际 v3 代码并调整 source & destination MIMEtypes,请查看我的“将 Google 表格文件导出为 CSV”blog post

【讨论】:

    猜你喜欢
    • 2013-03-04
    • 2012-06-09
    • 2012-03-23
    • 2011-12-19
    • 2022-01-15
    • 2011-03-31
    • 2010-10-20
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多