使用 tempfile 在 flask 中创建 pdf/xls 文档
Using tempfile to create pdf/xls documents in flask
我想问一下是否可以将 PDF/XLS 文档创建为临时文件。我这样做是为了之后使用烧瓶发送给他们。对于 pdf/xls 文件创建,我分别使用 reportlab 和 xlsxwriter 包。当我使用他们的方法保存文档时,出现 "Python temporary file permission denied" 错误。当我尝试使用 tempfile 方法关闭时,文件已损坏。有什么办法可以克服这个问题吗?或者任何其他合适的解决方案?
编辑:
一些代码片段:
import xlswriter
import tempfile
from flask import after_this_request
@app.route('/some_url', method=['POST'])
def create_doc_function():
@after_this_request
def cleanup(response):
temp.close()
return response
temp = tempfile.TemporaryFile()
book = xlsxwriter.Workbook(temp.name)
# some actions here ...
book.close() # raises "Python temporaty file permission denied" error.
# If missed, Excel book is gonna be corrupted,
# i.e. blank, which make sense
return send_file(temp, as_attachment=True,
attachment_filename='my_document_name.xls')
类似的故事与 pdf 文件。
使用 tempfile.mkstemp()
将在磁盘上创建一个标准的临时文件,该文件将一直存在直到被删除:
import tempfile
import os
handle, filepath = tempfile.mkstemp()
f = os.fdopen(handle) # convert raw handle to file object
...
编辑
tempfile.TemporaryFile()
将在关闭后立即销毁,这就是您上面的代码失败的原因。
您可以通过上下文管理器(或 atexit 模块)使用和删除 NamedTemporaryFile。它可能会为您完成肮脏的工作。
示例 1:
import os
from tempfile import NamedTemporaryFile
# define class, because everyone loves objects
class FileHandler():
def __init__(self):
'''
Let's create temporary file in constructor
Notice that there is no param (delete=True is not necessary)
'''
self.file = NamedTemporaryFile()
# write something funny into file...or do whatever you need
def write_into(self, btext):
self.file.write(btext)
def __enter__(self):
'''
Define simple but mandatory __enter__ function - context manager will require it.
Just return the instance, nothing more is requested.
'''
return self
def __exit__(self, exc_type, exc_val, exc_tb):
'''
Also define mandatory __exit__ method which is called at the end.
NamedTemporaryFile is deleted as soon as is closed (function checks it before and after close())
'''
print('Calling __exit__:')
print(f'File exists = {os.path.exists(self.file.name)}')
self.file.close()
print(f'File exists = {os.path.exists(self.file.name)}')
# use context mamager 'with' to create new instance and do something
with FileHandler() as fh:
fh.write_into(b'Hi happy developer!')
print(f'\nIn this point {fh.file.name} does not exist (exists = {os.path.exists(fh.file.name)})')
输出:
Calling __exit__:
File exists = True
File exists = False
In this point D:\users\fll2cj\AppData\Local\Temp\tmpyv37sp58 does not exist (exists = False)
或者你可以使用 atexit 模块,它在程序 (cmd) 退出时调用定义的函数。
示例 2:
import os, atexit
from tempfile import NamedTemporaryFile
class FileHandler():
def __init__(self):
self.file = NamedTemporaryFile()
# register function called when quit
atexit.register(self._cleanup)
def write_into(self, btext):
self.file.write(btext)
def _cleanup(self):
# because self.file has been created without delete=False, closing the file causes its deletion
self.file.close()
# create new instance and do whatever you need
fh = FileHandler()
fh.write_into(b'Hi happy developer!')
# now the file still exists, but when program quits, _cleanup() is called and file closed and automaticaly deleted.
我想问一下是否可以将 PDF/XLS 文档创建为临时文件。我这样做是为了之后使用烧瓶发送给他们。对于 pdf/xls 文件创建,我分别使用 reportlab 和 xlsxwriter 包。当我使用他们的方法保存文档时,出现 "Python temporary file permission denied" 错误。当我尝试使用 tempfile 方法关闭时,文件已损坏。有什么办法可以克服这个问题吗?或者任何其他合适的解决方案?
编辑:
一些代码片段:
import xlswriter
import tempfile
from flask import after_this_request
@app.route('/some_url', method=['POST'])
def create_doc_function():
@after_this_request
def cleanup(response):
temp.close()
return response
temp = tempfile.TemporaryFile()
book = xlsxwriter.Workbook(temp.name)
# some actions here ...
book.close() # raises "Python temporaty file permission denied" error.
# If missed, Excel book is gonna be corrupted,
# i.e. blank, which make sense
return send_file(temp, as_attachment=True,
attachment_filename='my_document_name.xls')
类似的故事与 pdf 文件。
使用 tempfile.mkstemp()
将在磁盘上创建一个标准的临时文件,该文件将一直存在直到被删除:
import tempfile
import os
handle, filepath = tempfile.mkstemp()
f = os.fdopen(handle) # convert raw handle to file object
...
编辑
tempfile.TemporaryFile()
将在关闭后立即销毁,这就是您上面的代码失败的原因。
您可以通过上下文管理器(或 atexit 模块)使用和删除 NamedTemporaryFile。它可能会为您完成肮脏的工作。
示例 1:
import os
from tempfile import NamedTemporaryFile
# define class, because everyone loves objects
class FileHandler():
def __init__(self):
'''
Let's create temporary file in constructor
Notice that there is no param (delete=True is not necessary)
'''
self.file = NamedTemporaryFile()
# write something funny into file...or do whatever you need
def write_into(self, btext):
self.file.write(btext)
def __enter__(self):
'''
Define simple but mandatory __enter__ function - context manager will require it.
Just return the instance, nothing more is requested.
'''
return self
def __exit__(self, exc_type, exc_val, exc_tb):
'''
Also define mandatory __exit__ method which is called at the end.
NamedTemporaryFile is deleted as soon as is closed (function checks it before and after close())
'''
print('Calling __exit__:')
print(f'File exists = {os.path.exists(self.file.name)}')
self.file.close()
print(f'File exists = {os.path.exists(self.file.name)}')
# use context mamager 'with' to create new instance and do something
with FileHandler() as fh:
fh.write_into(b'Hi happy developer!')
print(f'\nIn this point {fh.file.name} does not exist (exists = {os.path.exists(fh.file.name)})')
输出:
Calling __exit__:
File exists = True
File exists = False
In this point D:\users\fll2cj\AppData\Local\Temp\tmpyv37sp58 does not exist (exists = False)
或者你可以使用 atexit 模块,它在程序 (cmd) 退出时调用定义的函数。
示例 2:
import os, atexit
from tempfile import NamedTemporaryFile
class FileHandler():
def __init__(self):
self.file = NamedTemporaryFile()
# register function called when quit
atexit.register(self._cleanup)
def write_into(self, btext):
self.file.write(btext)
def _cleanup(self):
# because self.file has been created without delete=False, closing the file causes its deletion
self.file.close()
# create new instance and do whatever you need
fh = FileHandler()
fh.write_into(b'Hi happy developer!')
# now the file still exists, but when program quits, _cleanup() is called and file closed and automaticaly deleted.