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

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