【办公类-89-02】20250424会议记录模版WORD自动添加空格补全下划线

news2025/4/26 1:43:17

背景需求

4月23日听了一个MJB的征文培训,需要写会议记录

把资料黏贴到模版后,发现每行需要有画满下划线

 原来做这套资料,就是手动按空格到一行末,有空格才会出现下划线,也就是要按很多的空格(凑满一行)

或者一行行的复制复制,因为文字有长短,所以后面的空格也有长有短

需求:

Python批量自动给最后添加适合的空格数,自动实现没有文字,但有空格,有下划线

第1问

代码展示

from docx import Document


def add_solid_underline_with_spaces(doc_path, output_path, target_length=29):
    """
    为Word文档每段添加实线下划线,并用全角空格填充至指定长度
    (仅对每段最后一行末尾添加空格和下划线)
    
    参数:
        doc_path (str): 输入文档路径
        output_path (str): 输出文档路径
        target_length (int): 目标字符宽度(中文算2,英文算1)
    """
    # 加载文档
    doc = Document(doc_path)
    
    for paragraph in doc.paragraphs:
        if paragraph.text.strip():  # 只处理非空段落
            # 获取段落的最后一行
            lines = paragraph.text.split('\n')
            last_line = lines[-1] if lines else ""
            
            # 计算最后一行的字符宽度
            current_width = sum(2 if ord(c) > 127 else 1 for c in last_line)
            
            # 计算需要填充的全角空格数
            fill_count = max(0, target_length - current_width)

            # 计算需要填充的全角空格数
            fill_count = max(0, target_length - current_width)
            
            # print(f"段落内容: '{text}'")
            print(f"当前宽度: {current_width}, 需要填充空格数: {fill_count}\n")
            
            # 为原有内容添加实线下划线
            for run in paragraph.runs:
                run.font.underline = True  # 设置为单实线
            
            # 仅在最后添加全角空格并带下划线
            if fill_count > 0:
                # 清除原有换行符(如果有)
                if paragraph.runs and paragraph.runs[-1].text.endswith('\n'):
                    paragraph.runs[-1].text = paragraph.runs[-1].text.rstrip('\n')
                
                fill_run = paragraph.add_run("\u3000"  * fill_count)  # 使用全角空格
                fill_run.font.underline = True
                
                # 恢复原有换行符(如果有)
                if len(lines) > 1:
                    paragraph.add_run().add_break()

    # 保存文档
    doc.save(output_path)

# 使用示例
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\工具运用'
input_path = path + r'\附件1工具运用训会议记录(2025.4.23).docx'
output_path = path + r'\附件1工具运用训会议记录(2025.4.23)_实线下划线.docx'
add_solid_underline_with_spaces(input_path, output_path, target_length=29)

出现很多的方块

把全角改成空格

结果方块没有了,但是下划线不够长,

 分析:预设29个空格位置,已有字符超过29个,就不添加空格了

所以把预设空格数改到最大1000

运行后,都有空格了

结果显示

但是里面有大量的空格,会不会占空间?

结果显示:

如果设置1000字以上,空格太多,大小1.13

如果设置500字以上,大小变为22.3K

问题:

可是我并不知道每一段的总字数是多少,现在给所有段落默认添加1000字符,如果一段文字大于1000字,还是会没有空格和下划线。同时其他段落标题只有4-10个字,根本不需要填充1000字空格。

第2问:计算原有字符数+额外加多少空格下划线

手动测算一行有几个空

默认加78空,保证下划线肯定能撑满

代码展示

from docx import Document

z=78

