[IMP] report_xlsx: pre-commit auto fixes

pull/819/head
tien-ld 2023-11-22 22:48:09 +07:00
parent dc48b19cff
commit 2381d65fb1
14 changed files with 599 additions and 578 deletions

Binary file not shown.

View File

@ -17,13 +17,13 @@ Base report xlsx
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/16.0/report_xlsx :target: https://github.com/OCA/reporting-engine/tree/17.0/report_xlsx
:alt: OCA/reporting-engine :alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-report_xlsx :target: https://translation.odoo-community.org/projects/reporting-engine-17-0/reporting-engine-17-0-report_xlsx
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=16.0 :target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=17.0
:alt: Try me on Runboat :alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -38,49 +38,59 @@ This module provides a basic report class to generate xlsx report.
Installation Installation
============ ============
Make sure you have ``xlsxwriter`` Python module installed:: Make sure you have ``xlsxwriter`` Python module installed:
$ pip3 install xlsxwriter ::
For testing it is also necessary ``xlrd`` Python module installed:: $ pip3 install xlsxwriter
$ pip3 install xlrd For testing it is also necessary ``xlrd`` Python module installed:
::
$ pip3 install xlrd
Usage Usage
===== =====
An example of XLSX report for partners on a module called `module_name`: An example of XLSX report for partners on a module called
\`module_name\`:
A python class :: A python class :
from odoo import models ::
class PartnerXlsx(models.AbstractModel): from odoo import models
_name = 'report.module_name.report_name'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, data, partners): class PartnerXlsx(models.AbstractModel):
for obj in partners: _name = 'report.module_name.report_name'
report_name = obj.name _inherit = 'report.report_xlsx.abstract'
# One sheet by partner
sheet = workbook.add_worksheet(report_name[:31]) def generate_xlsx_report(self, workbook, data, partners):
bold = workbook.add_format({'bold': True}) for obj in partners:
sheet.write(0, 0, obj.name, bold) report_name = obj.name
# One sheet by partner
sheet = workbook.add_worksheet(report_name[:31])
bold = workbook.add_format({'bold': True})
sheet.write(0, 0, obj.name, bold)
To manipulate the ``workbook`` and ``sheet`` objects, refer to the To manipulate the ``workbook`` and ``sheet`` objects, refer to the
`documentation <http://xlsxwriter.readthedocs.org/>`_ of ``xlsxwriter``. `documentation <http://xlsxwriter.readthedocs.org/>`__ of
``xlsxwriter``.
A report XML record :: A report XML record :
<report ::
id="partner_xlsx"
model="res.partner" <report
string="Print to XLSX" id="partner_xlsx"
report_type="xlsx" model="res.partner"
name="module_name.report_name" string="Print to XLSX"
file="res_partner" report_type="xlsx"
attachment_use="False" name="module_name.report_name"
/> file="res_partner"
attachment_use="False"
/>
Bug Tracker Bug Tracker
=========== ===========
@ -88,7 +98,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xlsx%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xlsx%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@ -96,27 +106,27 @@ Credits
======= =======
Authors Authors
~~~~~~~ -------
* ACSONE SA/NV * ACSONE SA/NV
* Creu Blanca * Creu Blanca
Contributors Contributors
~~~~~~~~~~~~ ------------
* Adrien Peiffer <adrien.peiffer@acsone.eu> - Adrien Peiffer <adrien.peiffer@acsone.eu>
* S??bastien Alix <sebastien.alix@osiell.com> - S??bastien Alix <sebastien.alix@osiell.com>
* St??phane Bidoul <stephane.bidoul@acsone.eu> - St??phane Bidoul <stephane.bidoul@acsone.eu>
* Enric Tobella <etobella@creublanca.es> - Enric Tobella <etobella@creublanca.es>
* Graeme Gellatly <gdgellatly@gmail.com> - Graeme Gellatly <gdgellatly@gmail.com>
* Cristian Salamea <cs@prisehub.com> - Cristian Salamea <cs@prisehub.com>
* Rod Schouteden <rod.schouteden@dynapps.be> - Rod Schouteden <rod.schouteden@dynapps.be>
* Eugene Molotov <molotov@it-projects.info> - Eugene Molotov <molotov@it-projects.info>
* Christopher Ormaza <chris.ormaza@forgeflow.com> - Christopher Ormaza <chris.ormaza@forgeflow.com>
* Houz??fa Abbasbhay <houzefa.abba@xcg-consulting.fr> - Houz??fa Abbasbhay <houzefa.abba@xcg-consulting.fr>
Maintainers Maintainers
~~~~~~~~~~~ -----------
This module is maintained by the OCA. This module is maintained by the OCA.
@ -128,6 +138,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/16.0/report_xlsx>`_ project on GitHub. This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/17.0/report_xlsx>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -11,6 +11,8 @@ from odoo.http import (
content_disposition, content_disposition,
request, request,
route, route,
)
from odoo.http import (
serialize_exception as _serialize_exception, serialize_exception as _serialize_exception,
) )
from odoo.tools import html_escape from odoo.tools import html_escape
@ -69,8 +71,9 @@ class ReportController(ReportController):
url_decode(url.split("?")[1]).items() url_decode(url.split("?")[1]).items()
) # decoding the args represented in JSON ) # decoding the args represented in JSON
if "context" in data: if "context" in data:
context, data_context = json.loads(context or "{}"), json.loads( context, data_context = (
data.pop("context") json.loads(context or "{}"),
json.loads(data.pop("context")),
) )
context = json.dumps({**context, **data_context}) context = json.dumps({**context, **data_context})
response = self.report_routes( response = self.report_routes(

View File

@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@ -0,0 +1,10 @@
- Adrien Peiffer \<<adrien.peiffer@acsone.eu>\>
- S??bastien Alix \<<sebastien.alix@osiell.com>\>
- St??phane Bidoul \<<stephane.bidoul@acsone.eu>\>
- Enric Tobella \<<etobella@creublanca.es>\>
- Graeme Gellatly \<<gdgellatly@gmail.com>\>
- Cristian Salamea \<<cs@prisehub.com>\>
- Rod Schouteden \<<rod.schouteden@dynapps.be>\>
- Eugene Molotov \<<molotov@it-projects.info>\>
- Christopher Ormaza \<<chris.ormaza@forgeflow.com>\>
- Houz??fa Abbasbhay \<<houzefa.abba@xcg-consulting.fr>\>

View File

@ -1,10 +0,0 @@
* Adrien Peiffer <adrien.peiffer@acsone.eu>
* S??bastien Alix <sebastien.alix@osiell.com>
* St??phane Bidoul <stephane.bidoul@acsone.eu>
* Enric Tobella <etobella@creublanca.es>
* Graeme Gellatly <gdgellatly@gmail.com>
* Cristian Salamea <cs@prisehub.com>
* Rod Schouteden <rod.schouteden@dynapps.be>
* Eugene Molotov <molotov@it-projects.info>
* Christopher Ormaza <chris.ormaza@forgeflow.com>
* Houz??fa Abbasbhay <houzefa.abba@xcg-consulting.fr>

View File

@ -1 +1 @@
This module provides a basic report class to generate xlsx report. This module provides a basic report class to generate xlsx report.

View File

@ -0,0 +1,7 @@
Make sure you have `xlsxwriter` Python module installed:
$ pip3 install xlsxwriter
For testing it is also necessary `xlrd` Python module installed:
$ pip3 install xlrd

View File

@ -1,7 +0,0 @@
Make sure you have ``xlsxwriter`` Python module installed::
$ pip3 install xlsxwriter
For testing it is also necessary ``xlrd`` Python module installed::
$ pip3 install xlrd

View File

@ -1,32 +1,33 @@
An example of XLSX report for partners on a module called `module_name`: An example of XLSX report for partners on a module called
\`module_name\`:
A python class ::
A python class :
from odoo import models
from odoo import models
class PartnerXlsx(models.AbstractModel):
_name = 'report.module_name.report_name' class PartnerXlsx(models.AbstractModel):
_inherit = 'report.report_xlsx.abstract' _name = 'report.module_name.report_name'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, data, partners):
for obj in partners: def generate_xlsx_report(self, workbook, data, partners):
report_name = obj.name for obj in partners:
# One sheet by partner report_name = obj.name
sheet = workbook.add_worksheet(report_name[:31]) # One sheet by partner
bold = workbook.add_format({'bold': True}) sheet = workbook.add_worksheet(report_name[:31])
sheet.write(0, 0, obj.name, bold) bold = workbook.add_format({'bold': True})
sheet.write(0, 0, obj.name, bold)
To manipulate the ``workbook`` and ``sheet`` objects, refer to the
`documentation <http://xlsxwriter.readthedocs.org/>`_ of ``xlsxwriter``. To manipulate the `workbook` and `sheet` objects, refer to the
[documentation](http://xlsxwriter.readthedocs.org/) of `xlsxwriter`.
A report XML record ::
A report XML record :
<report
id="partner_xlsx" <report
model="res.partner" id="partner_xlsx"
string="Print to XLSX" model="res.partner"
report_type="xlsx" string="Print to XLSX"
name="module_name.report_name" report_type="xlsx"
file="res_partner" name="module_name.report_name"
attachment_use="False" file="res_partner"
/> attachment_use="False"
/>

View File

@ -45,7 +45,7 @@ try:
re.search(pattern, sheetname) and int(sheetname[-2:]) or 0 re.search(pattern, sheetname) and int(sheetname[-2:]) or 0
) )
# Only up to 100 duplicates # Only up to 100 duplicates
deduplicated_secuence = "~{:02d}".format(duplicated_secuence + 1) deduplicated_secuence = f"~{duplicated_secuence + 1:02d}"
if duplicated_secuence > 99: if duplicated_secuence > 99:
raise xlsxwriter.exceptions.DuplicateWorksheetName # noqa: B904 raise xlsxwriter.exceptions.DuplicateWorksheetName # noqa: B904
if duplicated_secuence: if duplicated_secuence:

