Odoo14使用hiPrint实现打印功能

news2024/11/15 4:02:59

使用hiPrint代替odoo原生的打印功能

可以实现快速自定义修改打印模板,无需每次都调整打印模板

无论是表单分页还是各种需求,都能满足

目录

1 使用命令创建新的模块,无用的demo文件可以删除掉

2 新建“打印模板”,用于保存打印模板

1)编写打印模板模型

2)增加打印模板权限

3)增加打印模板视图和菜单

3 首次运行先安装模块

4 增加按钮,定制并保存模板

1)增加自定义按钮“定制模板”xml

2)增加自定义按钮事件js,点击按钮实现打开新的页面

3)增加引入自定义按钮事件js的xml

4)列表视图增加自定义按钮

5)引入以上2个文件

6)引入js,bootstrap,hiprint并引用

7)编写接口,用于打开模板编辑界面,并实现修改保存打印模板

8)编写打开的打印模板页面,在打印模板页面调用接口,实现修改保存打印模板

5 编辑并保存打印模板

1)勾选打印模板记录,点击定制模板

2)在模板设计页面设计打印模板,并保存

6 新建“打印数据”,用于模拟测试打印功能(类似新建“打印模板”,此处省略说明)

1)增加模型,增加权限,增加视图,增加菜单,增加数据

7 在需要进行打印的列表处增加打印按钮

1)增加自定义按钮“打印”xml

2)增加自定义按钮事件js,点击按钮实现打印

3)增加引入自定义按钮事件js的xml

4)列表视图增加自定义按钮

5)引入以上2个文件

8 勾选数据记录,并点击打印按钮即可

9 插件下载


1 使用命令创建新的模块,无用的demo文件可以删除掉

 python odoo-bin scaffold hiprint

2 新建“打印模板”,用于保存打印模板

1)编写打印模板模型

2)增加打印模板权限

3)增加打印模板视图和菜单

class PrintTemp(models.Model):
    _name = 'print.temp'
    _order = 'name DESC'
    _description = '打印模板'

    _sql_constraints = [
        ('unique_code_print_temp', 'unique(code)', '编码需要唯一.'),
    ]

    name = fields.Char(u'名称', copy=False, index=True, required=True)
    code = fields.Char(u'编码', copy=False, index=True, default='/')
    type = fields.Char('类型')
    template = fields.Text('模板')
    remark = fields.Char(string='备注')

    def copy(self, default=None):
        default = dict(default or {})

        copied_count = self.search_count(
            [('name', '=like', u"副本 {}%".format(self.name))])
        if not copied_count:
            new_name = u"副本 {}".format(self.name)
        else:
            new_name = u"副本 {} ({})".format(self.name, copied_count)

        default['name'] = new_name
        return super(PrintTemp, self).copy(default)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
print_temp,print_temp,model_print_temp,,1,1,1,1
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record model="ir.ui.view" id="print_temp_tree_view">
        <field name="name">print.temp.tree</field>
        <field name="model">print.temp</field>
        <field name="arch" type="xml">
            <tree>
                <field name="name"/>
                <field name="code"/>
                <field name="type"/>
                <field name="remark"/>
            </tree>
        </field>
    </record>


    <record model="ir.ui.view" id="print_temp_form_view">
        <field name="name">print.temp.form</field>
        <field name="model">print.temp</field>
        <field name="arch" type="xml">
            <form delete="0">
                <sheet>
                    <group>
                        <group>
                            <field name="code"/>
                            <field name="name" />
                        </group>
                        <group>
                            <field name="template"/>
                            <field name="type"/>
                            <field name="remark"/>
                        </group>
                    </group>
                </sheet>
            </form>
        </field>
    </record>

    <record model="ir.actions.act_window" id="action_print_temp">
        <field name="name">打印模板</field>
        <field name="res_model">print.temp</field>
        <field name="view_mode">tree,form</field>
    </record>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <menuitem id="hiprint_menu" name="hiprint" web_icon="hiprint,static/description/icon.png" sequence="10"/>

        <menuitem id="hiprint_print_temp" name="打印模板" parent="hiprint_menu" sequence="10" action="action_print_temp"/>
    </data>
</odoo>

3 首次运行先安装模块

python odoo-bin -c odoo.conf -i hiprint

4 增加按钮,定制并保存模板

1)增加自定义按钮“定制模板”xml

2)增加自定义按钮事件js,点击按钮实现打开新的页面

3)增加引入自定义按钮事件js的xml

4)列表视图增加自定义按钮

5)引入以上2个文件

6)引入js,bootstrap,hiprint并引用

7)编写接口,用于打开模板编辑界面,并实现修改保存打印模板

8)编写打开的打印模板页面,在打印模板页面调用接口,实现修改保存打印模板

<?xml version="1.0" encoding="UTF-8"?>

<templates id="print_temp_button_template" xml:space="preserve">

    <t t-extend="ListView.buttons" t-name="hiprint_print_temp_tree_view.buttons">
        <t t-jquery="button.o_list_export_xlsx" t-operation="before">
            <t t-if="widget.modelName=='print.temp'">
                <button type="button" class="btn btn-primary o_list_button_custom">
                    定制模板
                </button>
            </t>
        </t>
    </t>

</templates>

odoo.define('add_print_temp_button', function (require) {
    "use strict";
    var ListController = require('web.ListController');
    var ListView = require('web.ListView');
    var viewRegistry = require('web.view_registry');

    function renderGenerateButton() {
        if (this.$buttons) {
            var self = this;
            this.$buttons.on('click', '.o_list_button_custom', function () {
                console.info('click');
                var actived_ids = []
                var state = self.model.get(self.handle, {raw: true});
                for (var i = 0; i < $('tbody .o_list_record_selector input').length; i++) {
                    if ($('tbody .o_list_record_selector input')[i].checked === true) {
                        actived_ids.push(state.res_ids[i]);
                    }
                }
                var ctx = state.context;
                if(actived_ids.length > 0){
                    window.open("pt_custom/" + actived_ids[0], '_blank');
                }
            });
        }
    }

    var ModelListController = ListController.extend({
        willStart: function () {
            var self = this;
            //设置管理员权限组才看到按钮,可以按需修改
            var ready = this.getSession().user_has_group('base.group_no_one')
                .then(function () {
                    if (true) {
                        self.buttons_template = 'hiprint_print_temp_tree_view.buttons';
                    }
                });
            return Promise.all([this._super.apply(this, arguments), ready]);
        },
        renderButtons: function () {
            this._super.apply(this, arguments);
            renderGenerateButton.apply(this, arguments);
        }
    });

    var ModelListView = ListView.extend({
        config: _.extend({}, ListView.prototype.config, {
            Controller: ModelListController,
        }),
    });

    //将tree视图的按钮注册到视图
    viewRegistry.add('print_temp_tree', ModelListView);
});
<odoo>
    <data>
        <template id="button_js" inherit_id="web.assets_backend">
            <xpath expr="." position="inside">
                <script type="text/javascript" src="/hiprint/static/src/js/print_temp_button.js"/>
            </xpath>
        </template>
    </data>
</odoo>
    <!--增加js_class="print_temp_tree"-->
    <record model="ir.ui.view" id="print_temp_tree_view">
        <field name="name">print.temp.tree</field>
        <field name="model">print.temp</field>
        <field name="arch" type="xml">
            <tree js_class="print_temp_tree">
                <field name="name"/>
                <field name="code"/>
                <field name="type"/>
                <field name="remark"/>
            </tree>
        </field>
    </record>
    'data': [
        'security/ir.model.access.csv',

        'views/print_temp_view.xml',
        'views/menus_view.xml',

        'static/src/xml/include_print_temp_button_js.xml',
    ],
    'qweb': [
        'static/src/xml/print_temp_button_template.xml',
    ]

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <template id="assets_backend" inherit_id="web.assets_backend">
        <xpath expr="." position="inside">
            <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/hinnn.css"/>
            <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/hiprint.css"/>
            <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/print-lock.css"/>

            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/polyfill.min.js"></script>
            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/jquery.minicolors.min.js"></script>
            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/JsBarcode.all.min.js"></script>
            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/qrcode.js"></script>
            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/hiprint.bundle.js"></script>
            <script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/jquery.hiwprint.js"></script>
            <!--<script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/socket.io.js"></script>-->
        </xpath>
    </template>
</odoo>

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


import logging

from odoo import http
from odoo.http import request
from odoo.tools import exception_to_unicode
import jinja2, sys, os

_logger = logging.getLogger(__name__)


