Python操作Word方法大全

直接上代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2025/5/7 9:37
# @Author  : BeiMo
# @File    : 操作Word.py
# @Software: PyCharm


from docx import Document
from docx.shared import Inches
import re
from docx.oxml.ns import qn


# 创建一个新的 Word 文档
def create_new_document():
    return Document()


# 打开一个现有的 Word 文档
# :param file_path: 要打开的 Word 文档的文件路径
# :return: 如果成功打开文档,返回文档对象;如果出现错误,打印错误信息并返回 None
def open_existing_document(file_path):
    try:
        return Document(file_path)
    except Exception as e:
        print(f"打开文档时出错: {e}")
        return None


# 向文档中添加一个标题
# :param doc: 要添加标题的文档对象
# :param title_text: 标题的文本内容
# :param level: 标题的级别,默认为 1 级标题
# :return: 添加标题后的文档对象
def add_title(doc, title_text, level=1):
    doc.add_heading(title_text, level=level)
    return doc


# 从文档中删除指定标题
# :param doc: 要删除标题的文档对象
# :param title_text: 要删除的标题的文本内容
# :return: 删除标题后的文档对象
def delete_title(doc, title_text):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落是否为标题,并且标题文本是否匹配
        if paragraph.style.name.startswith('Heading') and paragraph.text == title_text:
            p = paragraph._element
            p.getparent().remove(p)
            p._element = None
    return doc


# 更新文档中指定标题的文本内容
# :param doc: 要更新标题的文档对象
# :param old_title: 要更新的旧标题文本内容
# :param new_title: 新的标题文本内容
# :return: 更新标题后的文档对象
def update_title(doc, old_title, new_title):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落是否为标题,并且标题文本是否匹配旧标题
        if paragraph.style.name.startswith('Heading') and paragraph.text == old_title:
            paragraph.text = new_title
    return doc


# 在文档中查找指定标题
# :param doc: 要查找标题的文档对象
# :param title_text: 要查找的标题的文本内容
# :return: 如果找到标题,返回标题段落对象;如果未找到,返回 None
def find_title(doc, title_text):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落是否为标题,并且标题文本是否匹配
        if paragraph.style.name.startswith('Heading') and paragraph.text == title_text:
            return paragraph
    return None


# 向文档中添加一个段落
# :param doc: 要添加段落的文档对象
# :param paragraph_text: 段落的文本内容
# :return: 添加段落后的文档对象
def add_paragraph(doc, paragraph_text):
    doc.add_paragraph(paragraph_text)
    return doc


# 从文档中删除指定段落
# :param doc: 要删除段落的文档对象
# :param paragraph_text: 要删除的段落的文本内容
# :return: 删除段落后的文档对象
def delete_paragraph(doc, paragraph_text):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落文本是否匹配要删除的段落文本
        if paragraph.text == paragraph_text:
            p = paragraph._element
            p.getparent().remove(p)
            p._element = None
    return doc


# 更新文档中指定段落的文本内容
# :param doc: 要更新段落的文档对象
# :param old_paragraph: 要更新的旧段落文本内容
# :param new_paragraph: 新的段落文本内容
# :return: 更新段落后的文档对象
def update_paragraph(doc, old_paragraph, new_paragraph):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落文本是否匹配旧段落文本
        if paragraph.text == old_paragraph:
            paragraph.text = new_paragraph
    return doc


# 在文档中查找指定段落
# :param doc: 要查找段落的文档对象
# :param paragraph_text: 要查找的段落的文本内容
# :return: 如果找到段落,返回段落对象;如果未找到,返回 None
def find_paragraph(doc, paragraph_text):
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 检查段落文本是否匹配要查找的段落文本
        if paragraph.text == paragraph_text:
            return paragraph
    return None