def add_dynamic_underline(doc_path, output_path, extra_length=z):
    """
    为Word文档每段添加实线下划线,动态计算每段长度并额外增加指定字符数
    用全角空格填充至(实际长度+extra_length)的宽度
    
    参数:
        doc_path (str): 输入文档路径
        output_path (str): 输出文档路径
        extra_length (int): 每段额外增加的字符宽度
    """
    # 加载文档
    doc = Document(doc_path)
    
    for paragraph in doc.paragraphs:
        if paragraph.text.strip():  # 只处理非空段落
            # 获取段落的最后一行
            lines = paragraph.text.split('\n')
            last_line = lines[-1] if lines else ""
            
            # 计算最后一行的字符宽度(中文算2,英文算1)
            current_width = sum(2 if ord(c) > 127 else 1 for c in last_line)
            
            # 动态设置目标长度 = 当前宽度 + 额外长度
            target_length = current_width + extra_length
            
            # 计算需要填充的全角空格数
            fill_count = max(0, target_length - current_width)
            
            print(f"段落内容: '{last_line}'")
            print(f"当前宽度: {current_width}, 目标宽度: {target_length}, 需要填充空格数: {fill_count}\n")
            
            # 为原有内容添加实线下划线
            for run in paragraph.runs:
                run.font.underline = True  # 设置为单实线
            
            # 仅在最后添加全角空格并带下划线
            if fill_count > 0:
                # 清除原有换行符(如果有)
                if paragraph.runs and paragraph.runs[-1].text.endswith('\n'):
                    paragraph.runs[-1].text = paragraph.runs[-1].text.rstrip('\n')
                
                fill_run = paragraph.add_run(" " * fill_count)  # 使用全角空格
                fill_run.font.underline = True
                
                # 恢复原有换行符(如果有)
                if len(lines) > 1:
                    paragraph.add_run().add_break()

    # 保存文档
    doc.save(output_path)

# 使用示例
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\工具运用'
input_path = path + r'\附件1工具运用训会议记录(2025.4.23).docx'
output_path = path + r'\附件1工具运用训会议记录(2025.4.23)_动态下划线.docx'
add_dynamic_underline(input_path, output_path, extra_length=z)

虽然打印时看不见,但我觉得右边距上一推灰点和回车,还是不好看,希望右边距上的点子不要出现。

第3问

计算一行可以有多少个字符

手动输入满一行

from docx import Document



def count_width_per_line(doc_path):
    """统计 Word 文档中每一行的宽度(中文=2,英文=1)"""
    doc = Document(doc_path)
    
    for i, paragraph in enumerate(doc.paragraphs, 1):
        if not paragraph.text.strip():  # 跳过空行
            continue
        
        lines = paragraph.text.split('\n')  # 按换行符分割
        for j, line in enumerate(lines, 1):
            if not line.strip():  # 跳过空行
                continue
            
            # 计算宽度(中文=2,英文=1)
            width = sum(2 if ord(c) > 127 else 1 for c in line)
            print(f"第 {i} 段,第 {j} 行 | 宽度: {width} | 字符数: {len(line)} | 内容: '{line}'")
    
    print("\n统计完成!")

# 使用示例
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\工具运用'
doc_path = path + r'\附件1工具运用训会议记录(2025.4.23).docx'
count_width_per_line(doc_path)

计算一行可以有多少个字符=69个

第4问:每段最后一行有有几个汉字,69减去最后一行的汉字的树数目就是添加额外的空格数量

把都是汉字字符,是双数字符,尝试把69改成70

正好,都显示满了

代码展示

'''
会议记录自动补全下划线
 根据字数添加补全剩余空格下划线
deepseek \阿夏
20250424
'''
from docx import Document

# 每行标准宽度(中文=2,英文=1)
h = 70

def add_dynamic_underline(doc_path, output_path):
    """
    为Word文档每段添加实线下划线,动态计算每段行数并调整下划线长度
    并保持原有字体格式
    
    参数:
        doc_path (str): 输入文档路径
        output_path (str): 输出文档路径
    """
    doc = Document(doc_path)
    
    for paragraph in doc.paragraphs:
        if paragraph.text.strip():  # 只处理非空段落
            # 获取段落的最后一行
            lines = paragraph.text.split('\n')
            last_line = lines[-1] if lines else ""
            
            # 计算最后一行的字符宽度(中文算2,英文算1)
            current_width = sum(2 if ord(c) > 127 else 1 for c in last_line)
            
            # 计算该段有多少行(向上取整)
            line_count = current_width // h
            if line_count <1:
                line_count = 1
                extra_length = h - current_width 
            else:
                extra_length = h - (current_width - line_count*h)
                
            print(f"段落内容: '{last_line}'")
            print(f"当前宽度: {current_width},汉字和英文的字符长度:'{len(last_line)}', 每行宽度: {h}, 行数: {line_count}")
            print(f"额外下划线长度: {extra_length}\n")
    
            # print(f"当前宽度: {current_width}, 目标宽度: {target_length}, 需要填充空格数: {fill_count}\n")
            
            
            # 为原有内容添加实线下划线
            for run in paragraph.runs:
                run.font.underline = True  # 设置为单实线
            
            # 仅在最后添加全角空格并带下划线
            if extra_length > 0:
                # 清除原有换行符(如果有)
                if paragraph.runs and paragraph.runs[-1].text.endswith('\n'):
                    paragraph.runs[-1].text = paragraph.runs[-1].text.rstrip('\n')
                
                # 获取最后一个 run 的字体格式
                last_run = paragraph.runs[-1] if paragraph.runs else None
                
                # 添加空格,并复制原有格式
                fill_run = paragraph.add_run(" " * extra_length)
                if last_run:  # 如果存在原有 run,则复制其字体格式
                    fill_run.font.name = last_run.font.name  # 字体
                    fill_run.font.size = last_run.font.size  # 字号
                    fill_run.font.bold = last_run.font.bold  # 加粗
                    fill_run.font.italic = last_run.font.italic  # 斜体
                fill_run.font.underline = True  # 设置下划线
                
                # 恢复原有换行符(如果有)
                if len(lines) > 1:
                    paragraph.add_run().add_break()

    # 保存文档
    doc.save(output_path)

