From ca9bb2771c215738c5861f7be1604fe35e86d721 Mon Sep 17 00:00:00 2001 From: zzs Date: Thu, 27 Mar 2025 10:13:08 +0800 Subject: [PATCH] chore: do clear --- BookmarkOP.py | 340 +++++++++++++++++++------------------------------- 1 file changed, 125 insertions(+), 215 deletions(-) diff --git a/BookmarkOP.py b/BookmarkOP.py index 79215a9..d50d52f 100644 --- a/BookmarkOP.py +++ b/BookmarkOP.py @@ -1,32 +1,4 @@ import json -import time - -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 ReplaceAll(bookmark_obj_collection, bookmark_name_value_map): - """ - 替换所有书签 - Args: - bookmark_obj_collection: 书签对象集合 - bookmark_name_value_map: 书签名称和新值的映射 - """ - - for bookmark_name, new_value in bookmark_name_value_map.items(): - ReplaceOne(bookmark_obj_collection, bookmark_name, new_value) - def Replace(bookmark_name_value_map): """ @@ -37,7 +9,11 @@ def Replace(bookmark_name_value_map): doc = XSCRIPTCONTEXT.getDocument() bookmarks = doc.getBookmarks() - ReplaceAll(bookmarks, bookmark_name_value_map) + 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) def ReplaceWithJSON(json_str): @@ -56,7 +32,7 @@ def DebugCallReplace(): 调试调用 """ - Replace({"bb1": "P1", "bb2": "P2", "bb3": "P3", "bb4": "P4"}) + Replace({"合同编号_A": "11111", "合同名称_A": "11111"}) def DebugCallReplaceList(): @@ -66,6 +42,7 @@ def DebugCallReplaceList(): Replace({"list": "1\r2\r3\r4"}) + def QueryAll(): """ 查询所有书签,表格中的书签获取对应表格index @@ -85,27 +62,14 @@ def QueryAll(): doc = XSCRIPTCONTEXT.getDocument() bookmarks = doc.getBookmarks() bookmark_names = bookmarks.getElementNames() - filtered_bookmarks = [bk_name for bk_name in bookmark_names if not bk_name.startswith('_') 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() - # bookmark_in_table_position = QueryBookmarkPositionInTable(tables, bookmarks) - - existing_table_indices = {} - for bk_name in filtered_bookmarks: - # if bk_name in bookmark_in_table_position: - # table_index = bookmark_in_table_position[bk_name]["tableIndex"] - # if table_index in existing_table_indices: - # index = existing_table_indices[table_index] - # result["table"][index]["bookmark"].append(bk_name) - # else: - # new_entry = {"tableIndex": table_index, "bookmark": [bk_name]} - # result["table"].append(new_entry) - # existing_table_indices[table_index] = ( - # len(result["table"]) - 1 - # ) # 更新索引记录 - # else: result["text"].append(bk_name) return result @@ -114,6 +78,7 @@ def QueryAll(): def QueryAllWithJSON(): return returnWithJSON(QueryAll()) + def QueryBookmarkPositionInTable(tables, bookmarks): """ 查询书签在表格中的位置 @@ -147,29 +112,6 @@ def QueryBookmarkPositionInTable(tables, bookmarks): return bookmark_position - -def CreateRow(table, row_count): - """ - 创建表格行 - """ - table.getRows().insertByIndex(table.getRows().getCount(), row_count) - - -def FindTableIndex(table_bookmarks, location_bookmark_name): - """ - 找到表格索引 - """ - handle_table_index = -1 - for table_info in table_bookmarks: - if location_bookmark_name in table_info["bookmark"]: - handle_table_index = table_info["tableIndex"] - break - - if handle_table_index == -1: - raise ValueError(f"未找到书签 {location_bookmark_name} 对应的表格") - return handle_table_index - - def InsertRowWithJSON(json_str): """ 插入行 @@ -194,7 +136,9 @@ def InsertRow(location_bookmark_name, data, start_row_index=-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"] + handle_table_index = bookmark_in_table_position[location_bookmark_name][ + "tableIndex" + ] try: handle_table = tables.getByIndex(handle_table_index) @@ -213,27 +157,27 @@ def InsertRow(location_bookmark_name, data, start_row_index=-1): 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)}") + raise RuntimeError(f"err: {str(e)}") + def BatchInsertRowWithContentControl(data_array): """ @@ -245,13 +189,15 @@ def BatchInsertRowWithContentControl(data_array): 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 + 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"] + + handle_table_index = bookmark_in_table_position[location_bookmark_name][ + "tableIndex" + ] try: handle_table = tables.getByIndex(handle_table_index) @@ -270,32 +216,38 @@ def BatchInsertRowWithContentControl(data_array): 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)) + # === 清空单元格 === + cell_text.setString("") + # === 创建内容控件 === + content_control = doc.createInstance("com.sun.star.text.ContentControl") + + # === 插入控件到单元格 === cursor = cell_text.createTextCursor() - cell_text.insertTextContent(cursor, text_control, False) + cell_text.insertTextContent(cursor, content_control, False) + + # === 设置控件内容 === + cc_text = content_control.getText() + cc_cursor = cc_text.createTextCursor() + cc_cursor.setString(str(cell_value)) except Exception as e: @@ -314,13 +266,15 @@ def BatchInsertRow(data_array): 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 + 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"] + + handle_table_index = bookmark_in_table_position[location_bookmark_name][ + "tableIndex" + ] try: handle_table = tables.getByIndex(handle_table_index) @@ -339,50 +293,38 @@ def BatchInsertRow(data_array): 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): - """ - 插入行 - """ - - - -def DebugCallInsertRow(): - """ - 调试调用 - """ - InsertRow("t1", [["1", "2"], ["4", "5"]], 0) - - def DeleteRowWithJSON(json_str): """ 删除行 """ data = json.loads(json_str) - DeleteRow(data["location_bookmark_name"], data["start_row_index"], data["delete_row_count"]) + DeleteRow( + data["location_bookmark_name"], + data["start_row_index"], + data["delete_row_count"], + ) + def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-1): """ @@ -393,10 +335,6 @@ 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) - doc = XSCRIPTCONTEXT.getDocument() tables = doc.getTextTables() bookmarks = doc.getBookmarks() @@ -404,8 +342,9 @@ def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-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"] - + handle_table_index = bookmark_in_table_position[location_bookmark_name][ + "tableIndex" + ] handle_table = tables.getByIndex(handle_table_index) row_count = handle_table.getRows().getCount() @@ -419,15 +358,7 @@ def DeleteRow(location_bookmark_name, start_row_index, delete_row_count=-1): try: handle_table.getRows().removeByIndex(start_row_index, delete_row_count) except Exception as e: - raise RuntimeError(f"删除行时发生错误: {str(e)}") - - -def DebugCallDeleteRow(): - """ - 调试调用 - """ - DeleteRow("h1", 1, 2) - + raise RuntimeError(f"err: {str(e)}") def LocateBookmark(bookmark_name): """ @@ -438,7 +369,7 @@ def LocateBookmark(bookmark_name): doc = XSCRIPTCONTEXT.getDocument() if False == doc.getBookmarks().hasByName(bookmark_name): - return + return bookmark = doc.getBookmarks().getByName(bookmark_name) @@ -467,11 +398,6 @@ def LocateBookmark(bookmark_name): except Exception as e: raise RuntimeError(f"定位书签失败: {str(e)}") from e -def DebugCallLocateBookmarkLo1(): - LocateBookmark("lo1") - -def DebugCallLocateBookmarkLo2(): - LocateBookmark("lo2") def InsertBookmark(bookmark_name): """ @@ -481,21 +407,21 @@ def InsertBookmark(bookmark_name): """ doc = XSCRIPTCONTEXT.getDocument() controller = doc.getCurrentController() - + # 获取当前选区 selection = controller.getSelection() - + # 检查是否已存在同名书签,如果存在则先删除 bookmarks = doc.getBookmarks() if bookmarks.hasByName(bookmark_name): bookmarks.getByName(bookmark_name).dispose() - + try: # 创建书签 if selection.getCount() > 0: # 尝试获取选区的第一个元素 range_to_bookmark = selection.getByIndex(0) - + # 创建书签并附加到选区 bookmark = doc.createInstance("com.sun.star.text.Bookmark") bookmark.attach(range_to_bookmark) @@ -504,21 +430,13 @@ def InsertBookmark(bookmark_name): # 没有选中内容,创建点书签 cursor = controller.getViewCursor() text_cursor = cursor.getText().createTextCursorByRange(cursor) - + # 创建书签并附加到光标位置 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 DebugCallInsertBookmark(): - """ - 调试调用 - """ - InsertBookmark("bookmark_" + str(time.time())) def UpdateBookmark(bookmark_name, new_value): @@ -541,11 +459,6 @@ def UpdateBookmark(bookmark_name, new_value): old_bookmark = bookmarks.getByName(bookmark_name) old_bookmark.setName(new_value) -def DebugCallUpdateBookmark(): - """ - 调试调用 - """ - UpdateBookmark("ole_bookmark", "new_bookmark") def DeleteBookmark(bookmark_name): """ @@ -566,13 +479,6 @@ def DeleteBookmark(bookmark_name): except Exception as e: pass -def DebugCallDeleteBookmark(): - """ - 调试调用 - """ - DeleteBookmark("remove_me") - - def CreateTable(location_bookmark_name, data): """ 创建表格 @@ -581,6 +487,7 @@ def CreateTable(location_bookmark_name, data): data: 二维数组,用于填充表格数据 """ + def ReplaceTextAndInsertTableRow(json_str): """ 替换文本和表格 @@ -589,23 +496,27 @@ def ReplaceTextAndInsertTableRow(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 @@ -613,6 +524,7 @@ def SaveDocument(): print("err:", e) return False + def DebugCallReplaceBookmarksWithControls(): ReplaceBookmarksWithControls({"合同编号_A": "11111", "合同名称_A": "22222"}) @@ -621,39 +533,45 @@ 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() + for i in reversed(range(bookmarks.getCount())): + bookmark = bookmarks.getByIndex(i) + name = bookmark.getName() + anchor = bookmark.getAnchor() + if not anchor: + continue + + 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) - # 获取书签内容 - cursor = anchor.getText().createTextCursorByRange(anchor) - original_text = cursor.getString() + # === 第1步:清理旧书签 === + bookmark.dispose() - # 创建文本控件并设置内容 - 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) + # === 第2步:创建新书签 === + # 获取控件实际范围 + cc_anchor = content_control.getText().getAnchor() - # 替换原书签内容为控件 - 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)}") + new_bookmark = doc.createInstance("com.sun.star.text.Bookmark") + new_bookmark.setName(name) + new_bookmark.attach(cc_anchor) def NextEditableZone(current_index): """ - 根据索引定位可编辑区域(支持循环) + 根据索引定位可编辑的内容控件(支持循环) Args: current_index (int/str): 从 0 开始的索引,支持字符串或整数类型 """ @@ -661,40 +579,39 @@ def NextEditableZone(current_index): try: current_index = int(current_index) except (ValueError, TypeError): - print(f"err {current_index} cant convert to int") + print(f"错误:无法将 {current_index} 转换为整数") return doc = XSCRIPTCONTEXT.getDocument() controller = doc.getCurrentController() view_cursor = controller.getViewCursor() - # 收集所有可编辑控件的锚点 - text_fields = doc.getTextFields().createEnumeration() + # 收集所有内容控件的锚点 + text_content = doc.getText().createEnumeration() editable_anchors = [] - while text_fields.hasMoreElements(): - field = text_fields.nextElement() - if field.supportsService("com.sun.star.text.TextField.Input"): + while text_content.hasMoreElements(): + element = text_content.nextElement() + # 关键修改点:检查内容控件服务 + if element.supportsService("com.sun.star.text.ContentControl"): try: - anchor = field.getAnchor() + anchor = element.getAnchor() editable_anchors.append(anchor) except Exception: continue # 无控件时直接返回 if not editable_anchors: - print("文档中无可编辑控件") + print("文档中未找到内容控件") return # 计算有效索引(循环逻辑) total = len(editable_anchors) - effective_index = current_index % total # 此处不再报错 + effective_index = current_index % total # 自动处理越界 # 定位到目标控件 target_anchor = editable_anchors[effective_index] - view_cursor.gotoRange(target_anchor, False) - controller.select(target_anchor) # 选中控件(可选) - - + view_cursor.gotoRange(target_anchor.getStart(), False) # 跳转到控件起始位置 + controller.select(target_anchor) # 选中整个控件范围 @@ -710,16 +627,9 @@ g_exportedScripts = ( ReplaceTextAndInsertTableRow, DebugCallReplace, DebugCallReplaceList, - DebugCallInsertRow, - DebugCallDeleteRow, - DebugCallLocateBookmarkLo1, - DebugCallLocateBookmarkLo2, - DebugCallInsertBookmark, - DebugCallUpdateBookmark, - DebugCallDeleteBookmark, ReplaceBookmarksWithControls, ReplaceTextAndInsertTableRowWithContentControl, DebugCallReplaceBookmarksWithControls, SaveDocument, - NextEditableZone + NextEditableZone, )