Sfoglia il codice sorgente

feat(export): 增强图片块渲染支持样式映射和对齐方式

- 为 _render_image_block 函数添加 style_map 参数,支持 Word 样式映射
- 实现图片段落的 Word 样式应用,包括样式ID解析和样式名称兼容
- 完善对齐方式处理,显式支持左对齐、居中和右对齐三种模式
- 添加样式应用的错误处理和降级逻辑,确保样式不可用时默认使用 Normal 样式
- 在调用 _render_image_block 时传入 style_map 参数,保持与其他渲染函数的一致性
- 提高图片块渲染的样式一致性和用户体验
chensiyu 1 mese fa
parent
commit
67ef39500e
1 ha cambiato i file con 33 aggiunte e 4 eliminazioni
  1. 33 4
      app/services/export_service.py

+ 33 - 4
app/services/export_service.py

@@ -464,7 +464,7 @@ def blocks_to_docx_bytes(blocks: list[dict], style_map: dict, style_data: dict)
464 464
         elif block_type == 'table':
465 465
             _render_table_block(doc, block, style_map)
466 466
         elif block_type == 'image':
467
-            _render_image_block(doc, block)
467
+            _render_image_block(doc, block, style_map)
468 468
     
469 469
     # 先保存到临时缓冲区
470 470
     buf = io.BytesIO()
@@ -1087,10 +1087,11 @@ def _render_table_block(doc: Document, block: dict, style_map: dict):
1087 1087
                 _apply_run_style(run, cell_style)
1088 1088
 
1089 1089
 
1090
-def _render_image_block(doc: Document, block: dict):
1091
-    """渲染图片块(支持 Base64 Data URL)"""
1090
+def _render_image_block(doc: Document, block: dict, style_map: dict = None):
1091
+    """渲染图片块(支持 Base64 Data URL 和 Word 样式)"""
1092 1092
     content = block['content']
1093 1093
     style = block.get('style', {})
1094
+    word_style = block.get('word_style', 'Normal')
1094 1095
     
1095 1096
     # 只处理 Data URL
1096 1097
     if not isinstance(content, str) or not content.startswith('data:'):
@@ -1104,14 +1105,42 @@ def _render_image_block(doc: Document, block: dict):
1104 1105
         header, b64_data = content.split(',', 1)
1105 1106
         image_bytes = base64.b64decode(b64_data)
1106 1107
         
1107
-        # 创建段落并设置对齐
1108
+        # 创建段落并应用 Word 样式
1108 1109
         paragraph = doc.add_paragraph()
1109 1110
         
1111
+        # 应用 Word 样式(如"图表标题")
1112
+        if style_map:
1113
+            style_id = _resolve_style_id(style_map, word_style, 'Normal')
1114
+            if style_id:
1115
+                try:
1116
+                    paragraph.style = doc.styles[style_id]
1117
+                except KeyError:
1118
+                    # 如果找不到样式ID,尝试使用样式名称
1119
+                    try:
1120
+                        paragraph.style = word_style
1121
+                    except KeyError:
1122
+                        paragraph.style = 'Normal'
1123
+            else:
1124
+                # 如果没有找到映射,尝试直接使用 word_style
1125
+                try:
1126
+                    paragraph.style = word_style
1127
+                except KeyError:
1128
+                    paragraph.style = 'Normal'
1129
+        else:
1130
+            # 没有 style_map,尝试直接使用 word_style
1131
+            try:
1132
+                paragraph.style = word_style
1133
+            except KeyError:
1134
+                paragraph.style = 'Normal'
1135
+        
1136
+        # 设置对齐方式(可能覆盖样式中的对齐)
1110 1137
         align = style.get('align', 'left')
1111 1138
         if align == 'center':
1112 1139
             paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
1113 1140
         elif align == 'right':
1114 1141
             paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT
1142
+        elif align == 'left':
1143
+            paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
1115 1144
         
1116 1145
         # 插入图片
1117 1146
         run = paragraph.add_run()