class PrintCtrl(http.Controller):

    _pt_custom = '/pt_custom/<int:id>'
    _pt_find = '/pt_find/<int:id>'
    _pt_save = '/pt_save/<int:id>'
    _pd_list = '/pd_list'

    @http.route(_pt_custom, type='http', auth='none', method=['GET', 'POST'], csrf=False)
    def _pt_custom(self, **kw):
        try:
            if hasattr(sys, 'frozen'):
                # When running on compiled windows binary, we don't have access to package loader.
                path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views'))
                loader = jinja2.FileSystemLoader(path)
            else:
                loader = jinja2.PackageLoader('odoo.addons.hiprint', "views")
            env = jinja2.Environment(loader=loader, autoescape=True)
            return env.get_template("customtemp.html").render({'id': kw.get("id")})
        except Exception as e:
            return exception_to_unicode(e)

    @http.route(_pt_find, type='json', auth='none', methods=['GET', "POST"], csrf=False)
    def pt_find(self, **kw):
        result = {
            'method': self._pt_find,
            'code': 200,
            'message': 'ok',
            'data': {},
        }
        try:
            id = kw.get('id', False)
            code = kw.get('code', False)
            if code:
                print_temp = request.env['print.temp'].sudo().search([("code", "=", code)])
                if print_temp:
                    result['data'] = {
                        'template': print_temp.template,
                    }
                    return result
            if id:
                print_temp = request.env['print.temp'].sudo().search([("id", "=", id)])
                if print_temp:
                    result['data'] = {
                        'template': print_temp.template,
                    }
                    return result
        except Exception as e:
            request.env.cr.rollback()
            result['code'] = 500
            result['message'] = exception_to_unicode(e)
            return result
        return result

    @http.route(_pt_save, type='json', auth='none', methods=["POST"], csrf=False)
    def pt_save(self, **kw):
        result = {
            'method': self._pt_save,
            'code': 200,
            'message': 'ok',
            'data': {},
        }
        try:
            id = kw.get('id', False)
            template = kw.get('template', False)
            if id:
                print_temp = request.env['print.temp'].sudo().search([("id", "=", id)])
                print_temp.template = template
            else:
                result['code'] = 500
                result['message'] = '缺少必要的参数'
                return result
        except Exception as e:
            request.env.cr.rollback()
            result['code'] = 500
            result['message'] = exception_to_unicode(e)
            return result
        return result

    @http.route(_pd_list, type='json', auth='user', methods=["POST"], csrf=False)
    def pd_list(self, **kw):
        result = {
            'method': self._pd_list,
            'code': 200,
            'message': 'ok',
            'data': {},
        }
        try:
            result_data = []
            ids = kw.get('ids', False)
            if ids:
                for id in ids:
                    # 改成逐行查询,一次查询会导致顺序不正确
                    record = request.env['print.data'].sudo().search([("id", "=", id)])
                    result_data.append({
                        'id': record.id,
                        'name': record.name,
                        'code': record.code,
                    })
                result['data'] = {
                    'print_data': result_data,
                    'total': len(result_data),
                }
            else:
                result['code'] = 500
                result['message'] = '缺少必要的参数'
                return result
        except Exception as e:
            request.env.cr.rollback()
            result['code'] = 500
            result['message'] = exception_to_unicode(e)
            return result
        return result
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
    <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/hinnn.css"/>
    <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/hiprint.css"/>
    <link rel="stylesheet" href="/hiprint/static/src/js/hiprint/css/print-lock.css"/>

    <link rel="stylesheet" href="/hiprint/static/src/js/bootstrap-3.4.1-dist/css/bootstrap.min.css"/>
    <script type="text/javascript" src="/hiprint/static/src/js/jquery/jquery-1.12.4.min.js"></script>

