Read KDocs cells via clipboard

This commit is contained in:
2026-01-07 17:40:29 +08:00
parent a36fa3370b
commit 5fd13fa152

View File

@@ -202,6 +202,7 @@ class KDocsUploader:
def _open_document(self, doc_url: str, *, fast: bool = False) -> bool:
try:
self._doc_url = doc_url
self._ensure_clipboard_permissions(doc_url)
if fast:
doc_pages = self._find_doc_pages(doc_url)
if doc_pages:
@@ -232,6 +233,18 @@ class KDocsUploader:
self._last_error = f"打开文档失败: {e}"
return False
def _ensure_clipboard_permissions(self, doc_url: str) -> None:
if not self._context or not doc_url:
return
try:
parsed = urlparse(doc_url)
if not parsed.scheme or not parsed.netloc:
return
origin = f"{parsed.scheme}://{parsed.netloc}"
self._context.grant_permissions(["clipboard-read", "clipboard-write"], origin=origin)
except Exception:
return
def _normalize_doc_url(self, url: str) -> str:
if not url:
return ""
@@ -953,38 +966,70 @@ class KDocsUploader:
continue
def _get_current_cell_address(self) -> str:
try:
name_box = self._page.locator("input.edit-box").first
return name_box.input_value()
except Exception:
name_box = self._page.locator('#root input[type="text"]').first
return name_box.input_value()
def _navigate_to_cell(self, cell_address: str) -> None:
try:
name_box = self._page.locator("input.edit-box").first
name_box.click()
name_box.fill(cell_address)
name_box.press("Enter")
except Exception:
name_box = self._page.locator('#root input[type="text"]').first
name_box.click()
name_box.fill(cell_address)
name_box.press("Enter")
time.sleep(0.3)
def _focus_grid(self) -> None:
try:
info = self._page.evaluate(
"""() => {
const canvases = Array.from(document.querySelectorAll("canvas"));
let best = null;
for (const c of canvases) {
const rect = c.getBoundingClientRect();
if (!rect.width || !rect.height) continue;
if (rect.width < 200 || rect.height < 200) continue;
const area = rect.width * rect.height;
if (!best || area > best.area) {
best = {x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, area};
}
}
return best;
}"""
)
if info and info.get("x") and info.get("y"):
self._page.mouse.click(info["x"], info["y"])
time.sleep(0.1)
except Exception:
pass
def _read_clipboard_text(self) -> str:
try:
return self._page.evaluate("() => navigator.clipboard.readText()") or ""
except Exception:
return ""
def _get_cell_value(self, cell_address: str) -> str:
self._navigate_to_cell(cell_address)
time.sleep(0.3)
try:
formula_bar = self._page.locator('input[type="text"]').nth(1)
value = formula_bar.input_value()
if value:
return value.strip()
self._page.evaluate("() => navigator.clipboard.writeText('')")
except Exception:
pass
self._focus_grid()
try:
formula_inputs = self._page.locator('textbox')
for i in range(formula_inputs.count()):
try:
value = formula_inputs.nth(i).input_value()
self._page.keyboard.press("Control+c")
time.sleep(0.2)
value = self._read_clipboard_text()
if value:
import re
if not re.match(r"^[A-Z]+\d+$", value.strip()):
return value.strip()
except Exception:
continue
except Exception:
pass
return ""
@@ -1020,6 +1065,7 @@ class KDocsUploader:
return True
def _search_person(self, name: str) -> None:
self._focus_grid()
self._page.keyboard.press("Control+f")
time.sleep(0.3)
search_input = None