PDF报告¶
With Studio, you can edit existing PDF reports (e.g., invoices, quotations, etc.) or create new ones.
默认布局¶
The default layout of reports is managed outside Studio. Go to , then, in the Companies section, click Configure Document Layout. Layout settings are company-specific but apply to all reports.
小技巧
You can see how the different settings affect the report layout in the report preview on the right, or download a sample invoice PDF by clicking Download PDF Preview.
使用以下设置:
Layout: Four layouts are available:
Font: Seven fonts are available: Lato, Roboto, Open Sans, Montserrat, Oswald, Raleway, and Tajawal (which supports Arabic and Latin scripts). Go to the Google Fonts website to preview them.
Company logo: Click the Edit button to upload or change the logo. This adds the logo to the company’s record on the Company model, which you can access by going to and then clicking Update Info in the Companies section.
Colors: Change the primary and secondary colors used to structure reports. The default colors are automatically generated based on the colors of the logo.
Layout background: The following backgrounds are available:
空白:不显示任何内容。
几何:背景显示几何图片。
Custom: upload a custom background image.
Company tagline: This is displayed in the header of external reports. You can add multiple lines of text.
Company details: These are displayed in the header of external reports. You can add multiple lines of text.
Paper format: to define the default paper size of reports. You can select A4 (21 cm x 29.7 cm), US Letter (21.59 cm x 27.54 cm), or QR codes page. This can also be defined for individual reports in the Paper format field in Studio.
Creating new PDF reports¶
To create a new report for a model, access the model, click the Toggle Studio button, then click Reports. Click New and, in the popup window that opens, select the type of report. This is solely used to determine what is displayed in the header and footer:
创建报告后,您就可以开始 对其进行编辑。
编辑 PDF 报告¶
To access the reports available for a model, access the model (e.g., sales orders), click the Toggle Studio button, then click Reports. Select an existing report to open it or create a new one.
小技巧
或者,您也可以打开 Studio,点击 报告,然后搜索特定报告或模型。
重要
It is strongly recommended to duplicate the standard report and perform changes in the duplicated version. To duplicate a report, hover the mouse pointer on the top right corner of the report, click the vertical ellipsis icon (⋮), and then select Duplicate.
选项¶
Once you’ve selected or created a report, you can use the options in the left part of the screen to:
Change the Report name. The new name is applied everywhere (in Studio, under the Print button, and in the PDF file name).
Modify the Paper format. If no value is selected, the format defined in the default layout is used.
Show in print menu: to add the report in the Print menu available from the record.
从附件重新加载:首次生成报告时,将报告作为附件保存在记录中,并在以后的任何时候重新加载报告的原始版本。这是发票的法定要求,主要用于这种情况。
限制对用户组的可见性:将 PDF 报告的可用性限制在特定的 用户组。
编辑源文件:直接在 XML文件 中修改报告。
重置报告:放弃对报告所做的所有更改,并将其重置为标准版本。
打印预览:生成并下载报告预览。
报告编辑器¶
The report editor allows you to modify the formatting and contents of the report.
小技巧
You can Undo or Redo changes using the related buttons or the shortcuts
CTRL ZandCTRL Y.当您离开报告时,更改会自动保存;您也可以使用 保存 按钮手动保存。
您可以通过点击屏幕左侧的 :guilabel:`重置报告`按钮,将报告重置为其标准版本。
重要
编辑报告的页眉和页脚会影响所有的标准报告和自定义报告。
条件区块¶
虚线矩形代表**条件区块**(if/else 语句)。它们用于根据特定条件来显示或隐藏内容。点击区块即可查看条件。
选择一个值以预览其对应的输出,并在必要时进行编辑。
注解
Conditions can only be edited in XML.
其他内容¶
报告中有两种文本内容:
Static text, i.e., the text that’s not highlighted in blue, which can be modified directly in the editor.
Dynamic text, i.e., the text that’s highlighted in blue, which is replaced by field values when the report is generated, e.g., the SO number or the quotation date.
You can add content (e.g., fields, lists, tables, images, banners, etc.) to the report using
commands. Type / to open the powerbox, then type the command’s
name or select it from the list.
要在报告中添加静态文本,请在需要的位置键入文本。
要进行更高级的更改,您可以 直接在 XML 中编辑报告。
添加一个字段¶
To add a field, type / and select the Field command. In the list that opens, select
or search for the field; click the right arrow next to the field name to access the list of related
fields if needed. Then, specify the default value and press Enter.
Add a data table¶
Data tables are used to display relational fields. To add
a data table, type /, select the Dynamic Table command, and select the relation to be
displayed in the table.
注解
Only relations of type one2many or many2many can be displayed as data tables.
Once the table has been added, you can add columns using the table tools. Position the cursor on top of the column, then click the purple rectangle and select an option.
You can then insert the field of your choice in the columns. The dialog box that opens shows the source object for the field (e.g., the Tag model) and the list of available fields.
注解
The default row automatically iterates over the field’s content, generating a row on the report for each field value (e.g., one row per tag). You can add static content rows above or below the generated rows using the table tools.
You can also add data tables by modifying the report’s XML.
格式化¶
To format text in the report, select it, then format it using the options in the 文本编辑器.
编辑报告的 XML¶
警告
直接修改 XML 可能会在 升级 时导致报告问题。如果出现这种情况,只需将旧数据库中的更改复制到升级后的数据库中即可。
要编辑报告的 XML,请点击左窗格中的 编辑来源。
示例¶
Sometimes, tables are not properly recognized as such due to complex structures. In those cases, you can still modify them manually in the report XML. For example, with a sales order, you can find the following structure in the XML (simplified for documentation purposes):
<!-- table root element --> <table> <!-- thead = table header, the row with column titles --> <thead> <!-- table row element --> <tr> <!-- table header element --> <th>Name</th> <th>Price</th> </tr> </thead> <!-- table body, the main content --> <tbody> <!-- we create a row for each subrecord with t-foreach --> <tr t-foreach="record.some_relation_ids" t-as="line"> <!-- for each line, we output the name and price as table cells --> <td t-out="line.name"/> <td t-out="line.price"/> </tr> </tbody> </table>To modify a table, you must ensure that each row has the same number of data cells. For example, in the case above, you need to add a cell in the header section (with e.g., the column title) and another one in the body section with the field content (usually, with a
t-outort-fielddirective).<table> <!-- table root element --> <thead> <!-- thead = table header, the row with column titles --> <tr> <!-- table row element --> <th>Name</th> <!-- table header element --> <th>Price</th> <th>Category</th> </tr> </thead> <tbody> <!-- table body, the main content --> <tr t-foreach="record.some_relation_ids" t-as="line"> <!-- we create a row for each subrecord with t-foreach --> <td t-out="line.name"/> <!-- for each line, we output the name and price as table cells --> <td t-out="line.price"/> <td t-out="line.category_id.display_name"/> </tr> </tbody> </table>注解
Cells can span multiple rows or columns. For more information, go to the Mozilla Developer Network website.
For example, you can modify the Quotation/Order report to add a column to display the product category in the main table:
<table class="table table-sm o_main_table table-borderless mt-4"> <!-- In case we want to repeat the header, remove "display: table-row-group" --> <thead style="display: table-row-group"> <tr> <th name="th_description" class="text-start">Description</th> <th>Product Category</th> <th name="th_quantity" class="text-end">Quantity</th> <th name="th_priceunit" class="text-end">Unit Price</th> [...] <tr t-att-class="'bg-200 fw-bold o_line_section' if line.display_type == 'line_section' else 'fst-italic o_line_note' if line.display_type == 'line_note' else ''"> <t t-if="not line.display_type"> <td name="td_name"><span t-field="line.name">Bacon Burger</span></td> <td t-out="line.product_id.categ_id.display_name"/> <td name="td_quantity" class="text-end"> <span t-field="line.product_uom_qty">3</span> <span t-field="line.product_uom">units</span> <span t-if="line.product_packaging_id">![]()
To add a table in XML, you need to know the names of the fields and objects you wish to access and display. As an example, let’s add a table that details the tags on a sales order:
<!-- table root element -->
<table class="table">
<!-- thead = table header, the row with column titles -->
<thead>
<!-- table row element -->
<tr>
<!-- table header element -->
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<!-- table body, the main content -->
<tbody>
<!-- we create a row for each subrecord with t-foreach -->
<tr t-foreach="doc.tag_ids" t-as="tag">
<!-- for each line, we output the name and price as table cells -->
<td t-out="tag.id"/>
<td t-out="tag.name"/>
</tr>
</tbody>
</table>
注解
When adding tables manually, style them using Bootstrap classes, like the table class included in the
example above.
如果要根据特定条件显示/隐藏内容,可以在报告 XML 中手动添加 if/else 控制语句。
例如,如果要在没有标记的情况下隐藏自定义数据表,可以使用 t-if 属性定义条件,然后将其评估为 True 或 False。如果引号中没有标记,则不会显示表格。
<!-- table root element -->
<table class="table" t-if="len(doc.tag_ids) > 0">
<!-- thead = table header, the row with column titles -->
<thead>
<!-- table row element -->
<tr>
<!-- table header element -->
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<!-- table body, the main content -->
<tbody>
<!-- we create a row for each subrecord with t-foreach -->
<tr t-foreach="doc.tag_ids" t-as="tag">
<!-- for each line, we output the name and price as table cells -->
<td t-out="tag.id"/>
<td t-out="tag.name"/>
</tr>
</tbody>
</table>
如果想在 t-if 语句被评估为 False 时显示另一个块,可以使用 t-else 语句指定。在文档结构中,t-else`块必须直接跟在`t-if`块之后。无需在 `t-else 属性中指定任何条件。例如,让我们快速显示一条信息,说明引号上没有标记:
<!-- table root element -->
<table class="table" t-if="len(doc.tag_ids) > 0">
<!-- thead = table header, the row with column titles -->
<thead>
<!-- table row element -->
<tr>
<!-- table header element -->
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<!-- table body, the main content -->
<tbody>
<!-- we create a row for each subrecord with t-foreach -->
<tr t-foreach="doc.tag_ids" t-as="tag">
<!-- for each line, we output the name and price as table cells -->
<td t-out="tag.id"/>
<td t-out="tag.name"/>
</tr>
</tbody>
</table>
<div class="text-muted" t-else="">No tag present on this document.</div>
通过使用 `t-if/t-else`符号,报告编辑器可识别这些部分是互斥的,并应作为条件块显示:
您可以使用编辑器切换条件,预览它们的输出结果:
如果希望有多个选项,也可以使用 t-elif 指令添加中间条件。例如,销售订单报告的标题就是这样根据基础文档的条件而变化的。
<h2 class="mt-4">
<span t-if="env.context.get('proforma', False) or is_pro_forma">Pro-Forma Invoice # </span>
<span t-elif="doc.state in ['draft','sent']">Quotation # </span>
<span t-else="">Order # </span>
<span t-field="doc.name">SO0000</span>
</h2>
The title Pro-Forma Invoice is used depending on some contextual conditions. If these
conditions are not met and the state of the document is either draft or sent, then
Quotation is used. If none of those conditions are met, the report’s title is Order.
Working with images in a report can be challenging, as precise control over image size and
behavior is not always obvious. You can insert image fields using the report editor
(by using the /Field command), but inserting them in XML
using the t-field directive and accompanying t-options attributes provides better sizing and
positioning control.
例如,以下代码会将该行产品的字段 `image_128`输出为 64px 宽的图片(根据图片的宽高比自动调整高度)。
<span t-field="line.product_id.image_128" t-options-widget="image" t-options-width="64px"/>
图像部件有以下选项:
宽度:图像的宽度,通常以像素或CSS长度单位(如`rem`)表示(留空则为自动宽度)。height:图像的高度,通常以像素或CSS长度单位(如`rem`)表示(留空则为自动高度)。class:应用于`img` 标签的CSS类;可使用`Bootstrap类 <https://getbootstrap.com/docs/5.1/content/tables>`_。alt:图像的替代文本。style:样式属性;与`Bootstrap 类 <https://getbootstrap.com/docs/5.1/content/tables>`_ 相比,它允许您更自由地覆写样式。
这些属性必须包含字符串,即引号内再嵌套引号的文本,例如`t-options-width=“‘64px’”` (或者,也可以是一个有效的Python表达式)。
注解
图像控件不能用于`img`标签。而应在`span` (用于内联内容)或`div` (用于块级内容)节点上设置`t-field`指令。
例如,让我们在报价单表格中添加一个包含产品图片的列:
<table class="table table-sm o_main_table table-borderless mt-4">
<thead style="display: table-row-group">
<tr>
<th>Image</th>
<th name="th_description" class="text-start">Description</th>
<th>Product Category</th>
<th name="th_quantity" class="text-end">Quantity</th>
<th name="th_priceunit" class="text-end">Unit Price</th>
[...]
<t t-foreach="lines_to_report" t-as="line">
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal"/>
<tr t-att-class="'bg-200 fw-bold o_line_section' if line.display_type == 'line_section' else 'fst-italic o_line_note' if line.display_type == 'line_note' else ''">
<t t-if="not line.display_type">
<td>
<span t-field="line.product_template_id.image_128"
t-options-widget="'image'"
t-options-width="'64px'"
t-options-class="'rounded-3 shadow img-thumbnail'"
/>
</td>
<td name="td_name"><span t-field="line.name">Bacon Burger</span></td>
<td t-out="line.product_id.categ_id.display_name"/>
`t-options-width`属性将图片宽度限制为64像素,而`t-options-class`中使用的Bootstrap类则创建了一个带有圆角和阴影的缩略图样式边框。