</head>
<body>
<layout class="layout hinnn-layout hinnn-layout-has-sider height-100-per" style="background:#fff;">
    <content class="hinnn-layout-content" style="border-left:1px solid #e8e8e8;">
        <div class="container-fluid height-100-per print-content">

            <div class="row">
                <div class="col-sm-12">
                    <div class="row">
                        <div class="col-sm-3 col-md-2" style="padding-right:0px;">

                            <div class="rect-printElement-types hiprintEpContainer">
                                <ul class="hiprint-printElement-type">

                                    <li>
                                        <span class="title"><code>拖拽列表</code></span>
                                        <ul>
                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.text" style="">

                                                    <span class="glyphicon glyphicon-text-width" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">文本</span>
                                                </a>
                                            </li>

                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.image" style="">
                                                    <span class="glyphicon glyphicon-picture" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">图片</span>
                                                </a>
                                            </li>
                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.longText">
                                                    <span class="glyphicon glyphicon-subscript" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">长文</span>


                                                </a>
                                            </li>

                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.tableCustom" style="">
                                                    <span class="glyphicon glyphicon-th" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">表格</span>
                                                </a>
                                            </li>

                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.html">
                                                    <span class="glyphicon glyphicon-header" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">html</span>
                                                </a>
                                            </li>

                                        </ul>
                                    </li>
                                    <li>
                                        <span class="title">辅助</span>
                                        <ul>
                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.hline" style="">

                                                    <span class="glyphicon glyphicon-resize-horizontal" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">横线</span>
                                                </a>
                                            </li>

                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.vline" style="">
                                                    <span class="glyphicon glyphicon-resize-vertical" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">竖线</span>
                                                </a>
                                            </li>
                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.rect">
                                                    <span class="glyphicon glyphicon-unchecked" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">矩形</span>
                                                </a>
                                            </li>
                                            <li>
                                                <a class="ep-draggable-item" tid="testModule.oval">
                                                    <span class="glyphicon glyphicon-record" aria-hidden="true"></span>
                                                    <span class="glyphicon-class">椭圆</span>
                                                </a>
                                            </li>
                                        </ul>
                                    </li>
                                </ul>
                            </div>

                        </div>
                        <div class="col-sm-9 col-md-10">
                            <div class="hiprint-toolbar" style="margin-top:15px;">
                                <ul>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('A3')">A3</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('A4')">A4</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('A5')">A5</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('B3')">B3</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('B4')">B4</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="setPaper('B5')">B5</a></li>

                                    <li><a class="hiprint-toolbar-item"><input type="text" id="customWidth" style="width: 50px;height: 19px;border: 0px;" placeholder="宽/mm"/></a>
                                    </li>
                                    <li><a class="hiprint-toolbar-item"><input type="text" id="customHeight" style="width: 50px;height: 19px;border: 0px;" placeholder="高/mm"/></a>
                                    </li>

                                    <li><a class="hiprint-toolbar-item" onclick="setPaper($('#customWidth').val(),$('#customHeight').val())">自定义</a></li>
                                    <li><a class="hiprint-toolbar-item" onclick="rotatePaper()">旋转</a></li>
                                    <li>
                                        <a id="save" class="btn hiprint-toolbar-item " style="color: #fff;background-color: #d9534f;border-color: #d43f3a;">保存模板</a>
                                    </li>
                                </ul>
                                <div style="clear:both;"></div>
                            </div>
                            <div id="hiprint-printTemplate" class="hiprint-printTemplate" style="margin-top:20px;">

                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </content>
    <sider class="hinnn-layout-sider" style="">
        <div class="container height-100-per" style="width:250px;">
            <div class="row">
                <div class="col-sm-12">
                    <div id="PrintElementOptionSetting" style="margin-top:10px;"></div>
                </div>
            </div>
        </div>
    </sider>
</layout>

<div class="modal fade" id="alertModal" tabindex="-1" role="dialog" aria-labelledby="alertModalLabel">
    <div class="modal-dialog modal-lg" role="document" style="width: 825px;">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            </div>
            <div class="modal-body">
                <div class="prevViewDiv"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>

            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/custom_test/custom-etype-provider.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/polyfill.min.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/jquery.minicolors.min.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/JsBarcode.all.min.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/qrcode.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/hiprint.bundle.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/hiprint/plugins/jquery.hiwprint.js"></script>
