Toggle navigation
Toggle navigation
This project
Loading...
Sign in
万朱浩
/
Venue-Ops
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
马一丁
2025-12-11 18:30:19 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
2be0b2af694ae59b41208efc9f6b7b5c89d83435
2be0b2af
1 parent
9ad6b1ef
Improve SWOT pagination effect
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
26 deletions
ReportEngine/renderers/html_renderer.py
ReportEngine/renderers/pdf_renderer.py
ReportEngine/renderers/html_renderer.py
View file @
2be0b2a
...
...
@@ -1178,6 +1178,11 @@ class HTMLRenderer:
def
_render_swot_table
(
self
,
block
:
Dict
[
str
,
Any
])
->
str
:
"""
渲染四象限的SWOT专用表格,兼顾HTML与PDF的可读性。
PDF分页策略:
- 每个S/W/O/T象限内部禁止分页(break-inside: avoid)
- 允许在象限之间分页
- 卡片标题与第一个象限尽量保持在一起
"""
title
=
block
.
get
(
"title"
)
or
"SWOT 分析"
summary
=
block
.
get
(
"summary"
)
...
...
@@ -1188,12 +1193,14 @@ class HTMLRenderer:
(
"threats"
,
"威胁 Threats"
,
"T"
,
"threat"
),
]
cells_html
=
""
for
key
,
label
,
code
,
css
in
quadrants
:
for
idx
,
(
key
,
label
,
code
,
css
)
in
enumerate
(
quadrants
)
:
items
=
self
.
_normalize_swot_items
(
block
.
get
(
key
))
caption_text
=
f
"{len(items)} 条要点"
if
items
else
"待补充"
list_html
=
""
.
join
(
self
.
_render_swot_item
(
item
)
for
item
in
items
)
if
items
else
'<li class="swot-empty">尚未填入要点</li>'
# 第一个象限添加特殊类以便与标题保持在一起
first_cell_class
=
" swot-cell--first"
if
idx
==
0
else
""
cells_html
+=
f
"""
<div class="swot-cell
{css
}">
<div class="swot-cell
swot-cell--pageable {css}{first_cell_class}" data-swot-key="{key
}">
<div class="swot-cell__meta">
<span class="swot-pill {css}">{self._escape_html(code)}</span>
<div>
...
...
@@ -3208,20 +3215,61 @@ table th {{
color: var(--swot-muted);
opacity: 0.7;
}}
/* PDF/导出时的SWOT专用布局,避免圆角框重叠 */
/* PDF/导出时的SWOT专用布局,
支持分页且
避免圆角框重叠 */
body.exporting .swot-legend {{
display: none !important;
}}
body.exporting .swot-grid {{
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: stretch;
flex-direction: column;
gap: 16px;
}}
body.exporting .swot-cell {{
flex: 1 1 320px;
min-width: 240px;
width: 100
%
;
height: auto;
page-break-inside: avoid;
break-inside: avoid;
}}
body.exporting .swot-cell--first {{
page-break-before: avoid;
break-before: avoid;
}}
/* 打印模式下的SWOT分页控制 */
@media print {{
.swot-card {{
break-inside: auto;
page-break-inside: auto;
}}
.swot-card__head {{
break-after: avoid;
page-break-after: avoid;
}}
.swot-grid {{
display: flex;
flex-direction: column;
gap: 16px;
}}
.swot-cell {{
break-inside: avoid;
page-break-inside: avoid;
width: 100
%
;
}}
.swot-cell--first {{
break-before: avoid;
page-break-before: avoid;
}}
.swot-cell__meta {{
break-after: avoid;
page-break-after: avoid;
}}
.swot-list {{
break-inside: avoid;
page-break-inside: avoid;
}}
.swot-item {{
break-inside: avoid;
page-break-inside: avoid;
}}
}}
.callout {{
border-left: 4px solid var(--primary-color);
...
...
ReportEngine/renderers/pdf_renderer.py
View file @
2be0b2a
...
...
@@ -1049,35 +1049,78 @@ body {{
min-height: 400px;
}}
/* SWOT:PDF导出隐藏四象限标注,并使用自适应布局避免重叠 */
/* ========== SWOT PDF分页优化 ========== */
/* 核心策略:S/W/O/T四个象限各自内部禁止分页,但允许象限之间分页 */
/* 隐藏四象限标注图例 */
.swot-legend {{
display: none !important;
}}
/* SWOT卡片容器:允许内部分页 */
.swot-card {{
/* 允许卡片内容在必要时分页,避免整体被抬到下一页 */
break-inside: auto !important;
page-break-inside: auto !important;
margin: 20px 0;
}}
/* 卡片头部(标题+摘要):避免紧跟其后分页,尽量与第一个象限保持在一起 */
.swot-card__head {{
break-after: avoid;
page-break-after: avoid;
break-after: avoid !important;
page-break-after: avoid !important;
break-inside: avoid !important;
page-break-inside: avoid !important;
}}
/* 网格容器:PDF模式下使用纵向flex布局,允许子元素间分页 */
.swot-grid {{
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: stretch;
break-before: avoid;
page-break-before: avoid;
break-inside: auto;
page-break-inside: auto;
display: flex !important;
flex-direction: column !important;
gap: 16px !important;
break-inside: auto !important;
page-break-inside: auto !important;
}}
.swot-grid .swot-cell {{
flex: 1 1 320px;
min-width: 240px;
height: auto;
page-break-inside: avoid;
break-inside: avoid;
/* 每个SWOT象限单元格:禁止内部分页,允许前后分页 */
.swot-cell {{
break-inside: avoid !important;
page-break-inside: avoid !important;
break-before: auto;
page-break-before: auto;
break-after: auto;
page-break-after: auto;
width: 100
%
!important;
max-width: 100
%
!important;
flex: none !important;
min-height: auto !important;
height: auto !important;
box-sizing: border-box;
}}
/* 第一个象限:避免在标题后立即分页 */
.swot-cell--first {{
break-before: avoid !important;
page-break-before: avoid !important;
}}
/* 象限内的meta区域(图标+标题):避免被分页切开 */
.swot-cell__meta {{
break-inside: avoid !important;
page-break-inside: avoid !important;
break-after: avoid !important;
page-break-after: avoid !important;
}}
/* 条目列表:允许列表整体分页 */
.swot-list {{
break-inside: avoid !important;
page-break-inside: avoid !important;
}}
/* 单个条目:避免被分页切开 */
.swot-item {{
break-inside: avoid !important;
page-break-inside: avoid !important;
}}
{optimized_css}
...
...
Please
register
or
login
to post a comment