如何封装将控制台打印到 Word 的方法
How to encapsulate method to print console out to Word
我想有时将我的摘要统计信息打印到控制台,有时也打印到 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 的摘录。您可以看到它是如何充满打印行的,这在我仍在探索数据时很有用,而且我不想通过添加到列表中来摆脱 of/replace:
Document()
constructor essentially creates the .docx file package(这实际上是 XML 的 lots 和其他内容的 .zip 存档,后来 Word应用程序解析和呈现等)。
此语句 f = open(filename, 'w')
打开该文件对象(注意:这不会打开 Word 应用程序,也不会打开 Word 文档实例),然后将标准输出转储到该对象中。那是 100% 的时间会导致损坏的 Word 文档;因为您根本无法 以这种方式将 写入 word 文档。您基本上是在创建一个带有 docx 扩展名的纯文本文件,但是底层 "guts" 的 none 使 docx 成为 docx。结果,Word 应用程序不知道如何处理它。
修改您的代码,使此 "summary" 过程 returns 成为一个可迭代对象(此可迭代对象中的项目将是您要放入 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)
最简单的方法是让 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)
所以也许有更好的方法,但最后我
- 从我的摘要统计脚本中创建了一个函数
def run_summary
- 根据@Charles Duffy 的回答
def print_word
创建了一个函数,其中 StringIO
从 RunSummaryStats.run_summary(filepath, filename)
读取
- 在我的最后一个模块中调用了
def_print_word
。我在那里设置了路径、文件名和原始数据源的变量,如下所示:
PrintScriptToWord.print_word(ATSpath, RSBSfilename, curr_file + ".docx")
我欢迎任何改进此方法或其他方法的建议。
我想有时将我的摘要统计信息打印到控制台,有时也打印到 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 的摘录。您可以看到它是如何充满打印行的,这在我仍在探索数据时很有用,而且我不想通过添加到列表中来摆脱 of/replace:
Document()
constructor essentially creates the .docx file package(这实际上是 XML 的 lots 和其他内容的 .zip 存档,后来 Word应用程序解析和呈现等)。
此语句 f = open(filename, 'w')
打开该文件对象(注意:这不会打开 Word 应用程序,也不会打开 Word 文档实例),然后将标准输出转储到该对象中。那是 100% 的时间会导致损坏的 Word 文档;因为您根本无法 以这种方式将 写入 word 文档。您基本上是在创建一个带有 docx 扩展名的纯文本文件,但是底层 "guts" 的 none 使 docx 成为 docx。结果,Word 应用程序不知道如何处理它。
修改您的代码,使此 "summary" 过程 returns 成为一个可迭代对象(此可迭代对象中的项目将是您要放入 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)
最简单的方法是让 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)
所以也许有更好的方法,但最后我
- 从我的摘要统计脚本中创建了一个函数
def run_summary
- 根据@Charles Duffy 的回答
def print_word
创建了一个函数,其中StringIO
从RunSummaryStats.run_summary(filepath, filename)
读取
- 在我的最后一个模块中调用了
def_print_word
。我在那里设置了路径、文件名和原始数据源的变量,如下所示:
PrintScriptToWord.print_word(ATSpath, RSBSfilename, curr_file + ".docx")
我欢迎任何改进此方法或其他方法的建议。