Я хочу позволить пользователю отправить файл MS Word в мое приложение, обработать его с помощью библиотеки python-docx и вернуть обратно.Поскольку размер файла может быть большим, я не хочу сохранять его в файловой системе после обработки, а просто вернуть его для загрузки.
Получить файл из потока - это работает
import docx
from docx.document import Document
from StringIO import StringIO
source_stream = StringIO(request.vars['file'].value)
document = docx.Document(source_stream)
source_stream.close()
process_doc(document)
Вернуть его в виде потока - это не работает
Приложение действительно позволяет пользователю загружать файл , но * MS Word не можетоткройте файл, сказав «потому что какая-то часть отсутствует или недействительна» .
def download(document, filename):
import contenttype as c
import cStringIO
out_stream = cStringIO.StringIO()
document.save(out_stream)
response.headers['Content-Type'] = c.contenttype(filename)
response.headers['Content-Disposition'] = \
"attachment; filename=%s" % filename
return out_stream.getvalue()
Я нашел Загрузите объект StringIO с помощью send_file () , но эта ошибка сохраняетсяк рамке колбы.Я скорее использую web2py framework .
Обновление 1
Некоторые говорили о перемещении указателя файла на начало данных документа перед отправкой его в выходной поток.Но как это сделать?
Обновление 2
Как подсказал @scanny, я создал пустой файл
document = docx.Document()
и загрузил его из файлаобъект, использующий модуль BytesIO
:
document = docx.Document()
from io import BytesIO
out_stream = BytesIO()
document.save(out_stream)
filename = 'temporal_file.docx'
filepath = os.path.join(request.folder, 'uploads',filename )
try:
with open(filepath, 'wb') as f:
f.write(out_stream.getvalue())
response.flash ='Success to open file for writing'
response.headers['Content-Disposition'] = "attachment; filename=%s" % filename
response.headers['Content-Type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
#response['X-Sendfile'] = filepath
#response['Content-Length'] = os.stat(filepath).st_size
return out_stream.getvalue()
Как видно из кода, я также записываю этот пустой файл в файловую систему.И я мог бы легко загрузить его вручную и открыть его в MS word :
Итак, все еще остается открытым вопрос почему скачанный MS WordФайл (через выходной поток) поврежден и не может быть открыт MS Word ?
Обновление 3
Я исключил python-docx
из процесса вывода файла в выходпоток.И результат был тот же: после загрузки файла его нельзя открыть в MS Word.Код:
# we load without python-docx library
from io import BytesIO
try:
filename = 'empty_file.docx'
filepath = os.path.join(request.folder, 'uploads',filename )
# read a file from file system (disk)
with open(filepath, 'rb') as f:
out_stream = BytesIO(f.read())
response.flash ='Success to open file for reading'
response.headers['Content-Disposition'] = "attachment; filename=%s" % filename
response.headers['Content-Type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
return out_stream.getvalue()
except Exception as e:
response.flash ='Error open file for reading or download it - ' + filename
return