Compare commits

...

2 Commits

Author SHA1 Message Date
zzs
de95153976 feat: replace bookmark with image 2025-03-28 11:54:53 +08:00
zzs
88db5957d2 feat: change find position in table api 2025-03-28 09:50:42 +08:00

View File

@ -1,5 +1,12 @@
import json
import base64
import io
from com.sun.star.beans import PropertyValue
import tempfile
import os
from com.sun.star.beans import PropertyValue
from uno import ByteSequence, systemPathToFileUrl
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER, AT_PARAGRAPH
def Replace(bookmark_name_value_map):
"""
@ -305,8 +312,8 @@ def BatchInsertRow(data_array):
if not data or len(data) == 0:
return
if any(len(row) != col_count for row in data):
raise ValueError(f"数据列数不匹配,表格有 {col_count}")
# if any(len(row) != col_count for row in data):
# raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
try:
row_count = handle_table.getRows().getCount()
@ -516,12 +523,15 @@ def ReplaceTextAndInsertTableRow(json_str):
data = json.loads(json_str)
Replace(data["text"])
BatchInsertRow(data["table"])
ReplaceBookmarkWithImage(data["image"])
def ReplaceTextAndInsertTableRowWithContentControl(json_str):
data = json.loads(json_str)
# BatchInsertRowWithContentControl(data["table"])
ReplaceBookmarksWithControls(data["text"])
Replace(data["text"])
ReplaceBookmarkWithImage(data["image"])
BatchInsertRowWithContentControl(data["table"])
ReplaceBookmarksWithControls({}, ExtractBookmarkNames(data))
def returnWithJSON(data):
@ -545,8 +555,7 @@ def SaveDocument():
print("err:", e)
return False
def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
def ReplaceBookmarksWithControls(bookmark_name_value_map={}, exclude_bookmark_names=[]):
# 获取文档对象
doc = XSCRIPTCONTEXT.getDocument()
bookmarks = doc.getBookmarks()
@ -557,6 +566,9 @@ def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
# 遍历所有需要处理的书签
for name in bookmark_names:
try:
# 检查是否需要排除
if name in exclude_bookmark_names:
continue
# 检查书签是否存在
if not bookmarks.hasByName(name):
continue
@ -656,6 +668,133 @@ def NextEditableZone(current_index):
except Exception as e:
raise RuntimeError(f"err: {str(e)}") from e
def ReplaceBookmarkWithImage(data_array):
"""
替换书签为图片同时保留书签
参数:
data_array: 包含书签和图片信息的字典数组
"""
# 获取当前文档和相关服务
doc = XSCRIPTCONTEXT.getDocument()
bookmarks = doc.getBookmarks()
smgr = XSCRIPTCONTEXT.getComponentContext().getServiceManager()
graphic_provider = smgr.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", XSCRIPTCONTEXT.getComponentContext())
if not graphic_provider:
raise RuntimeError("无法初始化 GraphicProvider 服务")
for data in data_array:
bookmark_name = data["bookmarkName"]
image_data = data["imageData"]
width = data["width"]
height = data["height"]
file_type = data["fileType"]
# 检查书签是否存在
if bookmark_name not in bookmarks:
print(f"错误: 书签 '{bookmark_name}' 不存在")
continue
try:
# 解码 Base64 数据
image_bytes = base64.b64decode(image_data)
if not image_bytes:
raise ValueError("Base64 数据为空或无效")
# 获取书签的文本范围和光标
bookmark = bookmarks[bookmark_name]
text_range = bookmark.getAnchor()
text_cursor = text_range.getText().createTextCursorByRange(text_range)
# 记录书签位置并删除书签内容
text = text_range.getText()
text_cursor.setString("") # 删除书签范围内的文本
# 使用临时文件方式插入图片
temp_file_path = None
try:
with tempfile.NamedTemporaryFile(delete=False, suffix=f".{file_type}") as temp_file:
temp_file.write(image_bytes)
temp_file_path = temp_file.name
file_url = systemPathToFileUrl(temp_file_path)
url_prop = PropertyValue()
url_prop.Name = "URL"
url_prop.Value = file_url
graphic_properties = (url_prop,)
graphic = graphic_provider.queryGraphic(graphic_properties)
if not graphic:
raise RuntimeError(f"无法为书签 '{bookmark_name}' 生成图形对象")
# 创建图形对象
graphic_object = doc.createInstance("com.sun.star.text.TextGraphicObject")
graphic_object.Graphic = graphic
graphic_object.Width = width
graphic_object.Height = height
# 设置锚定方式
graphic_object.AnchorType = AS_CHARACTER # 锚定为字符
# 插入图片
text.insertTextContent(text_cursor, graphic_object, False)
if bookmark_name not in doc.getBookmarks():
# 重新创建书签以覆盖图片位置
bookmark_range = text.createTextCursorByRange(text_range)
new_bookmark = doc.createInstance("com.sun.star.text.Bookmark")
new_bookmark.Name = bookmark_name
text.insertTextContent(bookmark_range, new_bookmark, False)
finally:
# 清理临时文件
if temp_file_path and os.path.exists(temp_file_path):
os.unlink(temp_file_path)
except Exception as e:
continue
def ExtractBookmarkNames(data):
"""
data["image"] 数组中提取所有 bookmarkName组成一个字符串数组
参数:
data: 包含 "image" 键的字典其值为图片对象数组
返回:
list: 包含所有 bookmarkName 的字符串数组
"""
if "image" not in data or not isinstance(data["image"], list):
return []
# 使用列表推导式提取 bookmarkName
bookmark_names = [item["bookmarkName"] for item in data["image"] if "bookmarkName" in item]
return bookmark_names
def GetBookmarksInLists():
"""
返回文档中所有位于列表中的书签
Returns:
list: 位于列表中的书签名称列表
"""
doc = XSCRIPTCONTEXT.getDocument()
bookmarks = doc.getBookmarks()
bookmarks_in_lists = []
# 遍历所有书签
for bookmark in bookmarks:
bookmark_name = bookmark.getName()
anchor = bookmark.getAnchor()
# 判断书签的锚点是否在列表中
if anchor.supportsService("com.sun.star.text.Paragraph"):
paragraph = anchor
if paragraph.getPropertySetInfo().hasPropertyByName("NumberingStyleName"):
numbering_style = paragraph.getPropertyValue("NumberingStyleName")
if numbering_style:
bookmarks_in_lists.append(bookmark_name)
return bookmarks_in_lists
g_exportedScripts = (
Replace,
@ -671,4 +810,5 @@ g_exportedScripts = (
ReplaceTextAndInsertTableRowWithContentControl,
SaveDocument,
NextEditableZone,
GetBookmarksInLists,
)