2025-03-24 11:49:58 +08:00
|
|
|
|
import json
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def Replace(bookmark_name_value_map):
|
|
|
|
|
"""
|
|
|
|
|
替换所有书签
|
|
|
|
|
Args:
|
|
|
|
|
bookmark_name_value_map: 书签名称和新值的映射
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
for bookmark_name, new_value in bookmark_name_value_map.items():
|
|
|
|
|
if bookmarks.hasByName(bookmark_name):
|
|
|
|
|
bookmark = bookmarks.getByName(bookmark_name)
|
|
|
|
|
anchor = bookmark.getAnchor()
|
|
|
|
|
anchor.setString(new_value)
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
def ReplaceOne(bookmark_obj_collection, bookmark_name, new_value):
|
2025-03-24 11:49:58 +08:00
|
|
|
|
"""
|
2025-03-27 15:16:04 +08:00
|
|
|
|
替换一个书签
|
2025-03-24 11:49:58 +08:00
|
|
|
|
Args:
|
2025-03-27 15:16:04 +08:00
|
|
|
|
bookmark_obj_collection: 书签对象集合
|
|
|
|
|
bookmark_name: 书签名称
|
|
|
|
|
new_value: 新值
|
2025-03-24 11:49:58 +08:00
|
|
|
|
"""
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
if bookmark_obj_collection.hasByName(bookmark_name):
|
|
|
|
|
bookmark = bookmark_obj_collection.getByName(bookmark_name)
|
|
|
|
|
anchor = bookmark.getAnchor()
|
|
|
|
|
anchor.setString(new_value)
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
def ReplaceWithJSON(json_str):
|
2025-03-24 11:49:58 +08:00
|
|
|
|
"""
|
2025-03-27 15:16:04 +08:00
|
|
|
|
替换所有书签
|
|
|
|
|
Args:
|
|
|
|
|
json_str: 书签名称和新值的映射的JSON字符串
|
2025-03-24 11:49:58 +08:00
|
|
|
|
"""
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
bookmark_name_value_map = json.loads(json_str)
|
|
|
|
|
Replace(bookmark_name_value_map)
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def QueryAll():
|
|
|
|
|
"""
|
|
|
|
|
查询所有书签,表格中的书签获取对应表格index
|
|
|
|
|
|
|
|
|
|
返回结果格式:
|
|
|
|
|
{
|
|
|
|
|
"text": [],
|
|
|
|
|
"table": [
|
|
|
|
|
{
|
|
|
|
|
"tableIndex": 表格索引,
|
|
|
|
|
"bookmark": [书签名称列表]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_names = bookmarks.getElementNames()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
filtered_bookmarks = [
|
|
|
|
|
bk_name
|
|
|
|
|
for bk_name in bookmark_names
|
|
|
|
|
if not bk_name.startswith("_") and ":" not in bk_name
|
|
|
|
|
]
|
2025-03-24 11:49:58 +08:00
|
|
|
|
result = {"text": [], "table": []}
|
|
|
|
|
|
|
|
|
|
for bk_name in filtered_bookmarks:
|
2025-03-24 18:23:13 +08:00
|
|
|
|
result["text"].append(bk_name)
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def QueryAllWithJSON():
|
|
|
|
|
return returnWithJSON(QueryAll())
|
|
|
|
|
|
|
|
|
|
def QueryBookmarkPositionInTable(tables, bookmarks):
|
|
|
|
|
"""
|
2025-03-27 15:16:04 +08:00
|
|
|
|
查询书签在表格中的位置。
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
tables: 表格集合 (XIndexAccess)
|
|
|
|
|
bookmarks: 书签集合 (XIndexAccess)
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
一个字典,格式为 {'书签名': {'tableIndex': 表格索引, 'row': 行号}}
|
|
|
|
|
"""
|
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
|
|
# 遍历所有书签
|
|
|
|
|
for b in range(bookmarks.getCount()):
|
|
|
|
|
bookmark = bookmarks.getByIndex(b)
|
|
|
|
|
bookmark_name = bookmark.getName()
|
|
|
|
|
x_range = bookmark.getAnchor() # 获取书签的锚点
|
|
|
|
|
x_text = x_range.getText() # 获取书签所在的文本对象
|
|
|
|
|
|
|
|
|
|
# 遍历所有表格
|
|
|
|
|
for t in range(tables.getCount()):
|
|
|
|
|
table = tables.getByIndex(t)
|
|
|
|
|
|
|
|
|
|
# 遍历表格中的每一行
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
for j in range(max_cols):
|
|
|
|
|
cell = table.getCellByPosition(j, i)
|
|
|
|
|
cell_text = cell.getText()
|
|
|
|
|
|
|
|
|
|
if cell_text == x_text:
|
|
|
|
|
result[bookmark_name] = {
|
|
|
|
|
'tableIndex': t,
|
|
|
|
|
'row': i,
|
|
|
|
|
'col': j
|
2025-03-24 11:49:58 +08:00
|
|
|
|
}
|
2025-03-27 15:16:04 +08:00
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
break
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
return result
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
2025-03-24 14:51:09 +08:00
|
|
|
|
def InsertRowWithJSON(json_str):
|
|
|
|
|
"""
|
|
|
|
|
插入行
|
|
|
|
|
"""
|
|
|
|
|
data = json.loads(json_str)
|
|
|
|
|
InsertRow(data["location_bookmark_name"], data["data"], data["start_row_index"])
|
|
|
|
|
|
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def InsertRow(location_bookmark_name, data, start_row_index=-1):
|
|
|
|
|
"""
|
|
|
|
|
表格插入行
|
|
|
|
|
Args:
|
|
|
|
|
location_bookmark_name: 用于定位表格的书签
|
|
|
|
|
data: 二维数组,用于填充表格数据
|
|
|
|
|
start_row_index: 起始行位置,默认为-1,即在表格末尾插入
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
tables = doc.getTextTables()
|
2025-03-25 10:33:49 +08:00
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_in_table_position = QueryBookmarkPositionInTable(tables, bookmarks)
|
|
|
|
|
if location_bookmark_name not in bookmark_in_table_position:
|
|
|
|
|
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
handle_table_index = bookmark_in_table_position[location_bookmark_name][
|
|
|
|
|
"tableIndex"
|
|
|
|
|
]
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
handle_table = tables.getByIndex(handle_table_index)
|
|
|
|
|
except IndexError:
|
|
|
|
|
raise IndexError(f"表格索引 {handle_table_index} 超出范围")
|
|
|
|
|
|
|
|
|
|
col_count = handle_table.getColumns().getCount()
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
|
|
|
|
|
if not data or len(data) == 0:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
2025-03-24 15:55:55 +08:00
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
rows_to_insert = len(data)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 15:55:55 +08:00
|
|
|
|
if rows_to_insert > 0:
|
|
|
|
|
# 确定插入位置
|
|
|
|
|
if start_row_index != -1 and 0 <= start_row_index < row_count:
|
|
|
|
|
insert_pos = start_row_index + 1 # 在指定行下方插入
|
2025-03-24 11:49:58 +08:00
|
|
|
|
else:
|
2025-03-24 15:55:55 +08:00
|
|
|
|
insert_pos = row_count # 插入到表格末尾
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 15:55:55 +08:00
|
|
|
|
# 批量插入所有新行
|
|
|
|
|
handle_table.getRows().insertByIndex(insert_pos, rows_to_insert)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 15:55:55 +08:00
|
|
|
|
# 填充数据到新插入的行
|
|
|
|
|
for data_row_idx, row_data in enumerate(data):
|
|
|
|
|
target_row = insert_pos + data_row_idx # 计算目标行索引
|
|
|
|
|
for col_idx, cell_value in enumerate(row_data):
|
|
|
|
|
cell = handle_table.getCellByPosition(col_idx, target_row)
|
|
|
|
|
cell.setString(str(cell_value))
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
except Exception as e:
|
2025-03-27 10:13:08 +08:00
|
|
|
|
raise RuntimeError(f"err: {str(e)}")
|
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
def BatchInsertRowWithContentControl(data_array):
|
|
|
|
|
"""
|
|
|
|
|
批量插入行
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
tables = doc.getTextTables()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_in_table_position = QueryBookmarkPositionInTable(tables, bookmarks)
|
|
|
|
|
|
|
|
|
|
for arr_obj in data_array:
|
2025-03-27 10:13:08 +08:00
|
|
|
|
location_bookmark_name = arr_obj.get("location_bookmark_name")
|
|
|
|
|
data = arr_obj.get("data")
|
|
|
|
|
start_row_index = arr_obj.get("start_row_index", -1) # 默认值为 -1
|
2025-03-26 11:09:42 +08:00
|
|
|
|
if location_bookmark_name not in bookmark_in_table_position:
|
|
|
|
|
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
|
|
|
|
handle_table_index = bookmark_in_table_position[location_bookmark_name][
|
|
|
|
|
"tableIndex"
|
|
|
|
|
]
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
handle_table = tables.getByIndex(handle_table_index)
|
|
|
|
|
except IndexError:
|
|
|
|
|
raise IndexError(f"表格索引 {handle_table_index} 超出范围")
|
|
|
|
|
|
|
|
|
|
col_count = handle_table.getColumns().getCount()
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
|
|
|
|
|
if not data or len(data) == 0:
|
|
|
|
|
return
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# if any(len(row) != col_count for row in data):
|
|
|
|
|
# raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
rows_to_insert = len(data)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
if rows_to_insert > 0:
|
|
|
|
|
# 确定插入位置
|
|
|
|
|
if start_row_index != -1 and 0 <= start_row_index < row_count:
|
|
|
|
|
insert_pos = start_row_index + 1 # 在指定行下方插入
|
|
|
|
|
else:
|
|
|
|
|
insert_pos = row_count # 插入到表格末尾
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
# 批量插入所有新行
|
|
|
|
|
handle_table.getRows().insertByIndex(insert_pos, rows_to_insert)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
# 填充数据到新插入的行
|
|
|
|
|
for data_row_idx, row_data in enumerate(data):
|
|
|
|
|
target_row = insert_pos + data_row_idx # 计算目标行索引
|
|
|
|
|
for col_idx, cell_value in enumerate(row_data):
|
|
|
|
|
cell = handle_table.getCellByPosition(col_idx, target_row)
|
|
|
|
|
cell_text = cell.getText()
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
# === 清空单元格 ===
|
|
|
|
|
cell_text.setString("")
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
# === 创建内容控件 ===
|
2025-03-27 15:16:04 +08:00
|
|
|
|
content_control = doc.createInstance(
|
|
|
|
|
"com.sun.star.text.ContentControl"
|
|
|
|
|
)
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
# === 插入控件到单元格 ===
|
2025-03-26 11:09:42 +08:00
|
|
|
|
cursor = cell_text.createTextCursor()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
cell_text.insertTextContent(cursor, content_control, False)
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
# === 设置控件内容 ===
|
|
|
|
|
cc_text = content_control.getText()
|
|
|
|
|
cc_cursor = cc_text.createTextCursor()
|
|
|
|
|
cc_cursor.setString(str(cell_value))
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
def BatchInsertRow(data_array):
|
|
|
|
|
"""
|
|
|
|
|
批量插入行
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
tables = doc.getTextTables()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_in_table_position = QueryBookmarkPositionInTable(tables, bookmarks)
|
|
|
|
|
|
|
|
|
|
for arr_obj in data_array:
|
2025-03-27 10:13:08 +08:00
|
|
|
|
location_bookmark_name = arr_obj.get("location_bookmark_name")
|
|
|
|
|
data = arr_obj.get("data")
|
|
|
|
|
start_row_index = arr_obj.get("start_row_index", -1) # 默认值为 -1
|
2025-03-25 14:14:22 +08:00
|
|
|
|
if location_bookmark_name not in bookmark_in_table_position:
|
|
|
|
|
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
|
|
|
|
handle_table_index = bookmark_in_table_position[location_bookmark_name][
|
|
|
|
|
"tableIndex"
|
|
|
|
|
]
|
2025-03-25 14:14:22 +08:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
handle_table = tables.getByIndex(handle_table_index)
|
|
|
|
|
except IndexError:
|
|
|
|
|
raise IndexError(f"表格索引 {handle_table_index} 超出范围")
|
|
|
|
|
|
|
|
|
|
col_count = handle_table.getColumns().getCount()
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
|
|
|
|
|
if not data or len(data) == 0:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if any(len(row) != col_count for row in data):
|
|
|
|
|
raise ValueError(f"数据列数不匹配,表格有 {col_count} 列")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
rows_to_insert = len(data)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
if rows_to_insert > 0:
|
|
|
|
|
# 确定插入位置
|
|
|
|
|
if start_row_index != -1 and 0 <= start_row_index < row_count:
|
|
|
|
|
insert_pos = start_row_index + 1 # 在指定行下方插入
|
|
|
|
|
else:
|
|
|
|
|
insert_pos = row_count # 插入到表格末尾
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
# 批量插入所有新行
|
|
|
|
|
handle_table.getRows().insertByIndex(insert_pos, rows_to_insert)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
# 填充数据到新插入的行
|
|
|
|
|
for data_row_idx, row_data in enumerate(data):
|
|
|
|
|
target_row = insert_pos + data_row_idx # 计算目标行索引
|
|
|
|
|
for col_idx, cell_value in enumerate(row_data):
|
|
|
|
|
cell = handle_table.getCellByPosition(col_idx, target_row)
|
|
|
|
|
cell.setString(str(cell_value))
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
raise RuntimeError(f"插入行时发生错误: {str(e)}")
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-24 14:51:09 +08:00
|
|
|
|
def DeleteRowWithJSON(json_str):
|
|
|
|
|
"""
|
|
|
|
|
删除行
|
|
|
|
|
"""
|
|
|
|
|
data = json.loads(json_str)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
DeleteRow(
|
|
|
|
|
data["location_bookmark_name"],
|
|
|
|
|
data["start_row_index"],
|
|
|
|
|
data["delete_row_count"],
|
|
|
|
|
)
|
|
|
|
|
|
2025-03-24 14:51:09 +08:00
|
|
|
|
|
|
|
|
|
def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-1):
|
2025-03-24 11:49:58 +08:00
|
|
|
|
"""
|
|
|
|
|
删除表格行
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
location_bookmark_name: 用于定位表格的书签
|
|
|
|
|
start_row_index: 起始行位置(删除行包含本行)
|
|
|
|
|
delete_row_count: 删除的行数
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
tables = doc.getTextTables()
|
2025-03-25 10:33:49 +08:00
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_in_table_position = QueryBookmarkPositionInTable(tables, bookmarks)
|
|
|
|
|
if location_bookmark_name not in bookmark_in_table_position:
|
|
|
|
|
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
handle_table_index = bookmark_in_table_position[location_bookmark_name][
|
|
|
|
|
"tableIndex"
|
|
|
|
|
]
|
2025-03-25 10:33:49 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
handle_table = tables.getByIndex(handle_table_index)
|
|
|
|
|
row_count = handle_table.getRows().getCount()
|
|
|
|
|
if start_row_index < 0 or start_row_index >= row_count:
|
|
|
|
|
raise ValueError(f"起始行索引 {start_row_index} 超出范围")
|
|
|
|
|
|
2025-03-24 14:51:09 +08:00
|
|
|
|
# 如果未指定删除行数或超出范围,则删除剩余所有行
|
|
|
|
|
if start_row_index + delete_row_count > row_count or delete_row_count == -1:
|
|
|
|
|
delete_row_count = row_count - start_row_index
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
handle_table.getRows().removeByIndex(start_row_index, delete_row_count)
|
|
|
|
|
except Exception as e:
|
2025-03-27 10:13:08 +08:00
|
|
|
|
raise RuntimeError(f"err: {str(e)}")
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def LocateBookmark(bookmark_name):
|
|
|
|
|
"""
|
|
|
|
|
定位书签并选中内容
|
|
|
|
|
Args:
|
|
|
|
|
bookmark_name: 要定位的书签名称
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
|
|
|
|
|
if False == doc.getBookmarks().hasByName(bookmark_name):
|
2025-03-27 10:13:08 +08:00
|
|
|
|
return
|
2025-03-24 11:49:58 +08:00
|
|
|
|
|
|
|
|
|
bookmark = doc.getBookmarks().getByName(bookmark_name)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 获取书签的文本范围锚点
|
|
|
|
|
anchor = bookmark.getAnchor()
|
|
|
|
|
|
|
|
|
|
# 获取文档控制器
|
|
|
|
|
controller = doc.getCurrentController()
|
|
|
|
|
|
|
|
|
|
# 将视图光标移动到书签位置并选中
|
|
|
|
|
view_cursor = controller.getViewCursor()
|
|
|
|
|
view_cursor.gotoRange(anchor, False) # False表示不扩展选区
|
|
|
|
|
|
|
|
|
|
# 如果需要高亮显示(可选)
|
|
|
|
|
controller.select(anchor)
|
|
|
|
|
|
|
|
|
|
# 确保窗口可见(针对隐藏窗口的情况)
|
|
|
|
|
try:
|
|
|
|
|
window = controller.getFrame().getContainerWindow()
|
|
|
|
|
window.setVisible(True)
|
|
|
|
|
window.toFront()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise RuntimeError(f"定位书签失败: {str(e)}") from e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def InsertBookmark(bookmark_name):
|
|
|
|
|
"""
|
|
|
|
|
选中内容插入书签,如果没有选中任何内容,插入点书签
|
|
|
|
|
Args:
|
|
|
|
|
bookmark_name: 要插入的书签名称
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
controller = doc.getCurrentController()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
# 获取当前选区
|
|
|
|
|
selection = controller.getSelection()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
# 检查是否已存在同名书签,如果存在则先删除
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
if bookmarks.hasByName(bookmark_name):
|
|
|
|
|
bookmarks.getByName(bookmark_name).dispose()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
try:
|
|
|
|
|
# 创建书签
|
|
|
|
|
if selection.getCount() > 0:
|
|
|
|
|
# 尝试获取选区的第一个元素
|
|
|
|
|
range_to_bookmark = selection.getByIndex(0)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
# 创建书签并附加到选区
|
|
|
|
|
bookmark = doc.createInstance("com.sun.star.text.Bookmark")
|
|
|
|
|
bookmark.attach(range_to_bookmark)
|
|
|
|
|
bookmark.setName(bookmark_name)
|
|
|
|
|
else:
|
|
|
|
|
# 没有选中内容,创建点书签
|
|
|
|
|
cursor = controller.getViewCursor()
|
|
|
|
|
text_cursor = cursor.getText().createTextCursorByRange(cursor)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
# 创建书签并附加到光标位置
|
|
|
|
|
bookmark = doc.createInstance("com.sun.star.text.Bookmark")
|
|
|
|
|
bookmark.attach(text_cursor)
|
|
|
|
|
bookmark.setName(bookmark_name)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise RuntimeError(f"插入书签失败: {str(e)}") from e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def UpdateBookmark(bookmark_name, new_value):
|
|
|
|
|
"""
|
|
|
|
|
修改书签名称(通过删除旧书签 + 插入新书签实现)
|
|
|
|
|
Args:
|
|
|
|
|
bookmark_name: 原书签名称
|
|
|
|
|
new_value: 新书签名称
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
|
|
|
|
|
if not bookmarks.hasByName(bookmark_name):
|
|
|
|
|
raise ValueError(f"书签 '{bookmark_name}' 不存在")
|
|
|
|
|
|
|
|
|
|
if bookmarks.hasByName(new_value):
|
|
|
|
|
raise ValueError(f"书签 '{new_value}' 已存在")
|
|
|
|
|
|
|
|
|
|
# 获取旧书签的锚点位置
|
|
|
|
|
old_bookmark = bookmarks.getByName(bookmark_name)
|
|
|
|
|
old_bookmark.setName(new_value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def DeleteBookmark(bookmark_name):
|
|
|
|
|
"""
|
|
|
|
|
删除书签但保留内容(通过断开书签与锚点的关联)
|
|
|
|
|
"""
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
|
|
|
|
|
if not bookmarks.hasByName(bookmark_name):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
bookmark = bookmarks.getByName(bookmark_name)
|
|
|
|
|
|
|
|
|
|
if hasattr(bookmark, "Anchor"):
|
|
|
|
|
try:
|
|
|
|
|
anchor = bookmark.Anchor
|
|
|
|
|
anchor.getText().removeTextContent(bookmark)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
pass
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def CreateTable(location_bookmark_name, data):
|
|
|
|
|
"""
|
|
|
|
|
创建表格
|
|
|
|
|
Args:
|
|
|
|
|
location_bookmark_name: 用于定位表格的书签
|
|
|
|
|
data: 二维数组,用于填充表格数据
|
|
|
|
|
"""
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 14:14:22 +08:00
|
|
|
|
def ReplaceTextAndInsertTableRow(json_str):
|
|
|
|
|
"""
|
|
|
|
|
替换文本和表格
|
|
|
|
|
"""
|
|
|
|
|
data = json.loads(json_str)
|
|
|
|
|
Replace(data["text"])
|
|
|
|
|
BatchInsertRow(data["table"])
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
def ReplaceTextAndInsertTableRowWithContentControl(json_str):
|
|
|
|
|
data = json.loads(json_str)
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# BatchInsertRowWithContentControl(data["table"])
|
2025-03-26 11:09:42 +08:00
|
|
|
|
ReplaceBookmarksWithControls(data["text"])
|
2025-03-25 16:43:02 +08:00
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
def returnWithJSON(data):
|
|
|
|
|
return json.dumps(data, ensure_ascii=False)
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 16:43:02 +08:00
|
|
|
|
def SaveDocument():
|
|
|
|
|
# 获取当前文档对象
|
|
|
|
|
model = XSCRIPTCONTEXT.getDocument()
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 16:43:02 +08:00
|
|
|
|
try:
|
|
|
|
|
# 检查文档是否支持保存(XStorable 接口)
|
|
|
|
|
from com.sun.star.frame import XStorable
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 16:43:02 +08:00
|
|
|
|
xstorable = model.uno_getAdapter(XStorable)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-25 16:43:02 +08:00
|
|
|
|
# 调用保存方法(覆盖原文件)
|
|
|
|
|
xstorable.store()
|
|
|
|
|
return True
|
|
|
|
|
except Exception as e:
|
2025-03-26 11:09:42 +08:00
|
|
|
|
print("err:", e)
|
2025-03-25 16:43:02 +08:00
|
|
|
|
return False
|
|
|
|
|
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# 获取文档对象
|
2025-03-25 16:43:02 +08:00
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
bookmarks = doc.getBookmarks()
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# 过滤包含下划线前缀的书签
|
|
|
|
|
bookmark_names = [name for name in bookmarks.getElementNames() if not name.startswith("_")]
|
|
|
|
|
|
|
|
|
|
# 遍历所有需要处理的书签
|
|
|
|
|
for name in bookmark_names:
|
|
|
|
|
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)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"处理书签 '{name}' 时出错: {e}")
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
|
|
|
|
def NextEditableZone(current_index):
|
|
|
|
|
"""
|
2025-03-27 15:16:04 +08:00
|
|
|
|
根据索引定位名称包含'permission'的书签(支持循环)
|
2025-03-26 11:09:42 +08:00
|
|
|
|
Args:
|
|
|
|
|
current_index (int/str): 从 0 开始的索引,支持字符串或整数类型
|
|
|
|
|
"""
|
|
|
|
|
# 强制转换为整数 -----------------------------
|
|
|
|
|
try:
|
|
|
|
|
current_index = int(current_index)
|
|
|
|
|
except (ValueError, TypeError):
|
2025-03-27 10:13:08 +08:00
|
|
|
|
print(f"错误:无法将 {current_index} 转换为整数")
|
2025-03-26 11:09:42 +08:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
doc = XSCRIPTCONTEXT.getDocument()
|
|
|
|
|
controller = doc.getCurrentController()
|
|
|
|
|
view_cursor = controller.getViewCursor()
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
bookmarks = doc.getBookmarks()
|
|
|
|
|
bookmark_names = bookmarks.getElementNames()
|
|
|
|
|
|
|
|
|
|
# 过滤包含permission的书签(不区分大小写)
|
|
|
|
|
permission_bookmarks = [name for name in bookmark_names if not name.startswith("_")]
|
|
|
|
|
|
2025-03-26 11:09:42 +08:00
|
|
|
|
editable_anchors = []
|
2025-03-27 15:16:04 +08:00
|
|
|
|
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
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# 无匹配书签时直接返回
|
2025-03-26 11:09:42 +08:00
|
|
|
|
if not editable_anchors:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 计算有效索引(循环逻辑)
|
|
|
|
|
total = len(editable_anchors)
|
2025-03-27 10:13:08 +08:00
|
|
|
|
effective_index = current_index % total # 自动处理越界
|
2025-03-26 11:09:42 +08:00
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
# 定位到目标书签
|
2025-03-26 11:09:42 +08:00
|
|
|
|
target_anchor = editable_anchors[effective_index]
|
|
|
|
|
|
2025-03-27 15:16:04 +08:00
|
|
|
|
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
|
2025-03-25 16:43:02 +08:00
|
|
|
|
|
|
|
|
|
|
2025-03-24 11:49:58 +08:00
|
|
|
|
g_exportedScripts = (
|
|
|
|
|
Replace,
|
|
|
|
|
ReplaceWithJSON,
|
|
|
|
|
QueryAll,
|
|
|
|
|
QueryAllWithJSON,
|
|
|
|
|
InsertRow,
|
2025-03-24 14:51:09 +08:00
|
|
|
|
InsertRowWithJSON,
|
2025-03-24 11:49:58 +08:00
|
|
|
|
DeleteRow,
|
2025-03-24 14:51:09 +08:00
|
|
|
|
DeleteRowWithJSON,
|
2025-03-25 14:14:22 +08:00
|
|
|
|
ReplaceTextAndInsertTableRow,
|
2025-03-26 11:09:42 +08:00
|
|
|
|
ReplaceBookmarksWithControls,
|
|
|
|
|
ReplaceTextAndInsertTableRowWithContentControl,
|
|
|
|
|
SaveDocument,
|
2025-03-27 10:13:08 +08:00
|
|
|
|
NextEditableZone,
|
2025-03-24 11:49:58 +08:00
|
|
|
|
)
|