Это мой код, но мой код не работает с моей кнопкой для экспорта данных XLSX из Odoo.
# coding: utf-8
from odoo import fields, models, api, _
import time
from datetime import datetime, date, timedelta
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT
import xlsxwriter
from io import BytesIO
class AccountDailyBook(models.TransientModel):
_name = "account.daily.book"
date_start = fields.Date("Fecha desde", required=True, default=date.today().replace(day=1).strftime('%Y-%m-%d'))
date_end = fields.Date("Fecha hasta", required=True, default=time.strftime('%Y-%m-%d'))
company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company)
def imprimir_pdf(self):
for rec in self:
format_new = "%d/%m/%Y"
data = {
'ids': 0,
'form': {
'date_from': self.date_start,
'date_to': self.date_end,
'date_from_str': self.date_start.strftime(format_new),
'date_to_str': self.date_end.strftime(format_new),
'company': self.company_id.id
}
}
return self.env.ref('l10n_ve_full.report_daily_book').report_action(self, data=data) # , config=False
def imprimir_xlsx(self):
for rec in self:
format_new = "%d/%m/%Y"
data = {
'ids': 0,
'form': {
'date_from': self.date_start,
'date_to': self.date_end,
'date_from_str': self.date_start.strftime(format_new),
'date_to_str': self.date_end.strftime(format_new),
'company': self.company_id.id
}
}
# Crear el archivo
output = BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet('Reporte')
# Escribir los encabezados
sheet.write(0, 0, 'Código')
sheet.write(0, 1, 'Nombre')
sheet.write(0, 2, 'Débito')
sheet.write(0, 3, 'Crédito')
# Escribir los datos
row = 1
for doc in data['docs']:
sheet.write(row, 0, doc['code'])
sheet.write(row, 1, doc['name'])
sheet.write(row, 2, doc['debit'])
sheet.write(row, 3, doc['credit'])
row += 1
# Escribir los totales
sheet.write(row, 1, 'Total')
sheet.write(row, 2, data['debit_total'])
sheet.write(row, 3, data['credit_total'])
# Cerrar el archivo
workbook.close()
output.seek(0)
return self.env.ref('l10n_ve_full.report_daily_book').report_action(self, data=data)
# Devolver el archivo como una respuesta HTTP
return {
'name': 'report_daily_book.xlsx',
'type': 'binary',
'data': output.read(),
'context': self.env.context,
}
class AccountInventoryBookReport(models.AbstractModel):
_name = 'report.l10n_ve_full.report_daily_book_template'
@api.model
def _get_report_values(self, docids, data=None):
date_start = datetime.strptime(data['form']['date_from'], DATE_FORMAT)
date_end = datetime.strptime(data['form']['date_to'], DATE_FORMAT)
company_id = self.env['res.company'].search([('id','=',data['form']['company'])])
move_line_ids = self.env['account.move.line'].search([])
datos = []
debit_total = 0
credit_total = 0
self._cr.execute("select aa.code, aa.name, sum(aml.debit) as debit, sum(aml.credit) as credit "
"from account_move_line as aml "
"left join account_account as aa on aml.account_id = aa.id "
"where date >= '%s' and date <= '%s' "
"group by aa.code, aa.name "
"order by aa.code " % (date_start,date_end))
for r in self.env.cr.fetchall():
datos.append({
'code': r[0],
'name': r[1],
'debit': r[2],
'credit': r[3]
})
debit_total += r[2]
credit_total += r[3]
return {
'company_id': company_id,
'company': company_id,
'currency': company_id.currency_id,
'date_start': data['form']['date_from_str'],
'date_end': data['form']['date_to_str'],
'fecha_actual': datetime.now().strftime("%d/%m/%Y"),
'hora_actual': datetime.now().strftime("%H:%M:%S"),
'doc': move_line_ids[0],
'docs': datos,
'debit_total': debit_total,
'credit_total': credit_total,
}
Я пробовал с этим кодом
def imprimir_xlsx(self):
for rec in self:
format_new = "%d/%m/%Y"
data = {
'ids': 0,
'form': {
'date_from': self.date_start,
'date_to': self.date_end,
'date_from_str': self.date_start.strftime(format_new),
'date_to_str': self.date_end.strftime(format_new),
'company': self.company_id.id
}
}
# Crear el archivo
output = BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet('Reporte')
# Escribir los encabezados
sheet.write(0, 0, 'Código')
sheet.write(0, 1, 'Nombre')
sheet.write(0, 2, 'Débito')
sheet.write(0, 3, 'Crédito')
# Escribir los datos
row = 1
for doc in data['docs']:
sheet.write(row, 0, doc['code'])
sheet.write(row, 1, doc['name'])
sheet.write(row, 2, doc['debit'])
sheet.write(row, 3, doc['credit'])
row += 1
# Escribir los totales
sheet.write(row, 1, 'Total')
sheet.write(row, 2, data['debit_total'])
sheet.write(row, 3, data['credit_total'])
# Cerrar el archivo
workbook.close()
output.seek(0)
return self.env.ref('l10n_ve_full.report_daily_book').report_action(self, data=data)
# Devolver el archivo como una respuesta HTTP
return {
'name': 'report_daily_book.xlsx',
'type': 'binary',
'data': output.read(),
'context': self.env.context,
}






