Compare commits

...

4 Commits

Author SHA1 Message Date
zzs
9852d06e15 feat: replace with control 2025-03-26 11:09:42 +08:00
zzs
8e896cf683 feat: add save doc func 2025-03-25 16:43:02 +08:00
zzs
9d4df1df84 feat: replace bookmark and insert table row 2025-03-25 14:14:22 +08:00
zzs
ad1506790b fix: cant find bookmark 2025-03-25 10:33:49 +08:00

View File

@ -56,7 +56,7 @@ def DebugCallReplace():
调试调用
"""
Replace({"h1": "P1", "h2": "P2", "h3": "P3"})
Replace({"bb1": "P1", "bb2": "P2", "bb3": "P3", "bb4": "P4"})
def DebugCallReplaceList():
@ -85,7 +85,7 @@ def QueryAll():
doc = XSCRIPTCONTEXT.getDocument()
bookmarks = doc.getBookmarks()
bookmark_names = bookmarks.getElementNames()
filtered_bookmarks = [bk_name for bk_name in bookmark_names if '_' not in bk_name and ':' not in bk_name]
filtered_bookmarks = [bk_name for bk_name in bookmark_names if not bk_name.startswith('_') and ':' not in bk_name]
result = {"text": [], "table": []}
# tables = doc.getTextTables()
@ -186,13 +186,15 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1):
data: 二维数组用于填充表格数据
start_row_index: 起始行位置默认为-1即在表格末尾插入
"""
bookmark_info = QueryAll()
table_bookmarks = bookmark_info["table"]
handle_table_index = FindTableIndex(table_bookmarks, location_bookmark_name)
doc = XSCRIPTCONTEXT.getDocument()
tables = doc.getTextTables()
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} 对应的表格")
handle_table_index = bookmark_in_table_position[location_bookmark_name]["tableIndex"]
try:
handle_table = tables.getByIndex(handle_table_index)
@ -209,19 +211,6 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1):
raise ValueError(f"数据列数不匹配,表格有 {col_count}")
try:
# for _ in range(len(data)):
# if start_row_index > 0 & start_row_index < row_count:
# handle_table.getRows().insertByIndex(start_row_index, 1)
# else:
# handle_table.getRows().insertByIndex(row_count, 1)
# for row_idx, row_data in enumerate(data, start=row_count):
# for col_idx, cell_value in enumerate(row_data):
# cell = handle_table.getCellByPosition(col_idx, row_idx)
# cell.setString(str(cell_value))
# 获取需要插入的行数
# 获取表格当前总行数
row_count = handle_table.getRows().getCount()
rows_to_insert = len(data)
@ -246,6 +235,133 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1):
except Exception as e:
raise RuntimeError(f"插入行时发生错误: {str(e)}")
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:
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
if location_bookmark_name not in bookmark_in_table_position:
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
handle_table_index = bookmark_in_table_position[location_bookmark_name]["tableIndex"]
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)
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 # 插入到表格末尾
# 批量插入所有新行
handle_table.getRows().insertByIndex(insert_pos, rows_to_insert)
# 填充数据到新插入的行
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))
# 创建文本控件并赋值 -----------------------------
cell_text = cell.getText()
cell_text.setString("") # 清空原有内容
text_control = doc.createInstance("com.sun.star.text.TextField.Input")
text_control.setPropertyValue("Content", str(cell_value))
cursor = cell_text.createTextCursor()
cell_text.insertTextContent(cursor, text_control, False)
except Exception as e:
raise RuntimeError(f"插入行时发生错误: {str(e)}")
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:
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
if location_bookmark_name not in bookmark_in_table_position:
raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格")
handle_table_index = bookmark_in_table_position[location_bookmark_name]["tableIndex"]
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)
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 # 插入到表格末尾
# 批量插入所有新行
handle_table.getRows().insertByIndex(insert_pos, rows_to_insert)
# 填充数据到新插入的行
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))
except Exception as e:
raise RuntimeError(f"插入行时发生错误: {str(e)}")
def InsertRowWithJSONDefineCol(json_str):
"""
@ -258,7 +374,7 @@ def DebugCallInsertRow():
"""
调试调用
"""
InsertRow("h1", [["1", "2", "3"], ["4", "5", "6"]], 0)
InsertRow("t1", [["1", "2"], ["4", "5"]], 0)
def DeleteRowWithJSON(json_str):
@ -277,12 +393,20 @@ def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-1):
start_row_index: 起始行位置(删除行包含本行)
delete_row_count: 删除的行数
"""
bookmark_info = QueryAll()
table_bookmarks = bookmark_info["table"]
handle_table_index = FindTableIndex(table_bookmarks, location_bookmark_name)
# bookmark_info = QueryAll()
# table_bookmarks = bookmark_info["table"]
# handle_table_index = FindTableIndex(table_bookmarks, location_bookmark_name)
doc = XSCRIPTCONTEXT.getDocument()
tables = doc.getTextTables()
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} 对应的表格")
handle_table_index = bookmark_in_table_position[location_bookmark_name]["tableIndex"]
handle_table = tables.getByIndex(handle_table_index)
row_count = handle_table.getRows().getCount()
if start_row_index < 0 or start_row_index >= row_count:
@ -457,9 +581,123 @@ def CreateTable(location_bookmark_name, data):
data: 二维数组用于填充表格数据
"""
def ReplaceTextAndInsertTableRow(json_str):
"""
替换文本和表格
"""
data = json.loads(json_str)
Replace(data["text"])
BatchInsertRow(data["table"])
def ReplaceTextAndInsertTableRowWithContentControl(json_str):
data = json.loads(json_str)
ReplaceBookmarksWithControls(data["text"])
BatchInsertRowWithContentControl(data["table"])
def returnWithJSON(data):
return json.dumps(data, ensure_ascii=False)
def SaveDocument():
# 获取当前文档对象
model = XSCRIPTCONTEXT.getDocument()
try:
# 检查文档是否支持保存XStorable 接口)
from com.sun.star.frame import XStorable
xstorable = model.uno_getAdapter(XStorable)
# 调用保存方法(覆盖原文件)
xstorable.store()
return True
except Exception as e:
print("err:", e)
return False
def DebugCallReplaceBookmarksWithControls():
ReplaceBookmarksWithControls({"合同编号_A": "11111", "合同名称_A": "22222"})
def ReplaceBookmarksWithControls(bookmark_name_value_map={}):
doc = XSCRIPTCONTEXT.getDocument()
bookmarks = doc.getBookmarks()
for name in reversed([bm.getName() for bm in bookmarks]):
try:
if name.startswith('_'):
continue
bookmark = bookmarks.getByName(name)
anchor = bookmark.getAnchor()
# 获取书签内容
cursor = anchor.getText().createTextCursorByRange(anchor)
original_text = cursor.getString()
# 创建文本控件并设置内容
text_control = doc.createInstance("com.sun.star.text.TextField.Input")
if (bookmark_name_value_map.get(name)):
text_control.setPropertyValue("Content", bookmark_name_value_map.get(name))
else
text_control.setPropertyValue("Content", original_text)
# 替换原书签内容为控件
cursor.setString("")
anchor.getText().insertTextContent(cursor, text_control, False)
# 重新插入原书签到控件后
new_cursor = cursor.getText().createTextCursorByRange(cursor)
new_cursor.goRight(1, False)
doc.getBookmarks().addNew(name, new_cursor)
except Exception as e:
print(f"error{str(e)}")
def NextEditableZone(current_index):
"""
根据索引定位可编辑区域支持循环
Args:
current_index (int/str): 0 开始的索引支持字符串或整数类型
"""
# 强制转换为整数 -----------------------------
try:
current_index = int(current_index)
except (ValueError, TypeError):
print(f"err {current_index} cant convert to int")
return
doc = XSCRIPTCONTEXT.getDocument()
controller = doc.getCurrentController()
view_cursor = controller.getViewCursor()
# 收集所有可编辑控件的锚点
text_fields = doc.getTextFields().createEnumeration()
editable_anchors = []
while text_fields.hasMoreElements():
field = text_fields.nextElement()
if field.supportsService("com.sun.star.text.TextField.Input"):
try:
anchor = field.getAnchor()
editable_anchors.append(anchor)
except Exception:
continue
# 无控件时直接返回
if not editable_anchors:
print("文档中无可编辑控件")
return
# 计算有效索引(循环逻辑)
total = len(editable_anchors)
effective_index = current_index % total # 此处不再报错
# 定位到目标控件
target_anchor = editable_anchors[effective_index]
view_cursor.gotoRange(target_anchor, False)
controller.select(target_anchor) # 选中控件(可选)
g_exportedScripts = (
Replace,
ReplaceWithJSON,
@ -469,6 +707,7 @@ g_exportedScripts = (
InsertRowWithJSON,
DeleteRow,
DeleteRowWithJSON,
ReplaceTextAndInsertTableRow,
DebugCallReplace,
DebugCallReplaceList,
DebugCallInsertRow,
@ -477,5 +716,10 @@ g_exportedScripts = (
DebugCallLocateBookmarkLo2,
DebugCallInsertBookmark,
DebugCallUpdateBookmark,
DebugCallDeleteBookmark
DebugCallDeleteBookmark,
ReplaceBookmarksWithControls,
ReplaceTextAndInsertTableRowWithContentControl,
DebugCallReplaceBookmarksWithControls,
SaveDocument,
NextEditableZone
)