<script type="text/javascript" src="/hiprint/static/src/js/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
<script>
        var hiprintTemplate;
        var printTemplateJson;
        var printData = {

        };
        $(function() {
            var settings = {
               "url": "/pt_find/{{id}}",
               "method": "POST",
               "timeout": 0,
               "headers": {
                  "Content-Type": "application/json",
               },
               "data": JSON.stringify({
                  "params": {}
               }),
            };

            $.ajax(settings).done(function (response) {
               console.log(response.result.data.template);
               printTemplateJson = $.parseJSON($.parseJSON(response.result.data.template))

                //初始化打印插件
                hiprint.init({
                    providers: [new customElementTypeProvider()]
                });

                //hiprint.PrintElementTypeManager.build('.hiprintEpContainer', 'testModule');
                //设置左侧拖拽事件
                hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'));
                //console.info(printTemplateJson);
                hiprintTemplate = new hiprint.PrintTemplate({
                    template: printTemplateJson,
                    settingContainer: '#PrintElementOptionSetting',
                    paginationContainer: '.hiprint-printPagination'
                });
                //打印设计
                hiprintTemplate.design('#hiprint-printTemplate');
            });


			$('#save').click(function () {
                var settings = {
                   "url": "/pt_save/{{id}}",
                   "method": "POST",
                   "timeout": 0,
                   "headers": {
                      "Content-Type": "application/json",
                   },
                   "data": JSON.stringify({
                      "params": {
                        "template": JSON.stringify(JSON.stringify(hiprintTemplate.getJson()))
                      }
                   }),
                };

                $.ajax(settings).done(function (response) {
                    if(response.result.code=='200'){
	    				$('#alertModal .modal-body .prevViewDiv').html("保存成功")
	                    $('#alertModal').modal('show')
                    }
                    else{

                    }
                });
            })
        });

        var setPaper = function (paperTypeOrWidth, height) {
        	if(paperTypeOrWidth!="" && height!="")
            	hiprintTemplate.setPaper(paperTypeOrWidth, height);
        }
        var rotatePaper = function () {
            hiprintTemplate.rotatePaper();
        }

</script>
</body>
</html>

5 编辑并保存打印模板

1)勾选打印模板记录,点击定制模板

2)在模板设计页面设计打印模板,并保存

6 新建“打印数据”,用于模拟测试打印功能(类似新建“打印模板”,此处省略说明)

1)增加模型,增加权限,增加视图,增加菜单,增加数据

7 在需要进行打印的列表处增加打印按钮

1)增加自定义按钮“打印”xml

2)增加自定义按钮事件js,点击按钮实现打印

3)增加引入自定义按钮事件js的xml

4)列表视图增加自定义按钮

5)引入以上2个文件

<?xml version="1.0" encoding="UTF-8"?>

<templates id="print_data_button_template" xml:space="preserve">

    <t t-extend="ListView.buttons" t-name="hiprint_print_data_tree_view.buttons">
        <t t-jquery="button.o_list_export_xlsx" t-operation="before">
            <t t-if="widget.modelName=='print.data'">
                <button type="button" class="btn btn-warning o_list_button_print">
                    打印
                </button>
            </t>
        </t>
    </t>

</templates>

odoo.define('add_print_data_button', function (require) {
    "use strict";
    var ListController = require('web.ListController');
    var ListView = require('web.ListView');
    var viewRegistry = require('web.view_registry');
    var Dialog = require('web.Dialog');
    var core = require('web.core');
    var _t = core._t;

    function renderGenerateButton() {
        if (this.$buttons) {
            var self = this;
            this.$buttons.on('click', '.o_list_button_print', function () {
                var actived_ids = []
                var state = self.model.get(self.handle, {raw: true});
                for (var i = 0; i < $('tbody .o_list_record_selector input').length; i++) {
                    if ($('tbody .o_list_record_selector input')[i].checked === true) {
                        actived_ids.push(state.res_ids[i]);
                    }
                }

                $.ajax({
                   "url": "/pt_find/0",
                   "method": "POST",
                   "timeout": 0,
                   "headers": {
                      "Content-Type": "application/json",
                   },
                   "data": JSON.stringify({
                      "params": {
                        "code": "打印模板1"
                      }
                   }),
                }).done(function (resp) {
                    $.ajax({
                       "url": "/pd_list",
                       "method": "POST",
                       "timeout": 0,
                       "headers": {
                          "Content-Type": "application/json",
                       },
                       "data": JSON.stringify({
                          "params": {
                            "ids": actived_ids
                          }
                       }),
                    }).done(function (response) {
                        if(JSON.stringify(response.result.data) != "{}"){
                            var printTemplateJson = $.parseJSON($.parseJSON(resp.result.data.template));
                            hiprint.init({});
                            var hiprintTemplate = new hiprint.PrintTemplate({
                                template: printTemplateJson,
                                settingContainer: '#PrintElementOptionSetting',
                                paginationContainer: '.hiprint-printPagination'
                            });
                            hiprintTemplate.print(JSON.parse(JSON.stringify(response.result.data.device_device)));
                        }
                        else{
                            console.info(response.result);
                        }
                    });
                });
            });
        }
    }

    var ModelListController = ListController.extend({
        willStart: function () {
            var self = this;
            //设置管理员权限组才看到按钮,可以按需修改
            var ready = this.getSession().user_has_group('base.group_no_one')
                .then(function () {
                    if (true) {
                        self.buttons_template = 'hiprint_print_data_tree_view.buttons';
                    }
                });
            return Promise.all([this._super.apply(this, arguments), ready]);
        },
        renderButtons: function () {
            this._super.apply(this, arguments);
            renderGenerateButton.apply(this, arguments);
        }
    });

    var ModelListView = ListView.extend({
        config: _.extend({}, ListView.prototype.config, {
            Controller: ModelListController,
        }),
    });

    //将tree视图的按钮注册到视图
    viewRegistry.add('print_data_tree', ModelListView);
});
<odoo>
    <data>
        <template id="include_print_data_button_js" inherit_id="web.assets_backend">
            <xpath expr="." position="inside">
                <script type="text/javascript" src="/hiprint/static/src/js/print_data_button.js"/>
            </xpath>
        </template>
    </data>
