如何在 Odoo 中使用 Wkhtmltopdf 打印尺寸准确的 div?
How to print divs with an accurate size using Wkhtmltopdf in Odoo?
我正在尝试在 Odoo 10 中创建新的产品标签 Qweb 报告。
报告的纸张格式必须是无边距的 A4。每个标签的宽度必须为 70 毫米,高度为 42.4 毫米。这意味着每行将有三个标签,每页将有七行(A4 = 210mm x 297mm。所以 70mm x 3 = 210mm,42.4mm x 7 = 297mm)。我以这种方式创建了 paperformat:
<record id="paperformat_euro_no_margin" model="report.paperformat">
<field name="name">European A4 (no margins)</field>
<field name="default" eval="True" />
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">90</field>
</record>
我为我的自定义报告分配了纸张格式,我检查它工作正常:
<report
id="report_product_template_labels_custom"
string="Custom Products Labels"
model="product.template"
report_type="qweb-pdf"
name="my_module.report_producttemplatelabel_custom"
file="my_module.report_producttemplatelabel_custom"/>
<record id="report_product_template_labels_custom" model="ir.actions.report.xml">
<field name="paperformat_id" ref="paperformat_euro_no_margin"/>
</record>
然而,看到 Odoo 如何忽略值为 0 的 margin_left
和 margin_right
属性令人恼火(我认为它已被 Odoo S.A 报告和修复)。我必须将 margin-left:-5mm;
和 margin-right:-5mm;
样式应用于报告页面,以避免默认值覆盖我的值。 有没有更简洁的方法来解决这个问题?
但我的主要问题来了。这是我的报告代码:
<template id="report_producttemplatelabel_custom">
<t t-call="report.html_container">
<div class="page" style="margin-left:-5mm !important; margin-right:-5mm !important;">
<t t-foreach="docs" t-as="template">
<t t-foreach="template.product_variant_ids" t-as="product">
<t t-call="my_module.report_simple_label_custom">
<t t-set="product" t-value="product"/>
</t>
</t>
</t>
</div>
</t>
</template>
如您所见,对于产品的每个变体,我都展示了一个自定义的 Qweb 模板 (report_simple_label_custom
)。其代码如下:
<template id="report_simple_label_custom">
<div style="position: relative; display: block; width:70mm; height:42.4mm; float:left; margin:0; padding:0;">
<div style="width:100%; height:100%; border: 1px solid white; background: green;"></div>
</div>
</template>
代码非常简单。如果产品有 21 个变体,我应该会看到 21 个绿色 div,每行 3 个,非常适合 A4。但是,当我打印报告时,它们根本不适合。每个div
的高度似乎都比42.4mm少了很多。我试过修改 paperformat dpi
但我找不到一个值使 CSS 毫米与 PDF 毫米相同。
在尝试了很多事情之后,我决定忽略毫米并使用百分比,以使标签非常适合 PDF 大小。
- Div 宽度 = 100 / 3 ~ 33.2%
- Div 身高 = 100 / 7 ~ 14.28%
修改后,当我在 HTML 中打印报告时,一切看起来都很好,但是当我以 PDF 格式打印时,宽度可以但高度不行(div 重叠) .这是因为我猜有些父元素的高度不同于 100%。我将此高度应用于 page
div,但问题仍然存在。
那么,谁能告诉我如何解决这个问题?我只想要一个A4填满相同大小的矩形,每行三个,每列七个(如果少于21个变体,左边的space必须是空白)
我终于找到了解决整个问题的好方法。
避免在 PDF 的左右尺寸上看到烦人的边距的解决方案
Wkhtmltopdf 在这种情况下没有罪。当我以 HTML 格式打印报告时,我意识到它的两页边距也有 space。事实上它是一个填充,由于 .container
class。所以解决方案是覆盖我报告中的 class 属性,这样:
<template id="report_simple_label_custom">
<style type="text/css">
.container {
padding: 0 !important;
}
</style>
<div style="position: relative; display: block; width:70mm; height:42.4mm; float:left; margin:0; padding:0;">
<div style="width:100%; height:100%; border: 1px solid white; background: green;"></div>
</div>
</template>
将HTML大小精确转换为PDF大小的解决方案
当Odoo执行wkhtmltopdf
将HTML代码转换为PDF时,它没有使用选项--disable-smart-shrinking
。如果我们直接(在 Odoo 之外)执行 wkhtmltopdf
将任何 HTML 代码转换为 PDF,我们可以传递该参数以获得准确的结果。所以问题是:如何让 Odoo 在转换我们的报告时通过该参数?简单的答案是从 repo reporting-engine
安装官方 OCA 模块。它的名字是report_wkhtmltopdf_param
。它允许您告诉 Odoo 在打印特定纸张格式时将附加参数传递给 wkhtmltopdf
。
所以我必须添加这段代码来将参数传递给我的 paperformat 报告,当然,还要让我的模块依赖于 report_wkhtmltopdf_param
app:
<record id="paperformat_euro_no_margin" model="report.paperformat">
<field name="name">European A4 (no margins)</field>
<field name="default" eval="True" />
<field name="format">custom</field>
<field name="page_height">297</field>
<field name="page_width">210</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">96</field>
</record>
<record id="paperformat_euro_no_margin_disable_smart_shrinking" model="report.paperformat.parameter">
<field name="paperformat_id" ref="my_module.paperformat_euro_no_margin"/>
<field name="name">--disable-smart-shrinking</field>
</record>
注意:paperformat 的 dpi
必须为 96 才能获得最佳和更准确的结果。
我正在尝试在 Odoo 10 中创建新的产品标签 Qweb 报告。
报告的纸张格式必须是无边距的 A4。每个标签的宽度必须为 70 毫米,高度为 42.4 毫米。这意味着每行将有三个标签,每页将有七行(A4 = 210mm x 297mm。所以 70mm x 3 = 210mm,42.4mm x 7 = 297mm)。我以这种方式创建了 paperformat:
<record id="paperformat_euro_no_margin" model="report.paperformat">
<field name="name">European A4 (no margins)</field>
<field name="default" eval="True" />
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">90</field>
</record>
我为我的自定义报告分配了纸张格式,我检查它工作正常:
<report
id="report_product_template_labels_custom"
string="Custom Products Labels"
model="product.template"
report_type="qweb-pdf"
name="my_module.report_producttemplatelabel_custom"
file="my_module.report_producttemplatelabel_custom"/>
<record id="report_product_template_labels_custom" model="ir.actions.report.xml">
<field name="paperformat_id" ref="paperformat_euro_no_margin"/>
</record>
然而,看到 Odoo 如何忽略值为 0 的 margin_left
和 margin_right
属性令人恼火(我认为它已被 Odoo S.A 报告和修复)。我必须将 margin-left:-5mm;
和 margin-right:-5mm;
样式应用于报告页面,以避免默认值覆盖我的值。 有没有更简洁的方法来解决这个问题?
但我的主要问题来了。这是我的报告代码:
<template id="report_producttemplatelabel_custom">
<t t-call="report.html_container">
<div class="page" style="margin-left:-5mm !important; margin-right:-5mm !important;">
<t t-foreach="docs" t-as="template">
<t t-foreach="template.product_variant_ids" t-as="product">
<t t-call="my_module.report_simple_label_custom">
<t t-set="product" t-value="product"/>
</t>
</t>
</t>
</div>
</t>
</template>
如您所见,对于产品的每个变体,我都展示了一个自定义的 Qweb 模板 (report_simple_label_custom
)。其代码如下:
<template id="report_simple_label_custom">
<div style="position: relative; display: block; width:70mm; height:42.4mm; float:left; margin:0; padding:0;">
<div style="width:100%; height:100%; border: 1px solid white; background: green;"></div>
</div>
</template>
代码非常简单。如果产品有 21 个变体,我应该会看到 21 个绿色 div,每行 3 个,非常适合 A4。但是,当我打印报告时,它们根本不适合。每个div
的高度似乎都比42.4mm少了很多。我试过修改 paperformat dpi
但我找不到一个值使 CSS 毫米与 PDF 毫米相同。
在尝试了很多事情之后,我决定忽略毫米并使用百分比,以使标签非常适合 PDF 大小。
- Div 宽度 = 100 / 3 ~ 33.2%
- Div 身高 = 100 / 7 ~ 14.28%
修改后,当我在 HTML 中打印报告时,一切看起来都很好,但是当我以 PDF 格式打印时,宽度可以但高度不行(div 重叠) .这是因为我猜有些父元素的高度不同于 100%。我将此高度应用于 page
div,但问题仍然存在。
那么,谁能告诉我如何解决这个问题?我只想要一个A4填满相同大小的矩形,每行三个,每列七个(如果少于21个变体,左边的space必须是空白)
我终于找到了解决整个问题的好方法。
避免在 PDF 的左右尺寸上看到烦人的边距的解决方案
Wkhtmltopdf 在这种情况下没有罪。当我以 HTML 格式打印报告时,我意识到它的两页边距也有 space。事实上它是一个填充,由于 .container
class。所以解决方案是覆盖我报告中的 class 属性,这样:
<template id="report_simple_label_custom">
<style type="text/css">
.container {
padding: 0 !important;
}
</style>
<div style="position: relative; display: block; width:70mm; height:42.4mm; float:left; margin:0; padding:0;">
<div style="width:100%; height:100%; border: 1px solid white; background: green;"></div>
</div>
</template>
将HTML大小精确转换为PDF大小的解决方案
当Odoo执行wkhtmltopdf
将HTML代码转换为PDF时,它没有使用选项--disable-smart-shrinking
。如果我们直接(在 Odoo 之外)执行 wkhtmltopdf
将任何 HTML 代码转换为 PDF,我们可以传递该参数以获得准确的结果。所以问题是:如何让 Odoo 在转换我们的报告时通过该参数?简单的答案是从 repo reporting-engine
安装官方 OCA 模块。它的名字是report_wkhtmltopdf_param
。它允许您告诉 Odoo 在打印特定纸张格式时将附加参数传递给 wkhtmltopdf
。
所以我必须添加这段代码来将参数传递给我的 paperformat 报告,当然,还要让我的模块依赖于 report_wkhtmltopdf_param
app:
<record id="paperformat_euro_no_margin" model="report.paperformat">
<field name="name">European A4 (no margins)</field>
<field name="default" eval="True" />
<field name="format">custom</field>
<field name="page_height">297</field>
<field name="page_width">210</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">96</field>
</record>
<record id="paperformat_euro_no_margin_disable_smart_shrinking" model="report.paperformat.parameter">
<field name="paperformat_id" ref="my_module.paperformat_euro_no_margin"/>
<field name="name">--disable-smart-shrinking</field>
</record>
注意:paperformat 的 dpi
必须为 96 才能获得最佳和更准确的结果。