Вы можете использовать модуль report_xlsx. Вам нужно будет передать результат запроса, определенного внутри синтаксического анализатора отчетов qweb, в отчет XLSX.
Пример:
Определение действия отчета
<record id = "report_daily_book_xlsx" model = "ir.actions.report">
<field name = "name">Print to XLSX</field>
<field name = "model">account.daily.book</field>
<field name = "report_type">xlsx</field>
<field name = "report_name">report_daily_book</field>
<field name = "report_file">report_daily_book</field>
</record>
Добавьте анализатор отчетов (функция update_datas используется в качестве примера, чтобы вы могли протестировать этот анализатор отчетов)
class ReportDailyBook(models.AbstractModel):
_name = "report.report_daily_book"
_inherit = "report.report_xlsx.abstract"
_description = "Daily Books XLSX Report"
def generate_xlsx_report(self, workbook, data, books):
self.update_datas(data)
sheet = workbook.add_worksheet("Reporte")
# Escribir los encabezados
sheet.write(0, 0, 'Código')
sheet.write(0, 1, 'Nombre')
sheet.write(0, 2, 'Débito')
sheet.write(0, 3, 'Crédito')
# Escribir los datos
row = 1
for doc in data['docs']:
sheet.write(row, 0, doc['code'])
sheet.write(row, 1, doc['name'])
sheet.write(row, 2, doc['debit'])
sheet.write(row, 3, doc['credit'])
row += 1
# Escribir los totales
sheet.write(row, 1, 'Total')
sheet.write(row, 2, data['debit_total'])
sheet.write(row, 3, data['credit_total'])
def update_datas(self, data):
date_start = datetime.strptime(data['form']['date_from'], DATE_FORMAT)
date_end = datetime.strptime(data['form']['date_to'], DATE_FORMAT)
company_id = self.env['res.company'].search([('id', '=', data['form']['company'])])
move_line_ids = self.env['account.move.line'].search([])
datos = []
debit_total = 0
credit_total = 0
self._cr.execute("select aa.code, aa.name, sum(aml.debit) as debit, sum(aml.credit) as credit "
"from account_move_line as aml "
"left join account_account as aa on aml.account_id = aa.id "
"where date >= '%s' and date <= '%s' "
"group by aa.code, aa.name "
"order by aa.code " % (date_start, date_end))
for r in self.env.cr.fetchall():
datos.append({
'code': r[0],
'name': r[1],
'debit': r[2],
'credit': r[3]
})
debit_total += r[2]
credit_total += r[3]
data['docs'] = datos
data['debit_total'] = debit_total
data['credit_total'] = credit_total
Вернуть действие отчета с предопределенными данными в функции imprimir_xlsx
class AccountDailyBook(models.TransientModel):
_name = "account.daily.book"
date_start = fields.Date("Fecha desde", required=True, default=date.today().replace(day=1).strftime('%Y-%m-%d'))
date_end = fields.Date("Fecha hasta", required=True, default=time.strftime('%Y-%m-%d'))
company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company)
def imprimir_xlsx(self):
self.ensure_one()
format_new = "%d/%m/%Y"
data = {
'ids': 0,
'form': {
'date_from': self.date_start,
'date_to': self.date_end,
'date_from_str': self.date_start.strftime(format_new),
'date_to_str': self.date_end.strftime(format_new),
'company': self.company_id.id
}
}
return self.env.ref('l10n_ve_full.report_daily_book_xlsx').report_action(self, data=data)
Спасибо, но он по-прежнему экспортирует данные в PDF, а не в XlSX.
Вы установили модуль report_xlsx и добавили кнопку для вызова функции imprimir_xlsx?
да, я установил report_xlsx и добавил кнопку imprimir_xlsx
но он все еще продолжает печатать меня в pdf .. мне нужно в xlsx :/
Я протестировал его, и он работает. Пожалуйста, обновите свой вопрос, чтобы включить новые изменения
Я удалил код и вставил такой же, как у вас, и получаю следующую ошибку --> Сообщение об ошибке: Ошибка при отображении шаблона TypeError: неподдерживаемая строка формата передается в NoneType.__format__ Шаблон: 2183 Путь: /t/t/div[ 2]/div/table/tbody/tr/td[2]/span Node: <span t-esc = "'{0:,.2f}'.format(credit_total)"/> Произошла ошибка во время создания плантилла 2183 и оценка основного выражения: <span t-esc = "'{0:,.2f}'.format(credit_total)"/>
Это ошибка qweb, которая означает, что credit_total равно None.
Как я могу это исправить, значение оставляет его равным 0 или даже меняется на ноль, и оно продолжает выдавать мне ошибку
Парсер отчета должен включать credit_total в контекст, обязательно используйте имя отчета в атрибуте парсера отчета _name ('report.module.report_name').
он по-прежнему показывает данные в формате pdf и не экспортирует их напрямую в excel.
Обновлено действие отчета, чтобы использовать другой идентификатор. В моем предыдущем примере будет использоваться действие отчета qweb. Это сработало для меня, потому что у меня нет отчета qweb. Я напишу демонстрационный модуль, если он вам нужен
Да, пожалуйста, мне это нужно
попробуйте следующий код -> строка += 1, если не isinstance(data['debit_total'], (int, float)): data['debit_total'] = 0,0 лист.запишите (строка, 1, 'Всего') лист. write(row, 2, '{0:,.2f}'.format(data['debit_total'])) sheet.write(row, 2, '{0:,.2f}'.format(data['credit_total '])) но все равно выдает ошибку qweb Ошибка при рендеринге шаблона TypeError: неподдерживаемая строка формата передана в NoneType.__format__ Шаблон: 2183 Путь: /t/t/div[2]/div/table/tbody/tr/ td[3]/span Узел: <span t-esc = "'{0:,.2f}'.format(debit_total)"/>
Я комментирую строку кода этого xml, и он продолжает показывать мне одно и то же, как будто модификации не были обновлены
Когда я нажимаю кнопку печати, он отправляет меня на страницу, где я загружаю файл pdf, я продолжаю пытаться