# 替换文档中所有 {{}} 包含的指定内容
# :param doc: 要进行内容替换的文档对象
# :param placeholder_text: 要替换的占位符文本内容
# :param replacement_text: 替换后的文本内容
# :return: 替换内容后的文档对象
def replace_content(doc, placeholder_text, replacement_text):
    pattern = re.compile(rf'\{{{{{placeholder_text}}}}}')
    # 遍历文档中的每个段落
    for paragraph in doc.paragraphs:
        # 遍历段落中的每个运行对象
        for run in paragraph.runs:
            run.text = pattern.sub(replacement_text, run.text)
    # 遍历文档中的每个表格
    for table in doc.tables:
        # 遍历表格中的每一行
        for row in table.rows:
            # 遍历行中的每个单元格
            for cell in row.cells:
                # 遍历单元格中的每个段落
                for paragraph in cell.paragraphs:
                    # 遍历段落中的每个运行对象
                    for run in paragraph.runs:
                        run.text = pattern.sub(replacement_text, run.text)
    return doc


# 获取文档中所有的表格
# :param doc: 要获取表格的文档对象
# :return: 包含文档中所有表格的列表
def get_all_tables(doc):
    return doc.tables


# 复制文档中指定索引的表格
# :param doc: 要复制表格的文档对象
# :param table_index: 要复制的表格的索引
# :return: 复制表格后的文档对象
def copy_table(doc, table_index):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        original_table = tables[table_index]
        new_table = doc.add_table(rows=len(original_table.rows), cols=len(original_table.columns))
        # 遍历原表格的每一行
        for i, row in enumerate(original_table.rows):
            # 遍历行中的每个单元格
            for j, cell in enumerate(row.cells):
                new_table.cell(i, j).text = cell.text
    return doc


# 更新文档中指定表格的指定单元格的文本内容
# :param doc: 要更新单元格文本的文档对象
# :param table_index: 要更新的表格的索引
# :param row_index: 要更新的单元格所在的行索引
# :param col_index: 要更新的单元格所在的列索引
# :param new_text: 新的单元格文本内容
# :return: 更新单元格文本后的文档对象
def update_table_cell_text(doc, table_index, row_index, col_index, new_text):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查行索引和列索引是否在有效范围内
        if row_index < len(table.rows) and col_index < len(table.columns):
            table.cell(row_index, col_index).text = new_text
    return doc


# 向文档中指定表格的指定单元格添加图片
# :param doc: 要添加图片的文档对象
# :param table_index: 要添加图片的表格的索引
# :param row_index: 要添加图片的单元格所在的行索引
# :param col_index: 要添加图片的单元格所在的列索引
# :param image_path: 图片的文件路径
# :return: 添加图片后的文档对象
def add_image_to_table_cell(doc, table_index, row_index, col_index, image_path):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查行索引和列索引是否在有效范围内
        if row_index < len(table.rows) and col_index < len(table.columns):
            cell = table.cell(row_index, col_index)
            paragraph = cell.paragraphs[0]
            run = paragraph.add_run()
            run.add_picture(image_path, width=Inches(2))
    return doc


# 删除文档中指定表格的指定单元格的内容
# :param doc: 要删除单元格内容的文档对象
# :param table_index: 要删除单元格内容的表格的索引
# :param row_index: 要删除内容的单元格所在的行索引
# :param col_index: 要删除内容的单元格所在的列索引
# :return: 删除单元格内容后的文档对象
def delete_table_cell_content(doc, table_index, row_index, col_index):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查行索引和列索引是否在有效范围内
        if row_index < len(table.rows) and col_index < len(table.columns):
            cell = table.cell(row_index, col_index)
            # 遍历单元格中的每个段落
            for paragraph in cell.paragraphs:
                p = paragraph._element
                p.getparent().remove(p)
                p._element = None
    return doc


# 合并文档中指定表格的指定单元格范围
# :param doc: 要合并单元格的文档对象
# :param table_index: 要合并单元格的表格的索引
# :param start_row: 合并范围的起始行索引
# :param start_col: 合并范围的起始列索引
# :param end_row: 合并范围的结束行索引
# :param end_col: 合并范围的结束列索引
# :return: 合并单元格后的文档对象
def merge_table_cells(doc, table_index, start_row, start_col, end_row, end_col):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查起始行、结束行、起始列和结束列是否在有效范围内
        if start_row < len(table.rows) and end_row < len(table.rows) and start_col < len(
                table.columns) and end_col < len(table.columns):
            table.cell(start_row, start_col).merge(table.cell(end_row, end_col))
    return doc


