ODOO13 开发教程八 自定义导出数据到Excel

前面几篇文章,我们已经说明怎么去创建并安装自己的模块。如果你跟着前几篇去做了,那太好了,我们可以一起进行本篇文章的学习了。

本篇实际上为新的odoo开发者说明,如何在odoo中,使用第三方包将数据导出到Excel。事实上,odoo已经提供了数据的Excel导入和导出数据到Excel功能。也许你要问了,既然odoo已经提供了数据的导入导出,那为什么我们还要在这里看这篇文章学习如何自己定义导出数据到EXCEL。

学习自定义导出数据的一个原因是odoo提供的导出,在某些特殊的需求面前,并不能将需求所需要的字段完全展现出来。

举个例子,就是之前系统开发时,数据结构设计的不是很理想,有些该关联的字段没有关联,只是用了个Char类型的字段作为连接某两张表的桥梁,并没有many2one字段关联起来。这时候,在使用odoo提供的导出功能时,因为没有关联关系,是满足不了用户需求的。

再举个例子,如果说一本图书有好几个标签(many2many),但有个需求是,图书的多个标签,用某些符号隔开,放进一列。如果这时你用odoo的导出功能,他不会把所有标签拼接成一列,而是导出到Excel时是多行。总之就是odoo提供的功能满足不了用户需求了,我们才去自定义。


本文将继续在之前的图书管理模块上做开发演示,我将导出图书出版时间在某个时间段内的图书记录。将使用 xlwt 库做演示。

先使用models.TransientModel 做一个导出条件的向导,在zerone_inherit模块下创建文件夹wizard,并创建文件 __init__.py、export_books_data.py 和 export_books_data.xml 文件

__init__.py

# -*- coding: utf-8 -*-

from . import export_books_data

export_books_data.py

from odoo import api, fields, models, _
import xlwt


class ExportBooksData(models.TransientModel):
    _name = "export.books.data"

    start_date = fields.Date(string="开始时间")
    end_date = fields.Date(string="结束时间")
    already_export = fields.Boolean(string='已导出')
    file_name = fields.Char(string='文件名称', store=True)
    xls_file = fields.Binary(string='点击下载', attachment=True)

export_books_data.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="export_book_data_form_view" model="ir.ui.view">
        <field name="name">export.books.data.form</field>
        <field name="type">form</field>
        <field name="model">export.books.data</field>
        <field name="priority" eval="20"/>
        <field name="arch" type="xml">
            <form>
                <group>
                    <field name="start_date" required="1"/>
                    <field name="end_date" required="1"/>
                </group>
                <field name="file_name" invisible="1"/>
                <field name="already_export" invisible="1"/>
                <div attrs="{'invisible': [('already_export', '!=', True)]}">
                    <separator/>
                    <p>
                        点击下载:<field name="xls_file" readonly="1" filename="file_name"/>
                    </p>
                </div>
                <footer>
                    <button name='export_file' string='导出' type='object' class='oe_highlight'/>
                    <button string="取消" class="oe_link" special="cancel" />
                </footer>
            </form>
        </field>
    </record>
    <!--action-->
    <record id="action_export_books_data" model="ir.actions.act_window">
        <field name="name">导出图书数据</field>
        <field name="type">ir.actions.act_window</field>
        <field name="res_model">export.books.data</field>
        <field name="view_mode">form</field>
        <field name="context">{}</field>
        <field name="target">new</field>
    </record>
    <!--menu-->
    <menuitem id="menu_export_books_data"
              action="action_export_books_data" name="导出图书数据"
              parent="zerone_books.menu_books_root" sequence="150"/>
</odoo>

为导出向导编写导出方法 : export_file 。继续在 export_books_data.py 文件中添加

# -*- coding: utf-8 -*-

import base64
import io

from odoo import api, fields, models, _
import xlwt


class ExportBooksData(models.TransientModel):
    _name = "export.books.data"

    start_date = fields.Date(string="开始时间")
    end_date = fields.Date(string="结束时间")
    already_export = fields.Boolean(string='已导出')
    file_name = fields.Char(string='文件名称', store=True)
    xls_file = fields.Binary(string='点击下载数据汇总', attachment=True)

    @staticmethod
    def _get_tags_string(book):
        tags = book.tags_ids.mapped("name")
        tags_str = "、".join(tags)
        return tags_str

    # 返回header
    def _sheet_header(self):
        header_list = [
            ['图书编号', '图书名称', '作者', '出版时间', '标签']
        ]
        return header_list

    # 返回data
    def _sheet_content(self):
        content_list = []
        books = self.sudo().env['zerone.book'].search([
            ("publish_date", "<=", self.end_date),
            ("publish_date", ">=", self.start_date)
        ])
        for book in books:
            content_list.append([
                book.code,
                book.name,
                book.author,
                book.publish_date.strftime('%Y-%m-%d'),
                self._get_tags_string(book)
            ])
        return content_list

    def export_file(self):
        result = self._sheet_header() + self._sheet_content()
        wbk = xlwt.Workbook()
        sheet = wbk.add_sheet('Sheet1', cell_overwrite_ok=True)
        style = xlwt.XFStyle()
        # 居中
        al = xlwt.Alignment()
        al.horz = 0x02
        al.vert = 0x01
        style.alignment = al
        # 外边框
        borders = xlwt.Borders()
        borders.left = 1
        borders.right = 1
        borders.top = 1
        borders.bottom = 1
        borders.bottom_colour = 0x3A
        style.borders = borders
        # 字体
        font = xlwt.Font()
        font.name = u'微软雅黑'
        font.height = 220
        style.font = font

        for i in range(len(result)):
            for j in range(len(result[i])):
                sheet.write(i, j, result[i][j], style)

        fp = io.BytesIO()
        wbk.save(fp)
        fp.seek(0)
        data = fp.read()
        fp.close()

        file_name = "%s-%s 图书数据.xls" % (str(self.start_date), str(self.end_date))
        self.write({'already_export': True, 'xls_file': base64.b64encode(data), 'file_name': file_name})
        return {
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'res_model': 'export.books.data',
            'target': 'new',
            'res_id': self.id,
        }

最新代码:https://github.com/lwdsw/odoo13_danta

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章