Odoo中文社区可以通过以下三个域名访问:shine-it.net , odoocn.org,odoo.net.cn

原论坛用户的基本信息和发帖这里都予以保留,请注意:原论坛用户无需重新注册新用户,但是您的密码需要重置

开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

如果您登录系统碰到问题,请在微信公众号留言:

【分享-oe嵌入qweb】用js读取数据库数据,用类似html语言重写web报表



  • 本来是开发个报表模块,具体功能为:OE读取excel表格-web显示-导出成excel。
    做完了拿给老板看时,老板对web显示这一块大不满意(用的OE自带的form页面),觉得人性化方便做的不到位,让我重新设计web页面,于是开始了为期一个月的前端研究。

    起先是打算自己脱离OE搞个前端来显示这个报表,用的是Django做了一个页面,做的差不多时拿给老板看,老板说从OE再弹出个窗口体验性差,叫我整合进OE里,当时我就(此处省略若干字。。)

    不得已就去翻官网文档,看到这篇文档:https://doc.odoo.com/trunk/training/web_framework/
    后大有启发,决定用qweb来写这个报表。其中多亏了群里的高手指点,才得以实现呀

    看了这么久是不是着急看代码 8),嘿嘿。。

    首先从梦姑处偷了点经验,看了他的帖子:http://shine-it.net/index.php/topic,16514.0.html

    他的贴子里的我就不重复了

    先是js读取数据库:

    start: function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var self = this;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new instance.web.Model(&quot;lcqc.date.table.smt.data&quot;).query().filter([[&quot;smt_qctable_id&quot;, &quot;=&quot;, 139]])<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .all().then(function(result) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(&quot;##################the message_of_the_day result is&quot;, result);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.$el.append($(QWeb.render(&quot;MessageofTheDay&quot;, {item: result})));<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });<br />&nbsp; &nbsp; &nbsp; &nbsp; },
    


    值得注意的是得到的是一个object
    然后把参数item: result传递给qweb。
    qweb代码:

    &lt;t t-name=&quot;MessageofTheDay&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;oe_petstore_motd&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;table&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;t t-foreach=&quot;item&quot; t-as=&quot;qname&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &lt;tr&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;t t-esc=&quot;qname.date_smtqc_statistical_table&quot;/&gt;&lt;/td&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;t t-esc=&quot;qname.inspector_smtqc_st&quot;/&gt;&lt;/td&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ..................<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &lt;/tr&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/t&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/table&gt;<br />&nbsp; &nbsp; &lt;/t&gt;
    


    注意qweb的name字段等与js中的关联,就不一一说了,仔细看就看出来了。

    然后就是整合进OE:
    首先是__openerp__.py中的定义:
        'data': ['qc_table_qweb.xml'],
        "js": ["static/src/js/.js"],
        "css": ["static/src/css/
    .css"],
        "qweb": ["static/src/xml/*.xml"], 
    其中qc_table_qweb.xml放在模块的根目录里,其代码:

    &lt;openerp&gt;<br />&nbsp; &nbsp; &lt;data&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;record model=&quot;ir.actions.client&quot; id=&quot;action_client_example&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;name&quot;&gt;Example Client Action&lt;/field&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;tag&quot;&gt;example.action&lt;/field&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;/record&gt;<br />		&lt;menuitem id=&quot;qc_table_qweb_menu&quot; name=&quot;QC报表qweb&quot; sequence=&quot;20&quot; parent=&quot;qc_table_menu&quot;/&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem action=&quot;action_client_example&quot; id=&quot;menu_client_example&quot; parent=&quot;qc_table_qweb_menu&quot; name=&quot;qc_smt日报表qweb&quot;/&gt;<br />&nbsp; &nbsp; &lt;/data&gt;<br />&lt;/openerp&gt;
    



    同样注意下name字段与js的关联,才能保证正确显示。

    css:

    .oe_petstore_motd td,th{<br />&nbsp; &nbsp; border:1px solid blue;<br />}<br />.oe_petstore_motd td{<br />&nbsp; &nbsp; color:#F80E0E;<br />}
    


    其实我还是建议看上面的英文文档,跟着教程一步一步走,才能把握到精髓呀!

    下面上一张效果图:



  • 先贊一下,

    暂时看不懂



  • 历害哦。


  • 管理员

    分享的很完整,谢谢!



  • 结合 上面几篇文章  掉坑了,然后 找老刘 要了 样例  bzr branch lp:~niv-openerp/+junk/oepetstore -r 1

    然后从坑里 爬了出来

    安装 这个  教程 [检测到链接无效,已移除] br />
    看 楼主的 顺序 ,没理解前都会copy  看看 能不能运行。。  js  ,xml 写了,然后掉坑里了

    1、出菜单 ,贴代码

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />&lt;openerp&gt;<br />&nbsp; &nbsp; &lt;data&gt;<br />&nbsp; &nbsp; &nbsp; &lt;!-- Top menu item --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem name=&quot;Test&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id=&quot;menu_test_root&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sequence=&quot;30&quot;/&gt;<br />&nbsp; &nbsp;  &lt;record model=&quot;ir.actions.client&quot; id=&quot;action_client_example&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;name&quot;&gt;Example Client Action&lt;/field&gt;<br />&nbsp;  &lt;!-- 此处 name&nbsp; 修改了 浏览器 title&nbsp; &nbsp; --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;tag&quot;&gt;petstore.homepage&lt;/field&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp;  &lt;!-- 此处 tag 内容 要对应&nbsp; js&nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp;  instance.web.client_actions.add(&#039;petstore.homepage&#039;, &#039;instance.oepetstore.HomePage&#039;);<br /><br />这个 阿狸木有 解释,或者不解释 。<br /><br />济南-stone&nbsp; 提示 过 , “找action.tag是否写对”&nbsp; 结果不得要领<br />看了样例才知道<br />&nbsp; &nbsp; &nbsp; &nbsp;  --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;/record&gt;<br /> &lt;!-- 此处 tag 内容 要对应&nbsp; js&nbsp; &nbsp;  这个 阿狸木有 解释,或者不解释 。<br />&nbsp; --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem id=&quot;test_qweb_menu&quot; name=&quot;test qweb&quot; sequence=&quot;20&quot; parent=&quot;menu_test_root&quot;/&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem action=&quot;action_client_example&quot; id=&quot;menu_client_example&quot; parent=&quot;test_qweb_menu&quot; name=&quot;test report qweb&quot;/&gt;<br />&nbsp; &nbsp; &lt;/data&gt;<br />&lt;/openerp&gt;
    






    2 、js 代码


    <br />openerp.oepetstore = function(instance) {<br />&nbsp; &nbsp; var _t = instance.web._t,<br />&nbsp; &nbsp; &nbsp; &nbsp; _lt = instance.web._lt;<br />&nbsp; &nbsp; var QWeb = instance.web.qweb;<br /><br />&nbsp; &nbsp; instance.oepetstore = {};<br /><br /> /*&nbsp;  instance.oepetstore.HomePage = instance.web.Widget.extend({<br />&nbsp; &nbsp; &nbsp; &nbsp; start: function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(&quot;pet store home page loaded&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; },<br />&nbsp; &nbsp; });<br />&nbsp; &nbsp; */<br />&nbsp; &nbsp; instance.oepetstore.HomePage = instance.web.Widget.extend({<br />&nbsp; &nbsp; &nbsp; &nbsp; start: function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var self = this;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var model = new instance.web.Model(&quot;message_of_the_day&quot;);<br />//message_of_the_day&nbsp;  是py 定义了一个 类&nbsp; <br />//下面的 my_method&nbsp; 在py 类message_of_the_day&nbsp; &nbsp; 里有定义<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; model.call(&quot;my_method&quot;, &#91;], {context: new instance.web.CompoundContext()}).then(function(result) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.$el.append(&quot;&lt;div&gt;Hello &quot; + result[&quot;hello&quot;] + &quot;&lt;/div&gt;&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // will show &quot;Hello world&quot; to the user<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });<br />&nbsp; &nbsp; &nbsp; &nbsp; },<br />&nbsp; &nbsp; });<br />// instance.oepetstore.btn_start&nbsp; 是 copy 梦菇的 代码 ,木有 调用<br />&nbsp; &nbsp; instance.oepetstore.btn_start = function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; var self = this;<br />&nbsp; &nbsp; &nbsp; &nbsp; alert(&#039;test&#039;);<br />&nbsp; &nbsp; &nbsp; &nbsp; return false;<br />&nbsp; &nbsp; };<br />&nbsp; &nbsp; <br />&nbsp;  <br />&nbsp; &nbsp; function aaa(){<br />&nbsp; &nbsp; &nbsp; &nbsp; alert(123);<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; // 这里 定义了 ,然后&nbsp; xml 里 才能调用&nbsp; &nbsp; &nbsp;  &lt;field name=&quot;tag&quot;&gt;petstore.homepage&lt;/field&gt;<br />&nbsp; &nbsp; instance.web.client_actions.add(&#039;petstore.homepage&#039;, &#039;instance.oepetstore.HomePage&#039;);<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; instance.web.client_actions.add(&#039;bt_start&#039;, &#039;instance.oepetstore.btn_start&#039;);<br /><br /><br />}<br />
    




    3、贴下 py 代码

    <br />from openerp.osv import osv, fields<br /># 通过 js&nbsp; <br /># var model = new instance.web.Model(&quot;message_of_the_day&quot;);<br /># 调用 该类 <br />class message_of_the_day(osv.osv):<br />&nbsp; &nbsp; _name = &quot;message_of_the_day&quot;<br /><br />#通过&nbsp; js <br />#&nbsp; model.call(&quot;my_method&quot;, &#91;], {context: new instance.web.CompoundContext()}).then(function(result) {<br />#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.$el.append(&quot;&lt;div&gt;Hello &quot; + result[&quot;hello&quot;] + &quot;&lt;/div&gt;&quot;);<br /># 调用&nbsp; 下面 方法&nbsp; 通过 model.call (&quot;my_method&quot;, ....<br />&nbsp; &nbsp; def my_method(self, cr, uid, context=None):<br />&nbsp; &nbsp; &nbsp; &nbsp; return {&quot;hello&quot;: &quot;world&quot;}<br /><br />&nbsp; &nbsp; _columns = {<br />&nbsp; &nbsp; &nbsp; &nbsp; &#039;message&#039;: fields.text(string=&quot;Message&quot;),<br />&nbsp; &nbsp; &nbsp; &nbsp; &#039;color&#039;: fields.char(string=&quot;Color&quot;, size=20),<br />&nbsp; &nbsp; }<br />
    



    这样 界面可以出  hello  world



  • [quote author=行云流水 link=topic=16554.msg28741#msg28741 date=1408090429]
    结合 上面几篇文章  掉坑了,然后 找老刘 要了 样例  bzr branch lp:~niv-openerp/+junk/oepetstore -r 1

    然后从坑里 爬了出来

    安装 这个  教程 [检测到链接无效,已移除] br />
    看 楼主的 顺序 ,没理解前都会copy  看看 能不能运行。。  js  ,xml 写了,然后掉坑里了

    1、出菜单 ,贴代码

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />&lt;openerp&gt;<br />&nbsp; &nbsp; &lt;data&gt;<br />&nbsp; &nbsp; &nbsp; &lt;!-- Top menu item --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem name=&quot;Test&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id=&quot;menu_test_root&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sequence=&quot;30&quot;/&gt;<br />&nbsp; &nbsp;  &lt;record model=&quot;ir.actions.client&quot; id=&quot;action_client_example&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;name&quot;&gt;Example Client Action&lt;/field&gt;<br />&nbsp;  &lt;!-- 此处 name&nbsp; 修改了 浏览器 title&nbsp; &nbsp; --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;field name=&quot;tag&quot;&gt;petstore.homepage&lt;/field&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp;  &lt;!-- 此处 tag 内容 要对应&nbsp; js&nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp;  instance.web.client_actions.add(&#039;petstore.homepage&#039;, &#039;instance.oepetstore.HomePage&#039;);<br /><br />这个 阿狸木有 解释,或者不解释 。<br /><br />济南-stone&nbsp; 提示 过 , “找action.tag是否写对”&nbsp; 结果不得要领<br />看了样例才知道<br />&nbsp; &nbsp; &nbsp; &nbsp;  --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;/record&gt;<br /> &lt;!-- 此处 tag 内容 要对应&nbsp; js&nbsp; &nbsp;  这个 阿狸木有 解释,或者不解释 。<br />&nbsp; --&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem id=&quot;test_qweb_menu&quot; name=&quot;test qweb&quot; sequence=&quot;20&quot; parent=&quot;menu_test_root&quot;/&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;menuitem action=&quot;action_client_example&quot; id=&quot;menu_client_example&quot; parent=&quot;test_qweb_menu&quot; name=&quot;test report qweb&quot;/&gt;<br />&nbsp; &nbsp; &lt;/data&gt;<br />&lt;/openerp&gt;
    





    这样 界面可以出  hello  world

    [/quote]

    我上面说了, 注意qweb的name字段等与js中的关联,就不一一说了,仔细看就看出来了。

    。。。

    PS: 你这坑掉的可真深啊 😉



  • 具体怎么把读取数据后的表格导出成一个excel文件呢?谢谢!



  • 学习一下,用这种方式做报表似乎还是很方便的。。。



  • [quote author=神仙采葡萄 link=topic=16554.msg28959#msg28959 date=1410492180]
    具体怎么把读取数据后的表格导出成一个excel文件呢?谢谢!
    [/quote]
    开发导出模块,大概就是用python读取数据库然后导出成excel。
    一般用xlrd等



  • 多谢分享