# 拆分文档中指定表格的指定单元格
# :param doc: 要拆分单元格的文档对象
# :param table_index: 要拆分单元格的表格的索引
# :param row_index: 要拆分的单元格所在的行索引
# :param col_index: 要拆分的单元格所在的列索引
# :param num_rows: 拆分后的行数
# :param num_cols: 拆分后的列数
# :return: 拆分单元格后的文档对象
def split_table_cell(doc, table_index, row_index, col_index, num_rows, num_cols):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查行索引和列索引是否在有效范围内
        if row_index < len(table.rows) and col_index < len(table.columns):
            cell = table.cell(row_index, col_index)
            tc = cell._element
            # 拆分单元格
            for i in range(num_rows - 1):
                new_tc = tc.makeelement(qn('w:tc'))
                tc.addnext(new_tc)
            for j in range(num_cols - 1):
                for i in range(num_rows):
                    new_tc = tc.makeelement(qn('w:tc'))
                    tc.addnext(new_tc)
    return doc


# 对文档中指定表格的指定列进行排序
# :param doc: 要排序表格的文档对象
# :param table_index: 要排序的表格的索引
# :param column_index: 要排序的列的索引
# :param ascending: 是否按升序排序,默认为 True
# :return: 排序表格后的文档对象
def sort_table(doc, table_index, column_index, ascending=True):
    tables = doc.tables
    # 检查表格索引是否在有效范围内
    if table_index < len(tables):
        table = tables[table_index]
        # 检查表格是否有数据
        if len(table.rows) == 0:
            return doc
        # 检查列索引是否在有效范围内
        if column_index >= len(table.columns):
            print(f"列索引 {column_index} 超出范围,表格只有 {len(table.columns)} 列。")
            return doc
        # 提取表格数据
        data = []
        # 遍历表格的每一行
        for row in table.rows:
            row_data = [cell.text for cell in row.cells]
            data.append(row_data)
        # 对数据进行排序
        header = data[0]  # 假设第一行是表头
        body = data[1:]
        sorted_body = sorted(body, key=lambda x: x[column_index], reverse=not ascending)
        # 清空原表格内容
        for i in range(len(table.rows)):
            for j in range(len(table.columns)):
                cell = table.cell(i, j)
                p = cell.paragraphs[0]
                p.clear()
        # 将排序后的数据写回表格
        for i, row_data in enumerate([header] + sorted_body):
            for j, cell_text in enumerate(row_data):
                table.cell(i, j).text = cell_text
    return doc


if __name__ == "__main__":
    # 新建文档
    doc = create_new_document()

    # 添加标题
    doc = add_title(doc, "测试标题", level=1)

    # 添加段落
    doc = add_paragraph(doc, "这是一个测试段落。")

    # 替换内容
    doc = replace_content(doc, "MissionNumber", "QTYM-ZJ/ST-2024-003")

    # 添加表格
    table = doc.add_table(rows=3, cols=2)
    table.cell(0, 0).text = "姓名"
    table.cell(0, 1).text = "年龄"
    table.cell(1, 0).text = "张三"
    table.cell(1, 1).text = "25"
    table.cell(2, 0).text = "李四"
    table.cell(2, 1).text = "20"

    # 复制表格
    doc = copy_table(doc, 0)

    # 更新表格单元格文本
    doc = update_table_cell_text(doc, 0, 0, 0, "新的单元格内容")

    # 合并单元格
    doc = merge_table_cells(doc, 0, 0, 0, 0, 1)

    # 拆分单元格
    doc = split_table_cell(doc, 0, 0, 0, 2, 2)

    # 对表格进行排序
    # doc = sort_table(doc, 0, 1, ascending=True)

    # 保存文档
    doc.save("test.docx")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值