如何封装将控制台打印到Word的方法

时间:2019-07-08 19:15:41

标签: python automation docx data-analysis

我有时希望将摘要统计信息打印到控制台,而有时需要打印到Word。

我不希望我的代码被调用Word的行所困扰,因为那样的话,每次我只想要控制台输出时,我都需要查找并注释掉100行。

我已经考虑过在前面使用标志变量,并在我想打印而不是不打印时将其更改为false,但这也很麻烦。

我想到的最好的解决方案是编写一个单独的脚本来打开一个文档,通过调用我的第一个摘要状态脚本来编写,然后关闭该文档:

import sys
import RunSummaryStats
from docx import Document

filename = "demo.docx"
document = Document()
document.save(filename)
f = open(filename, 'w')
sys.stdout = f

# actually call my summary stats script here: Call RunSummaryStats etc.
print("5")

f.close()

但是,当我尝试使用python docx进行上述操作时,在打开我的文档文件时,我收到了错误We're sorry, we can't open this document because some parts are missing or invalid.,如您所见,上面的代码只是打印出一个数字,因此无法我要写入的数据有问题。

最后,它需要使用Word而不是其他文件格式来格式化某些数据表。

顺便说一下,这是RunSummaryStats的摘录。您可以看到它已经充满了打印行,这些行在我仍在浏览数据时很有用,并且我不想在添加列表时摆脱/替换它: enter image description here

3 个答案:

答案 0 :(得分:0)

Document() constructor essentially creates the .docx file package(实际上是XML和其他内容的很多的.zip归档文件,后来Word应用程序对其进行解析和渲染等。) / p>

此语句f = open(filename, 'w')打开该文件对象(注意:这不会打开Word应用程序,也不会打开Word Document实例),然后将标准输出转储到该对象中。那是100%的时间会导致Word文档损坏;因为您根本无法通过写入Word文档。您基本上是在创建带有docx扩展名的纯文本文件,但是没有一个使docx成为docx的基础“内胆”。结果,Word应用程序不知道如何处理它。

修改您的代码,以便此“摘要”过程返回一个可迭代项(此可迭代项中的项目将是您要放入Word文档中的任何项目)。然后,您可以使用类似add_paragraph方法的方法将每个项目添加到Word文档中。

def get_summary_stats(console=False):
    """
        if console==True, results will be printed to console
        returns a list of string for use elsewhere
    """
    # hardcoded, but presume you will actually *get* these information somehow, modify as needed:
    stats = ["some statistics about something", "more stuff about things"]
    if console:
        for s in stats:
            print(s)
    return stats

然后:

filename = "demo.docx"
document = Document()

# True will cause this function to print to console
for stat in get_summary_stats(True):
    document.add_paragraph(stat)
document.save(filename)

答案 1 :(得分:0)

最简单的方法是让cStringIO完成工作,并从收集所有数据到将其写入文件中分离出来。那就是:

import RunSummaryStats
import sys

# first, collect all your data into a StringIO object
orig_stdout = sys.stdout
stat_buffer = cStringIO.StringIO()
sys.stdout = stat_buffer
try:
    # actually call my summary stats script here: Call RunSummaryStats etc.
    print("5")
finally:
    sys.stdout = orig_stdout

# then, write the StringIO object's contents to a Document.
from docx import Document
filename = "demo.docx"
document = Document()
document.write(add_paragraph(stat_buffer.getvalue()))
document.save(filename)

答案 2 :(得分:0)

所以也许有更好的方法,但是最后我

  1. 从摘要统计信息脚本def run_summary中创建了一个函数
  2. 基于@Charles Duffy的答案def print_word创建了一个函数,其中StringIORunSummaryStats.run_summary(filepath, filename)中读取
  3. 在我的最终模块中,
  4. 称为def_print_word。在那里,我为路径,文件名和原始数据源设置了变量,如下所示:

PrintScriptToWord.print_word(ATSpath, RSBSfilename, curr_file + ".docx")

我欢迎提出任何改进此方法或其他方法的建议。