# 使用示例
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\工具运用'
input_path = path + r'\附件1工具运用训会议记录(2025.4.23).docx'
output_path = path + r'\附件1工具运用训会议记录(2025.4.23)_动态下划线.docx'
add_dynamic_underline(input_path, output_path)

测试效果

删除空行,然后把内容变成10-1000字的段落

ok,完美实现补全下划线的目标。

后续做成exe,GUI界面,选择文件夹,发给不同的课题组成员补会议记录用(贴完文字后,用Python自动添加一下每行最后空白的下划线)让做的资料的文本版式更好看,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解释器模式:自定义语言解析与执行的设计模式

解释器模式&#xff1a;自定义语言解析与执行的设计模式 一、模式核心&#xff1a;定义语言文法并实现解释器处理句子 在软件开发中&#xff0c;当需要处理特定领域的语言&#xff08;如数学表达式、正则表达式、自定义配置语言&#xff09;时&#xff0c;可以通过解释器模式…

AI催生DLP新战场 | 天空卫士连续6年入选Gartner 全球数据防泄漏(DLP)市场指南

“管理数据外泄风险仍然是企业的重大挑战之一&#xff0c;客户处出于各种因素寻求DLP。最近&#xff0c;一些组织对使用DLP控制机器对敏感信息的访问表现出很大兴趣。 随着生成式人工智能&#xff08;GenAI&#xff09;的运用和数据的不断扩散&#xff0c;数据外泄的问题变得更…

Adobe After Effects的插件--------Optical Flares之Lens Objects参数

Lens Objects,即【镜头对象】。 通用设置 全局参数发光多光圈光圈条纹微光反射钉球闪光圆环箍焦散镜头球缩放✔✔✔✔✔✔✔✔✔✔✔✔✔缩放偏移✔长宽比✔✔✔✔✔✔✔✔✔✔✔✔✔混合模式✔颜色✔全局种子✔亮度✔✔✔✔✔✔✔✔✔✔✔✔拉伸✔✔✔✔✔✔✔✔✔✔✔✔距离…

【问题】解决docker的方式安装n8n,找不到docker.n8n.io/n8nio/n8n:latest镜像的问题

问题概览 用docker方式安装n8n&#xff0c;遇到错误&#xff0c;安装不了的问题&#xff1a; Unable to find image docker.n8n.io/n8nio/n8n:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request can…

系统与网络安全------弹性交换网络(1)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 Trunk原理与配置 Trunk原理概述 Trunk&#xff08;虚拟局域网中继技术&#xff09;是指能让连接在不同交换机上的相同VLAN中的主机互通。 VLAN内通信 实现跨交换的同VLAN通信&#xff0c;通过Trunk链路&am…

10天学会嵌入式技术之51单片机-day-3

第九章 独立按键 按键的作用相当于一个开关&#xff0c;按下时接通&#xff08;或断开&#xff09;&#xff0c;松开后断开&#xff08;或接通&#xff09;。实物图、原理图、封装 9.2 需求描述 通过 SW1、SW2、SW3、SW4 四个独立按键分别控制 LED1、LED2、LED3、LED4 的亮…

深入解析微软MarkitDown:原理、应用与二次开发指南

一、项目背景与技术定位 微软开源的MarkitDown并非简单的又一个Markdown解析器&#xff0c;而是针对现代文档处理需求设计的工具链核心组件。该项目诞生于微软内部大规模文档系统的开发实践&#xff0c;旨在解决以下技术痛点&#xff1a; 大规模文档处理性能&#xff1a;能够高…

【PVCodeNet】《Palm Vein Recognition Network Combining Transformer and CNN》

