feat: replace with control
This commit is contained in:
parent
ca9bb2771c
commit
b835ed6cb3
265
BookmarkOP.py
265
BookmarkOP.py
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def Replace(bookmark_name_value_map):
|
def Replace(bookmark_name_value_map):
|
||||||
"""
|
"""
|
||||||
替换所有书签
|
替换所有书签
|
||||||
@ -16,6 +17,21 @@ def Replace(bookmark_name_value_map):
|
|||||||
anchor.setString(new_value)
|
anchor.setString(new_value)
|
||||||
|
|
||||||
|
|
||||||
|
def ReplaceOne(bookmark_obj_collection, bookmark_name, new_value):
|
||||||
|
"""
|
||||||
|
替换一个书签
|
||||||
|
Args:
|
||||||
|
bookmark_obj_collection: 书签对象集合
|
||||||
|
bookmark_name: 书签名称
|
||||||
|
new_value: 新值
|
||||||
|
"""
|
||||||
|
|
||||||
|
if bookmark_obj_collection.hasByName(bookmark_name):
|
||||||
|
bookmark = bookmark_obj_collection.getByName(bookmark_name)
|
||||||
|
anchor = bookmark.getAnchor()
|
||||||
|
anchor.setString(new_value)
|
||||||
|
|
||||||
|
|
||||||
def ReplaceWithJSON(json_str):
|
def ReplaceWithJSON(json_str):
|
||||||
"""
|
"""
|
||||||
替换所有书签
|
替换所有书签
|
||||||
@ -27,22 +43,6 @@ def ReplaceWithJSON(json_str):
|
|||||||
Replace(bookmark_name_value_map)
|
Replace(bookmark_name_value_map)
|
||||||
|
|
||||||
|
|
||||||
def DebugCallReplace():
|
|
||||||
"""
|
|
||||||
调试调用
|
|
||||||
"""
|
|
||||||
|
|
||||||
Replace({"合同编号_A": "11111", "合同名称_A": "11111"})
|
|
||||||
|
|
||||||
|
|
||||||
def DebugCallReplaceList():
|
|
||||||
"""
|
|
||||||
调试调用,替换list
|
|
||||||
"""
|
|
||||||
|
|
||||||
Replace({"list": "1\r2\r3\r4"})
|
|
||||||
|
|
||||||
|
|
||||||
def QueryAll():
|
def QueryAll():
|
||||||
"""
|
"""
|
||||||
查询所有书签,表格中的书签获取对应表格index
|
查询所有书签,表格中的书签获取对应表格index
|
||||||
@ -78,39 +78,61 @@ def QueryAll():
|
|||||||
def QueryAllWithJSON():
|
def QueryAllWithJSON():
|
||||||
return returnWithJSON(QueryAll())
|
return returnWithJSON(QueryAll())
|
||||||
|
|
||||||
|
|
||||||
def QueryBookmarkPositionInTable(tables, bookmarks):
|
def QueryBookmarkPositionInTable(tables, bookmarks):
|
||||||
"""
|
"""
|
||||||
查询书签在表格中的位置
|
查询书签在表格中的位置。
|
||||||
{'bk1': {'tableIndex': 0, 'row': 0, 'col': 0}, 'bk2': {'tableIndex': 0, 'row': 0, 'col': 2}}
|
|
||||||
|
参数:
|
||||||
|
tables: 表格集合 (XIndexAccess)
|
||||||
|
bookmarks: 书签集合 (XIndexAccess)
|
||||||
|
|
||||||
|
返回:
|
||||||
|
一个字典,格式为 {'书签名': {'tableIndex': 表格索引, 'row': 行号}}
|
||||||
"""
|
"""
|
||||||
|
result = {}
|
||||||
|
|
||||||
bookmark_names = bookmarks.getElementNames()
|
# 遍历所有书签
|
||||||
|
for b in range(bookmarks.getCount()):
|
||||||
|
bookmark = bookmarks.getByIndex(b)
|
||||||
|
bookmark_name = bookmark.getName()
|
||||||
|
x_range = bookmark.getAnchor() # 获取书签的锚点
|
||||||
|
x_text = x_range.getText() # 获取书签所在的文本对象
|
||||||
|
|
||||||
bookmark_position = {}
|
# 遍历所有表格
|
||||||
|
for t in range(tables.getCount()):
|
||||||
|
table = tables.getByIndex(t)
|
||||||
|
|
||||||
for table_index in range(tables.getCount()):
|
# 遍历表格中的每一行
|
||||||
table = tables.getByIndex(table_index)
|
rows = table.getRows().getCount()
|
||||||
|
for i in range(rows):
|
||||||
|
# 动态确定当前行的最大列数
|
||||||
|
max_cols = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
cell = table.getCellByPosition(max_cols, i)
|
||||||
|
max_cols += 1
|
||||||
|
except Exception:
|
||||||
|
break
|
||||||
|
|
||||||
col_count = table.getColumns().getCount()
|
for j in range(max_cols):
|
||||||
row_count = table.getRows().getCount()
|
cell = table.getCellByPosition(j, i)
|
||||||
|
cell_text = cell.getText()
|
||||||
|
|
||||||
for row in range(row_count):
|
if cell_text == x_text:
|
||||||
for col in range(col_count):
|
result[bookmark_name] = {
|
||||||
cell = table.getCellByPosition(col, row)
|
'tableIndex': t,
|
||||||
cell_text_obj = cell.getText()
|
'row': i,
|
||||||
|
'col': j
|
||||||
for bk_name in bookmark_names:
|
|
||||||
bookmark_obj = bookmarks.getByName(bk_name)
|
|
||||||
bookmark_text_obj = bookmark_obj.getAnchor().getText()
|
|
||||||
if cell_text_obj == bookmark_text_obj:
|
|
||||||
bookmark_position[bk_name] = {
|
|
||||||
"tableIndex": table_index,
|
|
||||||
"col": col,
|
|
||||||
"row": row,
|
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
return bookmark_position
|
return result
|
||||||
|
|
||||||
def InsertRowWithJSON(json_str):
|
def InsertRowWithJSON(json_str):
|
||||||
"""
|
"""
|
||||||
@ -151,9 +173,6 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1):
|
|||||||
if not data or len(data) == 0:
|
if not data or len(data) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if any(len(row) != col_count for row in data):
|
|
||||||
raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
row_count = handle_table.getRows().getCount()
|
row_count = handle_table.getRows().getCount()
|
||||||
rows_to_insert = len(data)
|
rows_to_insert = len(data)
|
||||||
@ -178,7 +197,6 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RuntimeError(f"err: {str(e)}")
|
raise RuntimeError(f"err: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
def BatchInsertRowWithContentControl(data_array):
|
def BatchInsertRowWithContentControl(data_array):
|
||||||
"""
|
"""
|
||||||
批量插入行
|
批量插入行
|
||||||
@ -210,8 +228,8 @@ def BatchInsertRowWithContentControl(data_array):
|
|||||||
if not data or len(data) == 0:
|
if not data or len(data) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if any(len(row) != col_count for row in data):
|
# if any(len(row) != col_count for row in data):
|
||||||
raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
|
# raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
row_count = handle_table.getRows().getCount()
|
row_count = handle_table.getRows().getCount()
|
||||||
@ -233,28 +251,28 @@ def BatchInsertRowWithContentControl(data_array):
|
|||||||
for col_idx, cell_value in enumerate(row_data):
|
for col_idx, cell_value in enumerate(row_data):
|
||||||
cell = handle_table.getCellByPosition(col_idx, target_row)
|
cell = handle_table.getCellByPosition(col_idx, target_row)
|
||||||
cell_text = cell.getText()
|
cell_text = cell.getText()
|
||||||
|
|
||||||
# === 清空单元格 ===
|
# === 清空单元格 ===
|
||||||
cell_text.setString("")
|
cell_text.setString("")
|
||||||
|
|
||||||
# === 创建内容控件 ===
|
# === 创建内容控件 ===
|
||||||
content_control = doc.createInstance("com.sun.star.text.ContentControl")
|
content_control = doc.createInstance(
|
||||||
|
"com.sun.star.text.ContentControl"
|
||||||
|
)
|
||||||
|
|
||||||
# === 插入控件到单元格 ===
|
# === 插入控件到单元格 ===
|
||||||
cursor = cell_text.createTextCursor()
|
cursor = cell_text.createTextCursor()
|
||||||
cell_text.insertTextContent(cursor, content_control, False)
|
cell_text.insertTextContent(cursor, content_control, False)
|
||||||
|
|
||||||
# === 设置控件内容 ===
|
# === 设置控件内容 ===
|
||||||
cc_text = content_control.getText()
|
cc_text = content_control.getText()
|
||||||
cc_cursor = cc_text.createTextCursor()
|
cc_cursor = cc_text.createTextCursor()
|
||||||
cc_cursor.setString(str(cell_value))
|
cc_cursor.setString(str(cell_value))
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def BatchInsertRow(data_array):
|
def BatchInsertRow(data_array):
|
||||||
"""
|
"""
|
||||||
批量插入行
|
批量插入行
|
||||||
@ -314,6 +332,7 @@ def BatchInsertRow(data_array):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
def DeleteRowWithJSON(json_str):
|
def DeleteRowWithJSON(json_str):
|
||||||
"""
|
"""
|
||||||
删除行
|
删除行
|
||||||
@ -360,6 +379,7 @@ def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-1):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RuntimeError(f"err: {str(e)}")
|
raise RuntimeError(f"err: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
def LocateBookmark(bookmark_name):
|
def LocateBookmark(bookmark_name):
|
||||||
"""
|
"""
|
||||||
定位书签并选中内容
|
定位书签并选中内容
|
||||||
@ -479,6 +499,7 @@ def DeleteBookmark(bookmark_name):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def CreateTable(location_bookmark_name, data):
|
def CreateTable(location_bookmark_name, data):
|
||||||
"""
|
"""
|
||||||
创建表格
|
创建表格
|
||||||
@ -499,8 +520,8 @@ def ReplaceTextAndInsertTableRow(json_str):
|
|||||||
|
|
||||||
def ReplaceTextAndInsertTableRowWithContentControl(json_str):
|
def ReplaceTextAndInsertTableRowWithContentControl(json_str):
|
||||||
data = json.loads(json_str)
|
data = json.loads(json_str)
|
||||||
|
# BatchInsertRowWithContentControl(data["table"])
|
||||||
ReplaceBookmarksWithControls(data["text"])
|
ReplaceBookmarksWithControls(data["text"])
|
||||||
BatchInsertRowWithContentControl(data["table"])
|
|
||||||
|
|
||||||
|
|
||||||
def returnWithJSON(data):
|
def returnWithJSON(data):
|
||||||
@ -525,53 +546,58 @@ def SaveDocument():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def DebugCallReplaceBookmarksWithControls():
|
|
||||||
ReplaceBookmarksWithControls({"合同编号_A": "11111", "合同名称_A": "22222"})
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
|
def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
|
||||||
|
# 获取文档对象
|
||||||
doc = XSCRIPTCONTEXT.getDocument()
|
doc = XSCRIPTCONTEXT.getDocument()
|
||||||
bookmarks = doc.getBookmarks()
|
bookmarks = doc.getBookmarks()
|
||||||
|
|
||||||
for i in reversed(range(bookmarks.getCount())):
|
# 过滤包含下划线前缀的书签
|
||||||
bookmark = bookmarks.getByIndex(i)
|
bookmark_names = [name for name in bookmarks.getElementNames() if not name.startswith("_")]
|
||||||
name = bookmark.getName()
|
|
||||||
anchor = bookmark.getAnchor()
|
# 遍历所有需要处理的书签
|
||||||
if not anchor:
|
for name in bookmark_names:
|
||||||
continue
|
try:
|
||||||
|
# 检查书签是否存在
|
||||||
|
if not bookmarks.hasByName(name):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 获取书签对象及其锚点
|
||||||
|
bookmark = bookmarks.getByName(name)
|
||||||
|
anchor = bookmark.getAnchor()
|
||||||
|
|
||||||
|
# 获取书签的原始内容
|
||||||
|
original_text = anchor.getString()
|
||||||
|
replace_value = bookmark_name_value_map.get(name, original_text)
|
||||||
|
|
||||||
|
# === 第1步:创建内容控件 ===
|
||||||
|
content_control = doc.createInstance("com.sun.star.text.ContentControl")
|
||||||
|
|
||||||
|
# 获取书签所在文本对象并清空原内容
|
||||||
|
text = anchor.getText()
|
||||||
|
anchor.setString("")
|
||||||
|
|
||||||
|
# 插入内容控件
|
||||||
|
text.insertTextContent(anchor, content_control, True)
|
||||||
|
|
||||||
|
# 设置控件内容
|
||||||
|
cc_cursor = content_control.getText().createTextCursor()
|
||||||
|
cc_cursor.setString(replace_value)
|
||||||
|
|
||||||
|
# === 第2步:清理旧书签 ===
|
||||||
|
bookmark.dispose()
|
||||||
|
|
||||||
|
# === 第3步:创建新书签 ===
|
||||||
|
cc_anchor = content_control.getText().getAnchor()
|
||||||
|
new_bookmark = doc.createInstance("com.sun.star.text.Bookmark")
|
||||||
|
new_bookmark.setName(name)
|
||||||
|
new_bookmark.attach(cc_anchor)
|
||||||
|
|
||||||
original_text = anchor.getString()
|
except Exception as e:
|
||||||
replace_value = bookmark_name_value_map.get(name, original_text)
|
print(f"处理书签 '{name}' 时出错: {e}")
|
||||||
|
|
||||||
# === 第1步:创建内容控件 ===
|
|
||||||
content_control = doc.createInstance("com.sun.star.text.ContentControl")
|
|
||||||
|
|
||||||
# 获取书签所在文本对象
|
|
||||||
text = anchor.getText()
|
|
||||||
anchor.setString("")
|
|
||||||
# # 创建游标并清空原内容
|
|
||||||
|
|
||||||
# 插入内容控件
|
|
||||||
text.insertTextContent(anchor, content_control, True)
|
|
||||||
|
|
||||||
# 设置控件内容
|
|
||||||
cc_cursor = content_control.getText().createTextCursor()
|
|
||||||
cc_cursor.setString(replace_value)
|
|
||||||
|
|
||||||
# === 第1步:清理旧书签 ===
|
|
||||||
bookmark.dispose()
|
|
||||||
|
|
||||||
# === 第2步:创建新书签 ===
|
|
||||||
# 获取控件实际范围
|
|
||||||
cc_anchor = content_control.getText().getAnchor()
|
|
||||||
|
|
||||||
new_bookmark = doc.createInstance("com.sun.star.text.Bookmark")
|
|
||||||
new_bookmark.setName(name)
|
|
||||||
new_bookmark.attach(cc_anchor)
|
|
||||||
|
|
||||||
def NextEditableZone(current_index):
|
def NextEditableZone(current_index):
|
||||||
"""
|
"""
|
||||||
根据索引定位可编辑的内容控件(支持循环)
|
根据索引定位名称包含'permission'的书签(支持循环)
|
||||||
Args:
|
Args:
|
||||||
current_index (int/str): 从 0 开始的索引,支持字符串或整数类型
|
current_index (int/str): 从 0 开始的索引,支持字符串或整数类型
|
||||||
"""
|
"""
|
||||||
@ -586,33 +612,49 @@ def NextEditableZone(current_index):
|
|||||||
controller = doc.getCurrentController()
|
controller = doc.getCurrentController()
|
||||||
view_cursor = controller.getViewCursor()
|
view_cursor = controller.getViewCursor()
|
||||||
|
|
||||||
# 收集所有内容控件的锚点
|
bookmarks = doc.getBookmarks()
|
||||||
text_content = doc.getText().createEnumeration()
|
bookmark_names = bookmarks.getElementNames()
|
||||||
editable_anchors = []
|
|
||||||
while text_content.hasMoreElements():
|
|
||||||
element = text_content.nextElement()
|
|
||||||
# 关键修改点:检查内容控件服务
|
|
||||||
if element.supportsService("com.sun.star.text.ContentControl"):
|
|
||||||
try:
|
|
||||||
anchor = element.getAnchor()
|
|
||||||
editable_anchors.append(anchor)
|
|
||||||
except Exception:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 无控件时直接返回
|
# 过滤包含permission的书签(不区分大小写)
|
||||||
|
permission_bookmarks = [name for name in bookmark_names if not name.startswith("_")]
|
||||||
|
|
||||||
|
editable_anchors = []
|
||||||
|
for bm_name in permission_bookmarks:
|
||||||
|
try:
|
||||||
|
bookmark = bookmarks.getByName(bm_name)
|
||||||
|
anchor = bookmark.getAnchor()
|
||||||
|
editable_anchors.append(anchor)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"err '{bm_name}' e: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 无匹配书签时直接返回
|
||||||
if not editable_anchors:
|
if not editable_anchors:
|
||||||
print("文档中未找到内容控件")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# 计算有效索引(循环逻辑)
|
# 计算有效索引(循环逻辑)
|
||||||
total = len(editable_anchors)
|
total = len(editable_anchors)
|
||||||
effective_index = current_index % total # 自动处理越界
|
effective_index = current_index % total # 自动处理越界
|
||||||
|
|
||||||
# 定位到目标控件
|
# 定位到目标书签
|
||||||
target_anchor = editable_anchors[effective_index]
|
target_anchor = editable_anchors[effective_index]
|
||||||
view_cursor.gotoRange(target_anchor.getStart(), False) # 跳转到控件起始位置
|
|
||||||
controller.select(target_anchor) # 选中整个控件范围
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 跳转到书签起始位置
|
||||||
|
view_cursor.gotoRange(target_anchor, False)
|
||||||
|
# 选中整个书签范围
|
||||||
|
controller.select(target_anchor)
|
||||||
|
|
||||||
|
# 窗口可见性处理
|
||||||
|
try:
|
||||||
|
window = controller.getFrame().getContainerWindow()
|
||||||
|
window.setVisible(True)
|
||||||
|
window.toFront()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeError(f"err: {str(e)}") from e
|
||||||
|
|
||||||
|
|
||||||
g_exportedScripts = (
|
g_exportedScripts = (
|
||||||
@ -625,11 +667,8 @@ g_exportedScripts = (
|
|||||||
DeleteRow,
|
DeleteRow,
|
||||||
DeleteRowWithJSON,
|
DeleteRowWithJSON,
|
||||||
ReplaceTextAndInsertTableRow,
|
ReplaceTextAndInsertTableRow,
|
||||||
DebugCallReplace,
|
|
||||||
DebugCallReplaceList,
|
|
||||||
ReplaceBookmarksWithControls,
|
ReplaceBookmarksWithControls,
|
||||||
ReplaceTextAndInsertTableRowWithContentControl,
|
ReplaceTextAndInsertTableRowWithContentControl,
|
||||||
DebugCallReplaceBookmarksWithControls,
|
|
||||||
SaveDocument,
|
SaveDocument,
|
||||||
NextEditableZone,
|
NextEditableZone,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user