在 Google App Engine 中将 docx 文件呈现为 django 模板

Posted

技术标签:

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

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

    使用其 downloadUrl 从谷歌驱动器下载 docx 文件 将下载的文件传递到python-docx模块中以提取文本 将提取的文本传递给 Django 以呈现 Django 变量 使用 python-docx 将文本写回 docx 最后将 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/…) 的文档 【参考方案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。

【讨论】:

以上是关于在 Google App Engine 中将 docx 文件呈现为 django 模板的主要内容,如果未能解决你的问题,请参考以下文章

Google App Engine - 向 db.model 的子类添加方法

在 Google-App-Engine 中使用 HSQLDB

连接 Google App Engine 和 Google Compute Engine

如何在 Google Cloud App Engine 上使用 PubSub 创建订阅者,该订阅者通过 Publisher 从 Google Cloud App Engine Flex 收听消息?

Google Cloud 中的 Google Compute Engine、App Engine 和 Container Engine 有啥区别?

Google-App-Engine 上的 Grails - 它死了吗? [关闭]