说白了,还是因为wkhtmltopdf工具使用的内存太大,打印200个页面就会直接内存超标,直接退出
直接改源码了,每次让pdf 转换工具只处理50个记录
@http.route(['/report/download'], type='http', auth="user")
def report_download(self, data, token):
"""This function is used by 'action_manager_report.js' in order to trigger the download of
a pdf/controller report.
:param data: a javascript array JSON.stringified containg report internal url ([0]) and
type [1]
:returns: Response with a filetoken cookie and an attachment header
"""
requestcontent = json.loads(data)
url, type = requestcontent[0], requestcontent[1]
try:
if type in ['qweb-pdf', 'qweb-text']:
converter = 'pdf' if type == 'qweb-pdf' else 'text'
extension = 'pdf' if type == 'qweb-pdf' else 'txt'
pattern = '/report/pdf/' if type == 'qweb-pdf' else '/report/text/'
reportname = url.split(pattern)[1].split('?')[0]
docids = None
if '/' in reportname:
reportname, docids = reportname.split('/')
if docids:
# Generic report:
data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON
response = self.report_routes(reportname, docids=docids, converter=converter, **dict(data))
else:
# Particular report:
data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON
response = self.report_routes(reportname, converter=converter, **dict(data))
report_context = dict(url_decode(url.split('?')[1]).items())
report = request.env['ir.actions.report']._get_report_from_name(reportname)
filename = "%s.%s" % (report.name, extension)
report_name = report.name
if docids:
ids = [int(x) for x in docids.split(",")]
obj = request.env[report.model].browse(ids)
if report.print_report_name and not len(obj) > 1:
report_name = safe_eval(report.print_report_name, {'object': obj, 'time': time})
filename = "%s.%s" % (report_name, extension)
response.headers.add('Content-Disposition', content_disposition(filename))
response.set_cookie('fileToken', token)
if report_context.get('backend'):
# 如果选择了后台运行,则保存到附件中,并返回None
self.save_attachment(response.data, report_name, filename)
return None
return response
else:
return
except Exception as e:
se = _serialize_exception(e)
error = {
'code': 200,
'message': "Odoo Server Error",
'data': se
}
return request.make_response(html_escape(json.dumps(error)))
@http.route([
'/report/<converter>/<reportname>',
'/report/<converter>/<reportname>/<docids>',
], type='http', auth='user', website=True)
def report_routes(self, reportname, docids=None, converter=None, **data):
report = request.env['ir.actions.report']._get_report_from_name(reportname)
context = dict(request.env.context)
if docids:
docids = [int(i) for i in docids.split(',')]
if data.get('options'):
data.update(json.loads(data.pop('options')))
if data.get('context'):
# Ignore 'lang' here, because the context in data is the one from the webclient *but* if
# the user explicitely wants to change the lang, this mechanism overwrites it.
data['context'] = json.loads(data['context'])
if data['context'].get('lang'):
del data['context']['lang']
context.update(data['context'])
if converter == 'html':
html = report.with_context(context).render_qweb_html(docids, data=data)[0]
return request.make_response(html)
elif converter == 'pdf':
list_pdf_temp= []
for list_docid in self.generator_five(docids, 50):
pdf_temp = report.with_context(context).render_qweb_pdf(list_docid, data=data)[0]
list_pdf_temp.append(pdf_temp)
data_pdf = pdf_tool.merge_pdf(list_pdf_temp)
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(data_pdf))]
return request.make_response(data_pdf, headers=pdfhttpheaders)
elif converter == 'text':
text = report.with_context(context).render_qweb_text(docids, data=data)[0]
texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))]
return request.make_response(text, headers=texthttpheaders)
else:
raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter)
def save_attachment(self, datas,report_name, file_name):
"""
<record id="documents_vendor_bill_extract_azure_interior" model="ir.attachment">
<field name="name">Invoice Azure Interior</field>
<field name="datas_fname">invoice_azure_interior.pdf</field>
<field name="datas" type="base64" file="documents/demo/files/invoice_azure_interior.pdf"/>
<field name="folder_id" ref="documents_finance_folder"/>
</record>
"""
attach = request.env['ir.attachment']
var = dict(name=report_name,
datas_fname=file_name,
datas=base64.b64encode(datas).decode('utf-8'),
folder_id=request.env.ref('documents.documents_finance_folder').id
)
attach.create([var])
@staticmethod
def generator_five(parm, num):
"""
将列表切分成每5个来返回
:param parm:
:return:
"""
length = len(parm)
for i in range(0, length, num):
yield parm[i:i + num]
懂得,原来世界如此简单!