From e12f34ed5d114175a4a4b251631e568bd3dca9d5 Mon Sep 17 00:00:00 2001 From: Shuming Liu Date: Fri, 3 Apr 2026 10:43:11 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/file_association.py | 68 ++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/server/file_association.py b/server/file_association.py index 89371b8..b838700 100644 --- a/server/file_association.py +++ b/server/file_association.py @@ -112,17 +112,47 @@ def read_word_content(doc_path: Path) -> List[str]: def read_docx_content(doc_path: Path) -> List[str]: """读取 .docx 格式 Word 文档内容""" - lines = [] try: with zipfile.ZipFile(doc_path, 'r') as z: content = z.read('word/document.xml').decode('utf-8') + # 提取所有 ... 中的内容,保留原始空白字符 texts = re.findall(r']*>(.*?)', content, re.DOTALL) + + # 去除 HTML 标签,不替换内部的空白字符 + processed = [] for text in texts: text = re.sub(r'<[^>]+>', '', text).strip() - text = re.sub(r'\s+', ' ', text) if text: - lines.append(text) - return lines + processed.append(text) + + # 拼接所有文本,保留 \t 和 \n + full_text = '\n'.join(processed) + + # 智能检测:判断是使用 \t 分割 6 段,还是每行一个字段 + lines = full_text.split('\n') + lines = [line.strip() for line in lines if line.strip()] + + # 检测是否每行都是单字段(没有\t) + # 如果前几行都没有\t,可能是每行一个字段 + has_tab_in_first_rows = any('\t' in line for line in lines[:6]) + + if not has_tab_in_first_rows and len(lines) >= 6: + # 可能是每行一个字段,尝试合并为 6 段 + result = [] + i = 0 + while i < len(lines): + if i + 5 <= len(lines): + # 尝试合并接下来的 6 行作为一段 + combined = '\t'.join(lines[i:i+6]) + result.append(combined) + i += 6 + else: + result.append(lines[i]) + i += 1 + return result + else: + # 每行已经有\t分割,直接返回 + return lines except Exception as e: print(f"读取 .docx 失败 ({doc_path.name}): {e}") return [] @@ -422,15 +452,33 @@ def main(): clear_directory(extract_dir) try: - # 解压 + # 先提取所有文件 + with zipfile.ZipFile(zip_file, 'r') as zip_ref: + zip_ref.extractall(data_dir) + + # 然后遍历所有成员,设置时间戳 with zipfile.ZipFile(zip_file, 'r') as zip_ref: for member in zip_ref.infolist(): - zip_ref.extract(member, data_dir) - member_path = data_dir / zip_file.stem / member.filename + # 构建正确的文件路径 - 先获取解压后的实际路径 + base_extract_path = data_dir / zip_file.stem + if member.filename.startswith(zip_file.stem + '/'): + # 文件路径包含 zip 文件名前缀 + member_path = base_extract_path / member.filename[len(zip_file.stem) + 1:] + elif member.filename.startswith(zip_file.stem): + # 文件路径直接以 zip 文件名开头 + member_path = base_extract_path / member.filename[len(zip_file.stem):].lstrip('/') + else: + # 文件路径不包含前缀 + member_path = base_extract_path / member.filename + + # 如果路径存在,设置时间戳 if member_path.exists(): - date_time = datetime(*member.date_time[:5]) - timestamp = date_time.timestamp() - os.utime(member_path, (timestamp, timestamp)) + try: + date_time = datetime(*member.date_time[:5]) + timestamp = date_time.timestamp() + os.utime(member_path, (timestamp, timestamp)) + except Exception: + pass # 检查是否多了一层目录 inner_dir = extract_dir / zip_file.stem