</odoo>

8 勾选数据记录,并点击打印按钮即可

9 插件下载

https://download.csdn.net/download/u010520912/89520006

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1910894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AFT:Attention Free Transformer论文笔记

原文链接 2105.14103 (arxiv.org) 原文翻译 Abstract 我们介绍了 Attention Free Transformer (AFT)&#xff0c;这是 Transformer [1] 的有效变体&#xff0c;它消除了点积自注意力的需要。在 AFT 层&#xff0c;键key和值value首先与一组学习的位置偏差position biases相结…

海南云亿商务咨询有限公司助力品牌快速崛起

在数字化浪潮的推动下&#xff0c;电商行业日新月异&#xff0c;短视频平台更是成为品牌宣传和销售的新宠。海南云亿商务咨询有限公司&#xff0c;作为抖音电商服务的领军者&#xff0c;凭借其专业的团队和丰富的经验&#xff0c;助力众多品牌在抖音平台上实现了快速增长。 一…

通过rpmbuild构建Elasticsearch-7.14.2-search-guard的RPM包

系列文章目录 rpmbuild从入门到放弃 search-guard插件使用入门手册 文章目录 系列文章目录前言一、资源准备二、spec文件1.基础信息2.%prep3.%Install4.%file5.%post6.%postun 三、成果演示1.执行构建过程图示例2.执行安装RPM包示例3.进程检查4.访问esApi 总结 前言 不管是源…

Google AlphaGo 繁忙训练的一天

早晨&#xff1a;启动与准备 7:00 AM - 起床与准备 AlphaGo的研发团队成员早早起床&#xff0c;进行晨练活动&#xff0c;如跑步或瑜伽&#xff0c;保持身体健康和精力充沛。 8:30 AM - 到达工作场所 研发团队到达Google的办公室或远程工作站&#xff0c;启动设备&#xff…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十六章 Linux 第一个程序 HelloWorld

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Docker——简介、安装(Ubuntu22.04)

1、简介 Docker 是一个开源的容器化平台&#xff0c;旨在简化应用程序的开发、交付和运行。它通过将应用程序及其所有依赖项打包到一个称为容器的标准化单元中&#xff0c;使应用程序能够在任何环境中一致地运行。Docker 解决了“在我的机器上能运行”的问题&#xff0c;使开发…

如何检测用户的Chrome插件

背景 已知一些Chrome插件会影响到网站的一些功能&#xff0c;希望在前端主动检测到用户使用了某插件然后弹出提示让用户关闭&#xff0c;以减少客诉 方法 1. 检测资源文件 如图获取插件的ID 启用插件后&#xff0c;打开 chrome-extension://${ID}/manifest.json 找到 web_a…

Java实战:寻找完美数

文章目录 一、何谓完美数二、寻找完美数&#xff08;一&#xff09;编程思路&#xff08;二&#xff09;编写程序&#xff08;三&#xff09;运行程序 三、实战小结 一、何谓完美数 完美数是一种特殊的自然数&#xff0c;它等于其所有正除数&#xff08;不包括其本身&#xff…

【好物推荐】2024年最佳无线耳塞和耳机

深入三星生态系统找到最适合使用的三星无线耳塞和耳机。 如果你有一部三星手机&#xff0c;你可以很容易地从市场上最好的无线耳机中选择。有与airpods相当的Galaxy Buds Pro 2&#xff0c;或者大量与Android兼容的第三方选项。其中许多还支持aptX或LDAC音频编解码器&#xff…

