Мой код кнопки для экспорта данных в файл xlsx (Excel) не работает

Это мой код, но мой код не работает с моей кнопкой для экспорта данных 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,
        }

Когда я нажимаю кнопку печати, он отправляет меня на страницу, где я загружаю файл pdf, я продолжаю пытаться

SirDomini x 19.05.2023 14:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
145
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать модуль 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.

SirDomini x 17.05.2023 21:05

Вы установили модуль report_xlsx и добавили кнопку для вызова функции imprimir_xlsx?

Kenly 17.05.2023 23:55

да, я установил report_xlsx и добавил кнопку imprimir_xlsx

SirDomini x 18.05.2023 23:34

но он все еще продолжает печатать меня в pdf .. мне нужно в xlsx :/

SirDomini x 19.05.2023 01:22

Я протестировал его, и он работает. Пожалуйста, обновите свой вопрос, чтобы включить новые изменения

Kenly 19.05.2023 12:51

Я удалил код и вставил такой же, как у вас, и получаю следующую ошибку --> Сообщение об ошибке: Ошибка при отображении шаблона 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)"/>

SirDomini x 19.05.2023 15:15

Это ошибка qweb, которая означает, что credit_total равно None.

Kenly 19.05.2023 18:29

Как я могу это исправить, значение оставляет его равным 0 или даже меняется на ноль, и оно продолжает выдавать мне ошибку

SirDomini x 19.05.2023 20:29

Парсер отчета должен включать credit_total в контекст, обязательно используйте имя отчета в атрибуте парсера отчета _name ('report.module.report_name').

Kenly 19.05.2023 23:04

он по-прежнему показывает данные в формате pdf и не экспортирует их напрямую в excel.

SirDomini x 22.05.2023 16:48

Обновлено действие отчета, чтобы использовать другой идентификатор. В моем предыдущем примере будет использоваться действие отчета qweb. Это сработало для меня, потому что у меня нет отчета qweb. Я напишу демонстрационный модуль, если он вам нужен

Kenly 22.05.2023 16:55

Да, пожалуйста, мне это нужно

SirDomini x 22.05.2023 17:00

попробуйте следующий код -> строка += 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)"/>

SirDomini x 22.05.2023 18:15

Я комментирую строку кода этого xml, и он продолжает показывать мне одно и то же, как будто модификации не были обновлены

SirDomini x 22.05.2023 18:16

Другие вопросы по теме