[1]吴凯,沈文忠,贾丁丁,等.融合Transformer和CNN的手掌静脉识别网络[J].计算机工程与应用,2023,59(24):98-109. 文章目录 1、Background and Motivation2、Related Work3、Advantages / Contributions4、Method5、Experiments5.1、Datasets and Metrics5.2、Hyper-parameters5.…

x-cmd install | brows - 终端里的 GitHub Releases 浏览器,告别繁琐下载!

目录 核心功能与优势安装适用场景 还在为寻找 GitHub 项目的特定 Release 版本而苦恼吗&#xff1f;还在网页上翻来覆去地查找下载链接吗&#xff1f;现在&#xff0c;有了 brows&#xff0c;一切都将变得简单高效&#xff01; brows 是一款专为终端设计的 GitHub Releases 浏览…

多模态知识图谱:重构大模型RAG效能新边界

当前企业级RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统在非结构化数据处理中面临四大核心问题&#xff1a; 数据孤岛效应&#xff1a;异构数据源&#xff08;文档/表格/图像/视频&#xff09;独立存储&#xff0c;缺乏跨模态语义关联&#xff0c;导致知识检…

实验八 版本控制

实验八 版本控制 一、实验目的 掌握Git基本命令的使用。 二、实验内容 1.理解版本控制工具的意义。 2.安装Windows和Linux下的git工具。 3.利用git bash结合常用Linux命令管理文件和目录。 4.利用git创建本地仓库并进行简单的版本控制实验。 三、主要实验步骤 1.下载并安…

JavaWeb:Web介绍

Web开篇 什么是web? Web网站工作流程 网站开发模式 Web前端开发 初识web Web标准 HtmlCss 什么是Html? 什么是CSS?

教育行业网络安全:守护学校终端安全,筑牢教育行业网络安全防线!

教育行业面临的终端安全问题日益突出&#xff0c;主要源于教育信息化进程的加速、终端设备多样化以及网络环境的开放性。 以下是教育行业终端安全面临的主要挑战&#xff1a; 1、设备类型复杂化 问题&#xff1a;教育机构使用的终端设备包括PC、服务器等&#xff0c;操作系统…

Spring Boot知识点详解

打包部署 <!‐‐ 这个插件&#xff0c;可以将应用打包成一个可执行的jar包&#xff1b;‐‐> <build><plugins> <plugin> <groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐maven‐plugin</artifactId&g…

DNS主从同步及解析

DNS 域名解析原理 域名系统的层次结构 &#xff1a;DNS 采用分层树状结构&#xff0c;顶级域名&#xff08;如.com、.org、.net 等&#xff09;位于顶层&#xff0c;下面是二级域名、三级域名等。例如&#xff0c;在域名 “www.example.com” 中&#xff0c;“com” 是顶级域名…

在Windows11上用wsl配置docker register 镜像地址

一、下载软件 1、下载wsl:安装 WSL | Microsoft Learn,先按照旧版 WSL 的手动安装步骤 | Microsoft Learn的步骤走 注:如果wsl2怎么都安装不下来,可能是Hyper-V没有打开,打开控制面板->程序和功能->启用或关闭Windows功能,勾选Hyper-V 如果Windows功能里面没有Hyp…

【Linux网络】构建UDP服务器与字典翻译系统

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

【PGCCC】Postgres 故障排除:修复重复的主键行

如何从表中删除不需要的重复行。这些重复行之所以“不需要”&#xff0c;是因为同一个值在指定为主键的列中出现多次。自从 glibc 好心地改变了排序方式后&#xff0c;我们发现这个问题有所增加。当用户升级操作系统并修改底层 glibc 库时&#xff0c;这可能会导致无效索引。 唯…

DeepSeek+Cursor+Devbox+Sealos项目实战

黑马程序员DeepSeekCursorDevboxSealos带你零代码搞定实战项目开发部署视频教程&#xff0c;基于AI完成项目的设计、开发、测试、联调、部署全流程 原视频地址视频选的项目非常基础&#xff0c;基本就是过了个web开发流程&#xff0c;但我在实际跟着操作时&#xff0c;ai依然会…

996引擎-拓展变量:物品变量

996引擎-拓展变量:物品变量 测试代码参考资料对于Lua来说,只有能保存数据库的变量才有意义。 至于临时变量,不像TXT那么束手束脚,通常使用Lua变量就能完成。 SELECT * FROM dbo.TBL_ITEM_EX_ABIL WHERE FLD_MAKEINDEX = 28620 <