Python 利用pandas处理CSV文件(DataFrame的基础用法)

前面介绍过通过Python标准库中的CSV模块处理CSV文件&#xff1a; Python 利用CSV模块处理数据 相比CSV模块&#xff0c;pandas的功能更加强大&#xff0c;本文将简单介绍如何通过pandas来处理CSV文件。 文章目录 一、pandas简介二、用法示例2.1 读取CSV文件2.1.1 read_csv参数…

3D模型进入可快速编辑时代,51建模网赋能Web3D展示!

丰富多样的Web3D展示形式&#xff0c;离不开强大的3D互动引擎作为坚实后盾。51建模网依托WebGL技术的先进力量&#xff0c;匠心打造了一款在线3D模型编辑器&#xff0c;它不仅能够迅速优化3D模型效果&#xff0c;更能够生成引人入胜的3D互动内容&#xff0c;让创意无界&#xf…

【问题记录】Windows中Node的express无法直接识别

问题描述 在使用express_generator的时候windows平台中出现无法识别express命令的问题&#xff0c;另外就算添加了全局环境变量也没用。 问题解决 查看官方文档发现在node版本8之前的时候使用的是express&#xff0c;但是之后的版本使用npx&#xff0c;这个工具的出现主要想…

数字身份管理发展趋势:IAM 和数据安全相结合

数据安全和IAM作为网络安全领域中不同的学科而存在。然而&#xff0c;随着越来越多的组织利用云服务&#xff0c;情况发生了显著的转变。许多公司现在将重要的安全控制(例如管理存储、应用程序和网络的控制)委托给他们选择的云服务提供商(CSP)。 图&#xff1a;用户与云服务商职…

C++ QT实现验证码功能

codearea.h #ifndef RENDERAREA_H #define RENDERAREA_H#include <QList> #include <QPainterPath> #include <QRect> #include <QWidget>#define DEF_CODECOUNT 4 // 验证码默认位数#define DEF_NOISYPOINTCOUNT 60 // 噪点数量 #define DEF_C…

印尼“支付宝” DANA 如何借力 OceanBase 实现3个“关键零”

当前&#xff0c;移动支付在东南亚正迅猛发展&#xff0c;据谷歌、淡马锡与贝恩公司发布的报告预测&#xff0c;东盟地区蓬勃兴起的移动支付市场有望在2030年突破至2万亿美元的交易规模。 在此背景下&#xff0c;DANA作为印尼——东南亚最大经济体中的一员&#xff0c;秉持着推…

【docker 把系统盘空间耗没了!】windows11 更改 ubuntu 子系统存储位置

系统&#xff1a;win11 ubuntu 22 子系统&#xff0c;docker 出现问题&#xff1a;系统盘突然没空间了&#xff0c;一片红 经过排查&#xff0c;发现 AppData\Local\packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\ 这个文件夹竟然有 90GB 下面提供解决办法 步…

磁力搜索引擎是什么?为什么有些资源喜欢用磁力链接?

磁力链接是什么东西&#xff1f;在日常生活中&#xff0c;我们接触的比较多的下载链接是直链。 所谓的直链简单来说就是直接指向服务器文件资源的链接&#xff0c;如B站app的下载链接&#xff0c;这种链接有统一的服务器提供保障&#xff0c;通常比较稳定&#xff0c;可以追溯源…

数据结构 —— Dijkstra算法

数据结构 —— Dijkstra算法 Dijkstra算法划分集合模拟过程打印路径 在上次的博客中&#xff0c;我们解决了使用最小的边让各个顶点连通&#xff08;最小生成树&#xff09; 这次我们要解决的问题是现在有一个图&#xff0c;我们要找到一条路&#xff0c;使得从一个顶点到另一个…

java之数组练习

思路&#xff1a; 代码&#xff1a; public static void main(String[] args) {char[] arrnew char[26];for (char i0;i<arr.length;i ){arr[i] (char) (Ai);}System.out.println(arr);} 结果&#xff1a;

VMware使用技巧

目录 1. 系统快照 1.1 拍摄快照 1.2 查看快照 1.3 应用/删除快照 2. 克隆虚拟机 3. 删除虚拟机 1. 系统快照 1.1 拍摄快照 将当前系统的状态保存下来&#xff0c;如果将来系统出现不可修复的故障&#xff0c;使用快照可以恢复操作系统&#xff1b; CentOS7——拍照—…