View File

@ -1,478 +1,480 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" /> <meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Base report xlsx</title> <title>Base report xlsx</title>
<style type="text/css"> <style type="text/css">
/* /*
:Author: David Goodger (goodger@python.org) :Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ :Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain. :Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils. Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet. customize this style sheet.
*/ */
/* used to remove borders from tables and images */ /* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th { .borderless, table.borderless td, table.borderless th {
border: 0 } border: 0 }
table.borderless td, table.borderless th { table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important". /* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */ The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important } padding: 0 0.5em 0 0 ! important }
.first { .first {
/* Override more specific margin styles with "! important". */ /* Override more specific margin styles with "! important". */
margin-top: 0 ! important } margin-top: 0 ! important }
.last, .with-subtitle { .last, .with-subtitle {
margin-bottom: 0 ! important } margin-bottom: 0 ! important }
.hidden { .hidden {
display: none } display: none }
.subscript { .subscript {
vertical-align: sub; vertical-align: sub;
font-size: smaller } font-size: smaller }
.superscript { .superscript {
vertical-align: super; vertical-align: super;
font-size: smaller } font-size: smaller }
a.toc-backref { a.toc-backref {
text-decoration: none ; text-decoration: none ;
color: black } color: black }
blockquote.epigraph { blockquote.epigraph {
margin: 2em 5em ; } margin: 2em 5em ; }
dl.docutils dd { dl.docutils dd {
margin-bottom: 0.5em } margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden; overflow: hidden;
} }
/* Uncomment (and remove this text!) to get bold-faced definition list terms /* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt { dl.docutils dt {
font-weight: bold } font-weight: bold }
*/ */
div.abstract { div.abstract {
margin: 2em 5em } margin: 2em 5em }
div.abstract p.topic-title { div.abstract p.topic-title {
font-weight: bold ; font-weight: bold ;
text-align: center } text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error, div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning { div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ; margin: 2em ;
border: medium outset ; border: medium outset ;
padding: 1em } padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title, div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title, div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title { div.tip p.admonition-title {
font-weight: bold ; font-weight: bold ;
font-family: sans-serif } font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title, div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error { div.warning p.admonition-title, .code .error {
color: red ; color: red ;
font-weight: bold ; font-weight: bold ;
font-family: sans-serif } font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in /* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs. compound paragraphs.
div.compound .compound-first, div.compound .compound-middle { div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em } margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle { div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em } margin-top: 0.5em }
*/ */
div.dedication { div.dedication {
margin: 2em 5em ; margin: 2em 5em ;
text-align: center ; text-align: center ;
font-style: italic } font-style: italic }
div.dedication p.topic-title { div.dedication p.topic-title {
font-weight: bold ; font-weight: bold ;
font-style: normal } font-style: normal }
div.figure { div.figure {
margin-left: 2em ; margin-left: 2em ;
margin-right: 2em } margin-right: 2em }
div.footer, div.header { div.footer, div.header {
clear: both; clear: both;
font-size: smaller } font-size: smaller }
div.line-block { div.line-block {
display: block ; display: block ;
margin-top: 1em ; margin-top: 1em ;
margin-bottom: 1em } margin-bottom: 1em }
div.line-block div.line-block { div.line-block div.line-block {
margin-top: 0 ; margin-top: 0 ;
margin-bottom: 0 ; margin-bottom: 0 ;
margin-left: 1.5em } margin-left: 1.5em }
div.sidebar { div.sidebar {
margin: 0 0 0.5em 1em ; margin: 0 0 0.5em 1em ;
border: medium outset ; border: medium outset ;
padding: 1em ; padding: 1em ;
background-color: #ffffee ; background-color: #ffffee ;
width: 40% ; width: 40% ;
float: right ; float: right ;
clear: right } clear: right }
div.sidebar p.rubric { div.sidebar p.rubric {
font-family: sans-serif ; font-family: sans-serif ;
font-size: medium } font-size: medium }
div.system-messages { div.system-messages {
margin: 5em } margin: 5em }
div.system-messages h1 { div.system-messages h1 {
color: red } color: red }
div.system-message { div.system-message {
border: medium outset ; border: medium outset ;
padding: 1em } padding: 1em }
div.system-message p.system-message-title { div.system-message p.system-message-title {
color: red ; color: red ;
font-weight: bold } font-weight: bold }
div.topic { div.topic {
margin: 2em } margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em } margin-top: 0.4em }
h1.title { h1.title {
text-align: center } text-align: center }
h2.subtitle { h2.subtitle {
text-align: center } text-align: center }
hr.docutils { hr.docutils {
width: 75% } width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left { img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ; clear: left ;
float: left ; float: left ;
margin-right: 1em } margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right { img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ; clear: right ;
float: right ; float: right ;
margin-left: 1em } margin-left: 1em }
img.align-center, .figure.align-center, object.align-center { img.align-center, .figure.align-center, object.align-center {
display: block; display: block;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
table.align-center { table.align-center {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.align-left { .align-left {
text-align: left } text-align: left }
.align-center { .align-center {
clear: both ; clear: both ;
text-align: center } text-align: center }
.align-right { .align-right {
text-align: right } text-align: right }
/* reset inner alignment in figures */ /* reset inner alignment in figures */
div.align-right { div.align-right {
text-align: inherit } text-align: inherit }
/* div.align-center * { */ /* div.align-center * { */
/* text-align: left } */ /* text-align: left } */
.align-top { .align-top {
vertical-align: top } vertical-align: top }
.align-middle { .align-middle {
vertical-align: middle } vertical-align: middle }
.align-bottom { .align-bottom {
vertical-align: bottom } vertical-align: bottom }
ol.simple, ul.simple { ol.simple, ul.simple {
margin-bottom: 1em } margin-bottom: 1em }
ol.arabic { ol.arabic {
list-style: decimal } list-style: decimal }
ol.loweralpha { ol.loweralpha {
list-style: lower-alpha } list-style: lower-alpha }
ol.upperalpha { ol.upperalpha {
list-style: upper-alpha } list-style: upper-alpha }
ol.lowerroman { ol.lowerroman {
list-style: lower-roman } list-style: lower-roman }
ol.upperroman { ol.upperroman {
list-style: upper-roman } list-style: upper-roman }
p.attribution { p.attribution {
text-align: right ; text-align: right ;
margin-left: 50% } margin-left: 50% }
p.caption { p.caption {
font-style: italic } font-style: italic }
p.credits { p.credits {
font-style: italic ; font-style: italic ;
font-size: smaller } font-size: smaller }
p.label { p.label {
white-space: nowrap } white-space: nowrap }
p.rubric { p.rubric {
font-weight: bold ; font-weight: bold ;
font-size: larger ; font-size: larger ;
color: maroon ; color: maroon ;
text-align: center } text-align: center }
p.sidebar-title { p.sidebar-title {
font-family: sans-serif ; font-family: sans-serif ;
font-weight: bold ; font-weight: bold ;
font-size: larger } font-size: larger }
p.sidebar-subtitle { p.sidebar-subtitle {
font-family: sans-serif ; font-family: sans-serif ;
font-weight: bold } font-weight: bold }
p.topic-title { p.topic-title {
font-weight: bold } font-weight: bold }
pre.address { pre.address {
margin-bottom: 0 ; margin-bottom: 0 ;
margin-top: 0 ; margin-top: 0 ;
font: inherit } font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code { pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ; margin-left: 2em ;
margin-right: 2em } margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */ pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee } pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 } pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 } pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 } pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1} pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289} pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier { span.classifier {
font-family: sans-serif ; font-family: sans-serif ;
font-style: oblique } font-style: oblique }
span.classifier-delimiter { span.classifier-delimiter {
font-family: sans-serif ; font-family: sans-serif ;
font-weight: bold } font-weight: bold }
span.interpreted { span.interpreted {
font-family: sans-serif } font-family: sans-serif }
span.option { span.option {
white-space: nowrap } white-space: nowrap }
span.pre { span.pre {
white-space: pre } white-space: pre }
span.problematic { span.problematic {
color: red } color: red }
span.section-subtitle { span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */ /* font-size relative to parent (h1..h6 element) */
font-size: 80% } font-size: 80% }
table.citation { table.citation {
border-left: solid 1px gray; border-left: solid 1px gray;
margin-left: 1px } margin-left: 1px }
table.docinfo { table.docinfo {
margin: 2em 4em } margin: 2em 4em }
table.docutils { table.docutils {
margin-top: 0.5em ; margin-top: 0.5em ;
margin-bottom: 0.5em } margin-bottom: 0.5em }
table.footnote { table.footnote {
border-left: solid 1px black; border-left: solid 1px black;
margin-left: 1px } margin-left: 1px }
table.docutils td, table.docutils th, table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th { table.docinfo td, table.docinfo th {
padding-left: 0.5em ; padding-left: 0.5em ;
padding-right: 0.5em ; padding-right: 0.5em ;
vertical-align: top } vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name { table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ; font-weight: bold ;
text-align: left ; text-align: left ;
white-space: nowrap ; white-space: nowrap ;
padding-left: 0 } padding-left: 0 }
/* "booktabs" style (no vertical lines) */ /* "booktabs" style (no vertical lines) */
table.docutils.booktabs { table.docutils.booktabs {
border: 0px; border: 0px;
border-top: 2px solid; border-top: 2px solid;
border-bottom: 2px solid; border-bottom: 2px solid;
border-collapse: collapse; border-collapse: collapse;
} }
table.docutils.booktabs * { table.docutils.booktabs * {
border: 0px; border: 0px;
} }
table.docutils.booktabs th { table.docutils.booktabs th {
border-bottom: thin solid; border-bottom: thin solid;
text-align: left; text-align: left;
} }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% } font-size: 100% }
ul.auto-toc { ul.auto-toc {
list-style-type: none } list-style-type: none }
</style> </style>
</head> </head>
<body> <body>
<div class="document" id="base-report-xlsx"> <div class="document" id="base-report-xlsx">
<h1 class="title">Base report xlsx</h1> <h1 class="title">Base report xlsx</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:7b3079fe8522598fe2663c2ca653d380f864ca43319b7c0be50e6e83df8794a7 !! source digest: sha256:7b3079fe8522598fe2663c2ca653d380f864ca43319b7c0be50e6e83df8794a7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/reporting-engine/tree/16.0/report_xlsx"><img alt="OCA/reporting-engine" src="https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-report_xlsx"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p> <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/reporting-engine/tree/17.0/report_xlsx"><img alt="OCA/reporting-engine" src="https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/reporting-engine-17-0/reporting-engine-17-0-report_xlsx"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module provides a basic report class to generate xlsx report.</p> <p>This module provides a basic report class to generate xlsx report.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li> <li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li> <li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li> <li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul> <li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li> <li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li> <li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="installation"> <div class="section" id="installation">
<h1><a class="toc-backref" href="#toc-entry-1">Installation</a></h1> <h1><a class="toc-backref" href="#toc-entry-1">Installation</a></h1>
<p>Make sure you have <tt class="docutils literal">xlsxwriter</tt> Python module installed:</p> <p>Make sure you have <tt class="docutils literal">xlsxwriter</tt> Python module installed:</p>
<pre class="literal-block"> <pre class="literal-block">
$ pip3 install xlsxwriter $ pip3 install xlsxwriter
</pre> </pre>
<p>For testing it is also necessary <tt class="docutils literal">xlrd</tt> Python module installed:</p> <p>For testing it is also necessary <tt class="docutils literal">xlrd</tt> Python module installed:</p>
<pre class="literal-block"> <pre class="literal-block">
$ pip3 install xlrd $ pip3 install xlrd
</pre> </pre>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1> <h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>An example of XLSX report for partners on a module called <cite>module_name</cite>:</p> <p>An example of XLSX report for partners on a module called
<p>A python class</p> `module_name`:</p>
<pre class="literal-block"> <p>A python class :</p>
from odoo import models <pre class="literal-block">
from odoo import models
class PartnerXlsx(models.AbstractModel):
_name = 'report.module_name.report_name' class PartnerXlsx(models.AbstractModel):
_inherit = 'report.report_xlsx.abstract' _name = 'report.module_name.report_name'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, data, partners):
for obj in partners: def generate_xlsx_report(self, workbook, data, partners):
report_name = obj.name for obj in partners:
# One sheet by partner report_name = obj.name
sheet = workbook.add_worksheet(report_name[:31]) # One sheet by partner
bold = workbook.add_format({'bold': True}) sheet = workbook.add_worksheet(report_name[:31])
sheet.write(0, 0, obj.name, bold) bold = workbook.add_format({'bold': True})
</pre> sheet.write(0, 0, obj.name, bold)
<p>To manipulate the <tt class="docutils literal">workbook</tt> and <tt class="docutils literal">sheet</tt> objects, refer to the </pre>
<a class="reference external" href="http://xlsxwriter.readthedocs.org/">documentation</a> of <tt class="docutils literal">xlsxwriter</tt>.</p> <p>To manipulate the <tt class="docutils literal">workbook</tt> and <tt class="docutils literal">sheet</tt> objects, refer to the
<p>A report XML record</p> <a class="reference external" href="http://xlsxwriter.readthedocs.org/">documentation</a> of
<pre class="literal-block"> <tt class="docutils literal">xlsxwriter</tt>.</p>
&lt;report <p>A report XML record :</p>
id=&quot;partner_xlsx&quot; <pre class="literal-block">
model=&quot;res.partner&quot; &lt;report
string=&quot;Print to XLSX&quot; id=&quot;partner_xlsx&quot;
report_type=&quot;xlsx&quot; model=&quot;res.partner&quot;
name=&quot;module_name.report_name&quot; string=&quot;Print to XLSX&quot;
file=&quot;res_partner&quot; report_type=&quot;xlsx&quot;
attachment_use=&quot;False&quot; name=&quot;module_name.report_name&quot;
/&gt; file=&quot;res_partner&quot;
</pre> attachment_use=&quot;False&quot;
</div> /&gt;
<div class="section" id="bug-tracker"> </pre>
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1> </div>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/reporting-engine/issues">GitHub Issues</a>. <div class="section" id="bug-tracker">
In case of trouble, please check there if your issue has already been reported. <h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
If you spotted it first, help us to smash it by providing a detailed and welcomed <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/reporting-engine/issues">GitHub Issues</a>.
<a class="reference external" href="https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xlsx%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> In case of trouble, please check there if your issue has already been reported.
<p>Do not contact contributors directly about support or help with technical issues.</p> If you spotted it first, help us to smash it by providing a detailed and welcomed
</div> <a class="reference external" href="https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xlsx%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<div class="section" id="credits"> <p>Do not contact contributors directly about support or help with technical issues.</p>
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1> </div>
<div class="section" id="authors"> <div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2> <h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<ul class="simple"> <div class="section" id="authors">
<li>ACSONE SA/NV</li> <h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<li>Creu Blanca</li> <ul class="simple">
</ul> <li>ACSONE SA/NV</li>
</div> <li>Creu Blanca</li>
<div class="section" id="contributors"> </ul>
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2> </div>
<ul class="simple"> <div class="section" id="contributors">
<li>Adrien Peiffer &lt;<a class="reference external" href="mailto:adrien.peiffer&#64;acsone.eu">adrien.peiffer&#64;acsone.eu</a>&gt;</li> <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<li>S??bastien Alix &lt;<a class="reference external" href="mailto:sebastien.alix&#64;osiell.com">sebastien.alix&#64;osiell.com</a>&gt;</li> <ul class="simple">
<li>St??phane Bidoul &lt;<a class="reference external" href="mailto:stephane.bidoul&#64;acsone.eu">stephane.bidoul&#64;acsone.eu</a>&gt;</li> <li>Adrien Peiffer &lt;<a class="reference external" href="mailto:adrien.peiffer&#64;acsone.eu">adrien.peiffer&#64;acsone.eu</a>&gt;</li>
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li> <li>S??bastien Alix &lt;<a class="reference external" href="mailto:sebastien.alix&#64;osiell.com">sebastien.alix&#64;osiell.com</a>&gt;</li>
<li>Graeme Gellatly &lt;<a class="reference external" href="mailto:gdgellatly&#64;gmail.com">gdgellatly&#64;gmail.com</a>&gt;</li> <li>St??phane Bidoul &lt;<a class="reference external" href="mailto:stephane.bidoul&#64;acsone.eu">stephane.bidoul&#64;acsone.eu</a>&gt;</li>
<li>Cristian Salamea &lt;<a class="reference external" href="mailto:cs&#64;prisehub.com">cs&#64;prisehub.com</a>&gt;</li> <li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
<li>Rod Schouteden &lt;<a class="reference external" href="mailto:rod.schouteden&#64;dynapps.be">rod.schouteden&#64;dynapps.be</a>&gt;</li> <li>Graeme Gellatly &lt;<a class="reference external" href="mailto:gdgellatly&#64;gmail.com">gdgellatly&#64;gmail.com</a>&gt;</li>
<li>Eugene Molotov &lt;<a class="reference external" href="mailto:molotov&#64;it-projects.info">molotov&#64;it-projects.info</a>&gt;</li> <li>Cristian Salamea &lt;<a class="reference external" href="mailto:cs&#64;prisehub.com">cs&#64;prisehub.com</a>&gt;</li>
<li>Christopher Ormaza &lt;<a class="reference external" href="mailto:chris.ormaza&#64;forgeflow.com">chris.ormaza&#64;forgeflow.com</a>&gt;</li> <li>Rod Schouteden &lt;<a class="reference external" href="mailto:rod.schouteden&#64;dynapps.be">rod.schouteden&#64;dynapps.be</a>&gt;</li>
<li>Houz??fa Abbasbhay &lt;<a class="reference external" href="mailto:houzefa.abba&#64;xcg-consulting.fr">houzefa.abba&#64;xcg-consulting.fr</a>&gt;</li> <li>Eugene Molotov &lt;<a class="reference external" href="mailto:molotov&#64;it-projects.info">molotov&#64;it-projects.info</a>&gt;</li>
</ul> <li>Christopher Ormaza &lt;<a class="reference external" href="mailto:chris.ormaza&#64;forgeflow.com">chris.ormaza&#64;forgeflow.com</a>&gt;</li>
</div> <li>Houz??fa Abbasbhay &lt;<a class="reference external" href="mailto:houzefa.abba&#64;xcg-consulting.fr">houzefa.abba&#64;xcg-consulting.fr</a>&gt;</li>
<div class="section" id="maintainers"> </ul>
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2> </div>
<p>This module is maintained by the OCA.</p> <div class="section" id="maintainers">
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>This module is maintained by the OCA.</p>
mission is to support the collaborative development of Odoo features and <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
promote its widespread use.</p> <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/16.0/report_xlsx">OCA/reporting-engine</a> project on GitHub.</p> mission is to support the collaborative development of Odoo features and
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> promote its widespread use.</p>
</div> <p>This module is part of the <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/17.0/report_xlsx">OCA/reporting-engine</a> project on GitHub.</p>
</div> <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div> </div>
</body> </div>
</html> </div>
</body>
</html>

View File

@ -42,7 +42,6 @@ class TestReport(common.TransactionCase):
self.assertEqual(attachment.name, f"{self.docs.name}.xlsx") self.assertEqual(attachment.name, f"{self.docs.name}.xlsx")
def test_id_retrieval(self): def test_id_retrieval(self):
# Typical call from WebUI with wizard # Typical call from WebUI with wizard
objs = self.xlsx_report._get_objs_for_report( objs = self.xlsx_report._get_objs_for_report(
False, {"context": {"active_ids": self.docs.ids}} False, {"context": {"active_ids": self.docs.ids}}

3
requirements.txt 100644
View File

@ -0,0 +1,3 @@
# generated from manifests external_dependencies
xlrd
xlsxwriter