You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python替换.odt文件字符串并导出新文件?

ODT文件文本替换并导出的Python实现方案

需求说明

非当前工作目录下存在myfile.odt文件,需要将其中的字符串astring替换为anewstring,并将修改后的文件导出到当前目录(生成新的ODT文件)。

已尝试方法及问题

  • 直接将ODT作为普通文本文件读写:生成的文件损坏无法打开,尝试脚本如下:
f1 = open('test.odt', 'r', encoding='latin') 
f2 = open('newfile.odt', 'w') 
for line in f1: 
    f2.write(line.replace('mystring', 'newstring')) 
f1.close() 
f2.close()
  • 使用xml.etree但因不熟悉XML操作,遇到诸多理解和实现问题
  • 尝试过其他解决方案及ChatGPT建议均无效
  • 无法使用odfpy库

可行实现方案(基于xml.etree与zipfile)

ODT本质是压缩包,核心文本内容存储在包内的content.xml文件中。以下是完整实现步骤:

代码实现

import os
import zipfile
import xml.etree.ElementTree as ET
from tempfile import TemporaryDirectory

# 配置参数
source_odt_path = "/path/to/your/myfile.odt"  # 替换为实际的非当前目录下的myfile.odt路径
target_odt_name = "modified_myfile.odt"       # 当前目录生成的新文件名
old_str = "astring"
new_str = "anewstring"

# ODT XML的命名空间,必须指定才能正确解析标签
namespaces = {
    'text': 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'
}

# 创建临时目录用于解压ODT文件
with TemporaryDirectory() as temp_dir:
    # 解压源ODT文件到临时目录
    with zipfile.ZipFile(source_odt_path, 'r') as zip_ref:
        zip_ref.extractall(temp_dir)
    
    # 读取并修改content.xml
    content_path = os.path.join(temp_dir, 'content.xml')
    tree = ET.parse(content_path)
    root = tree.getroot()
    
    # 遍历所有普通段落文本节点,替换目标字符串
    for elem in root.findall('.//text:p', namespaces):
        if elem.text and old_str in elem.text:
            elem.text = elem.text.replace(old_str, new_str)
    # 遍历带格式的文本片段节点,替换目标字符串
    for elem in root.findall('.//text:span', namespaces):
        if elem.text and old_str in elem.text:
            elem.text = elem.text.replace(old_str, new_str)
    
    # 保存修改后的content.xml
    tree.write(content_path, encoding='UTF-8', xml_declaration=True)
    
    # 重新打包成新的ODT文件
    with zipfile.ZipFile(target_odt_name, 'w', zipfile.ZIP_DEFLATED) as zip_out:
        # 遍历临时目录下的所有文件,按原结构添加到压缩包
        for foldername, subfolders, filenames in os.walk(temp_dir):
            for filename in filenames:
                file_path = os.path.join(foldername, filename)
                # 计算压缩包内的相对路径,保证ODT结构合法
                arcname = os.path.relpath(file_path, temp_dir)
                zip_out.write(file_path, arcname)

print(f"修改完成,新文件已保存到当前目录:{target_odt_name}")

关键说明

  1. 命名空间处理:ODT的XML使用特定命名空间,必须在findall中指定namespaces参数才能正确定位文本标签(如text:p对应段落,text:span对应带格式的文本片段)
  2. 临时目录:使用TemporaryDirectory自动处理临时文件的创建与清理,避免手动管理文件残留
  3. 压缩包操作:严格按照ODT的原始压缩结构重新打包,确保生成的文件格式合法可正常打开
  4. 文本节点遍历:覆盖普通段落和带格式文本片段,确保所有目标字符串都被替换

内容的提问来源于stack exchange,提问作者Michael Gauthier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:37:28