模板在线编辑与导出链路重构

This commit is contained in:
zwt13703
2026-07-05 23:35:00 +08:00
parent 1369d87afb
commit c84ec6aa71
15 changed files with 1434 additions and 166 deletions
+73
View File
@@ -69,6 +69,77 @@ def _remove_unreferenced_headings(document: DocumentObject, referenced_anchors:
_delete_block(block)
def _ordered_unique_anchors(logs: list[dict]) -> list[str]:
ordered: list[str] = []
seen: set[str] = set()
for item in logs:
anchor = (item.get("anchor_title") or item.get("title") or "").strip()
if not anchor or anchor in seen:
continue
seen.add(anchor)
ordered.append(anchor)
return ordered
def _reorder_heading_sections(document: DocumentObject, ordered_anchors: list[str]):
body = document.element.body
elements = list(body.iterchildren())
pre_heading: list = []
sections: list[tuple[str, list]] = []
found_heading = False
index = 0
while index < len(elements):
child = elements[index]
if isinstance(child, CT_P):
paragraph = Paragraph(child, document)
if _is_heading(paragraph):
found_heading = True
anchor = paragraph.text.strip()
section_elements = [child]
index += 1
while index < len(elements):
current = elements[index]
if isinstance(current, CT_P):
current_paragraph = Paragraph(current, document)
if _is_heading(current_paragraph):
break
section_elements.append(current)
index += 1
sections.append((anchor, section_elements))
continue
if not found_heading:
pre_heading.append(child)
index += 1
if not sections:
return
section_map: dict[str, list[list]] = {}
for anchor, section_elements in sections:
section_map.setdefault(anchor, []).append(section_elements)
all_section_elements = [element for _, section_elements in sections for element in section_elements]
for element in all_section_elements:
parent = element.getparent()
if parent is not None:
parent.remove(element)
sect_pr = None
for child in list(body.iterchildren()):
if not isinstance(child, (CT_P, CT_Tbl)):
sect_pr = child
break
for anchor in ordered_anchors:
for section_elements in section_map.pop(anchor, []):
for element in section_elements:
if sect_pr is not None:
sect_pr.addprevious(element)
else:
body.append(element)
def _clear_paragraph(paragraph: Paragraph):
element = paragraph._element
for child in list(element):
@@ -369,6 +440,8 @@ def _replace_section_group(
def export_document_bytes(template_bytes: bytes, logs: list[dict]) -> bytes:
document = Document(BytesIO(template_bytes))
ordered_anchors = _ordered_unique_anchors(logs)
_reorder_heading_sections(document, ordered_anchors)
referenced_anchors: set[str] = set()
for item in logs: