Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions report_xls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
#
##############################################################################

from . import ir_report
from . import report_xls
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
28 changes: 15 additions & 13 deletions report_xls/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
##############################################################################
{
'name': 'Excel report engine',
'version': '0.4.1',
'version': '0.6',
'license': 'AGPL-3',
'author': 'Noviat',
'website': 'http://www.noviat.com',
Expand All @@ -30,16 +30,17 @@
Excel report engine
===================

This module adds Excel export capabilities to the standard OpenERP reporting engine.
This module adds Excel export capabilities to the standard odoo reporting
engine.

Report development
''''''''''''''''''
In order to create an Excel report you can\n
- define a report of type 'xls'
- pass ``{'xls_export': 1}`` via the context to the report create method

The ``report_xls`` class contains a number of attributes and methods to facilitate
the creation XLS reports in OpenERP.
The ``report_xls`` class contains a number of attributes and methods to
facilitate the creation XLS reports in OpenERP.

* cell types

Expand All @@ -52,28 +53,29 @@

* cell formulas

Cell formulas can be easily added with the help of the ``rowcol_to_cell()`` function which
you can import from the ``utils.py`` module.
Cell formulas can be easily added with the help of the ``rowcol_to_cell()``
function which you can import from the ``utils.py`` module.

* Excel templates

It is possible to define Excel templates which can be adapted by 'inherited' modules.
Download the ``account_move_line_report_xls`` module from http://apps.openerp.com
as example.
It is possible to define Excel templates which can be adapted
by 'inherited' modules.
Download the ``account_move_line_report_xls`` module
from http://apps.odoo.com as example.

* XLS with multiple sheets

Download the ``account_journal_report_xls`` module from http://apps.openerp.com as example.
Download the ``account_journal_report_xls`` module
from http://apps.odoo.com as example.

Development assistance
''''''''''''''''''''''
Contact info@noviat.com for help with the development of Excel reports in OpenERP.
Contact info@noviat.com for help with the development of
Excel reports in odoo.

""",
'depends': ['base'],
'external_dependencies': {'python': ['xlwt']},
'demo': [],
'data': [],
'active': False,
'installable': True,
}
Expand Down
36 changes: 36 additions & 0 deletions report_xls/ir_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
#
# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import fields, orm


class ir_actions_report_xml(orm.Model):
_inherit = 'ir.actions.report.xml'

def _check_selection_field_value(self, cr, uid,
field, value, context=None):
if field == 'report_type' and value == 'xls':
return
return super(ir_actions_report_xml, self)._check_selection_field_value(
cr, uid, field, value, context=context)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
65 changes: 42 additions & 23 deletions report_xls/report_xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# OpenERP, Open Source Management Solution
#
# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
# Copyright (c) 2014 Noviat nv/sa (www.noviat.com). All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand All @@ -16,7 +16,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

Expand Down Expand Up @@ -60,8 +60,8 @@ class report_xls(report_sxw):

# header/footer
hf_params = {
'font_size': 8,
'font_style': 'I', # B: Bold, I: Italic, U: Underline
'font_size': 8,
'font_style': 'I', # B: Bold, I: Italic, U: Underline
}

# styles
Expand All @@ -77,8 +77,12 @@ class report_xls(report_sxw):
'fill': 'pattern: pattern solid, fore_color %s;' % _pfc,
'fill_blue': 'pattern: pattern solid, fore_color 27;',
'fill_grey': 'pattern: pattern solid, fore_color 22;',
'borders_all': 'borders: left thin, right thin, top thin, bottom thin, '
'left_colour %s, right_colour %s, top_colour %s, bottom_colour %s;' % (_bc, _bc, _bc, _bc),
'borders_all':
'borders: '
'left thin, right thin, top thin, bottom thin, '
'left_colour %s, right_colour %s, '
'top_colour %s, bottom_colour %s;'
% (_bc, _bc, _bc, _bc),
'left': 'align: horz left;',
'center': 'align: horz center;',
'right': 'align: horz right;',
Expand All @@ -93,15 +97,17 @@ def create(self, cr, uid, ids, data, context=None):
self.cr = cr
self.uid = uid
report_obj = self.pool.get('ir.actions.report.xml')
report_ids = report_obj.search(cr, uid,
[('report_name', '=', self.name[7:])], context=context)
report_ids = report_obj.search(
cr, uid, [('report_name', '=', self.name[7:])], context=context)
if report_ids:
report_xml = report_obj.browse(cr, uid, report_ids[0], context=context)
report_xml = report_obj.browse(
cr, uid, report_ids[0], context=context)
self.title = report_xml.name
if report_xml.report_type == 'xls':
return self.create_source_xls(cr, uid, ids, data, context)
elif context.get('xls_export'):
self.table = data.get('model') or self.table # use model from 'data' when no ir.actions.report.xml entry
# use model from 'data' when no ir.actions.report.xml entry
self.table = data.get('model') or self.table
return self.create_source_xls(cr, uid, ids, data, context)
return super(report_xls, self).create(cr, uid, ids, data, context)

Expand All @@ -110,6 +116,7 @@ def create_source_xls(self, cr, uid, ids, data, context=None):
context = {}
parser_instance = self.parser(cr, uid, self.name2, context)
self.parser_instance = parser_instance
self.context = context
objs = self.getObjects(cr, uid, ids, context)
parser_instance.set_context(objs, data, ids, 'xls')
objs = parser_instance.localcontext['objects']
Expand All @@ -120,10 +127,14 @@ def create_source_xls(self, cr, uid, ids, data, context=None):
self.xls_headers = {
'standard': '',
}
report_date = datetime_field.context_timestamp(cr, uid, datetime.now(), context).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
report_date = datetime_field.context_timestamp(
cr, uid, datetime.now(), context)
report_date = report_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
self.xls_footers = {
'standard': ('&L&%(font_size)s&%(font_style)s' + report_date +
'&R&%(font_size)s&%(font_style)s&P / &N') % self.hf_params,
'standard': (
'&L&%(font_size)s&%(font_style)s' + report_date +
'&R&%(font_size)s&%(font_style)s&P / &N'
) % self.hf_params,
}
self.generate_xls_report(_p, _xs, data, objs, wb)
wb.save(n)
Expand All @@ -138,7 +149,8 @@ def render(self, wanted, col_specs, rowtype, render_space='empty'):
- wanted: element from the wanted_list
- col_specs : cf. specs[1:] documented in xls_row_template method
- rowtype : 'header' or 'data'
- render_space : type dict, (caller_space + localcontext) if not specified
- render_space : type dict, (caller_space + localcontext)
if not specified
"""
if render_space == 'empty':
render_space = {}
Expand All @@ -151,7 +163,6 @@ def render(self, wanted, col_specs, rowtype, render_space='empty'):
if isinstance(row[i], CodeType):
row[i] = eval(row[i], render_space)
row.insert(0, wanted)
#_logger.warn('row O = %s', row)
return row

def generate_xls_report(self, parser, xls_styles, data, objects, wb):
Expand All @@ -163,11 +174,13 @@ def xls_row_template(self, specs, wanted_list):
Returns a row template.

Input :
- 'wanted_list': list of Columns that will be returned in the row_template
- 'wanted_list': list of Columns that will be returned in the
row_template
- 'specs': list with Column Characteristics
0: Column Name (from wanted_list)
1: Column Colspan
2: Column Size (unit = the width of the character ’0′ as it appears in the sheet’s default font)
2: Column Size (unit = the width of the character ’0′
as it appears in the sheet’s default font)
3: Column Type
4: Column Data
5: Column Formula (or 'None' for Data)
Expand All @@ -186,7 +199,8 @@ def xls_row_template(self, specs, wanted_list):
if s_len > 5 and s[5] is not None:
c.append({'formula': s[5]})
else:
c.append({'write_cell_func': report_xls.xls_types[c[3]]})
c.append({
'write_cell_func': report_xls.xls_types[c[3]]})
# Set custom cell style
if s_len > 6 and s[6] is not None:
c.append(s[6])
Expand All @@ -201,23 +215,28 @@ def xls_row_template(self, specs, wanted_list):
col += c[1]
break
if not found:
_logger.warn("report_xls.xls_row_template, column '%s' not found in specs", w)
_logger.warn("report_xls.xls_row_template, "
"column '%s' not found in specs", w)
return r

def xls_write_row(self, ws, row_pos, row_data, row_style=default_style, set_column_size=False):
def xls_write_row(self, ws, row_pos, row_data,
row_style=default_style, set_column_size=False):
r = ws.row(row_pos)
for col, size, spec in row_data:
data = spec[4]
formula = spec[5].get('formula') and xlwt.Formula(spec[5]['formula']) or None
formula = spec[5].get('formula') and \
xlwt.Formula(spec[5]['formula']) or None
style = spec[6] and spec[6] or row_style
if not data:
# if no data, use default values
data = report_xls.xls_types_default[spec[3]]
if size != 1:
if formula:
ws.write_merge(row_pos, row_pos, col, col + size - 1, data, style)
ws.write_merge(
row_pos, row_pos, col, col + size - 1, data, style)
else:
ws.write_merge(row_pos, row_pos, col, col + size - 1, data, style)
ws.write_merge(
row_pos, row_pos, col, col + size - 1, data, style)
else:
if formula:
ws.write(row_pos, col, formula, style)
Expand Down
Binary file added report_xls/static/description/help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions report_xls/static/description/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Excel report engine</h2>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img src="open_receivables.png">
</div>
</div>
<div class="oe_span6">
<p class="oe_mt32">
<br><br>This module adds Excel export capabilities to the standard odoo reporting engine.
</p>
</div>
</div>
</section>

<section class="oe_spaced oe_container oe_dark">
<div class="oe_row">
<h2 class="oe_slogan">Report development</h2>
<p class="oe_mt32">
In order to create an Excel report you can
<ul>
<li>define a report of type 'xls'</li>
<li>pass <code>{'xls_export': 1}</code> via the context to the report create method</li>
</ul>
</p>
<p class="oe_mt32">
The <code>report_xls</code> class contains a number of attributes and methods to facilitate the creation XLS reports in odoo.
<ul>
<li>
cell types
<br>Supported cell types : text, number, boolean, date.
</li>
</ul>
<ul>
<li>
cell styles
<br>The predefined cell style definitions result in a consistent look and feel of the odoo Excel reports.
</li>
</ul>
<ul>
<li>
cell formulas
<br>Cell formulas can be easily added with the help of the <code>rowcol_to_cell()</code> function which you can import from the <code>utils.py</code> module.
</li>
</ul>
<ul>
<li>
Excel templates
<br>It is possible to define Excel templates which can be adapted by 'inherited' modules.
<br>Download the <b>account_move_line_report_xls</b> module from <a href="http://apps.odoo.com">http://apps.odoo.com</a> as example.
</li>
</ul>
<ul>
<li>
XLS with multiple sheets
<br>Download the <b>account_journal_report_xls</b> module from <a href="http://apps.odoo.com">http://apps.odoo.com</a> as example.
</li>
</ul>
</p>
</div>
</section>

<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Development assistance</h2>
</div>
<div class="oe_span6">
<br>
<div class="oe_picture">
<center><img src="help.png" height="150"></center>
</div>
</div>
<div class="oe_span6">
<p class="oe_mt32">
<br><br>Contact <a href="mailto:info@noviat.com">info@noviat.com</a> for help with the development of Excel reports in odoo.
</p>
</div>
</div>
</section>

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion report_xls/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def _render(code):
def rowcol_to_cell(row, col, row_abs=False, col_abs=False):
# Code based upon utils from xlwt distribution
"""
Convert numeric row/col notation to an Excel cell reference string in A1 notation.
Convert numeric row/col notation to an Excel cell
reference string in A1 notation.
"""
d = col // 26
m = col % 26
Expand Down