我有时希望将摘要统计信息打印到控制台,而有时需要打印到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的摘录。您可以看到它已经充满了打印行,这些行在我仍在浏览数据时很有用,并且我不想在添加列表时摆脱/替换它:
答案 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)
所以也许有更好的方法,但是最后我
def run_summary
中创建了一个函数def print_word
创建了一个函数,其中StringIO
从RunSummaryStats.run_summary(filepath, filename)
中读取def_print_word
。在那里,我为路径,文件名和原始数据源设置了变量,如下所示: PrintScriptToWord.print_word(ATSpath, RSBSfilename, curr_file + ".docx")
我欢迎提出任何改进此方法或其他方法的建议。