删除-docx-空行工具脚本
Contents
本文介绍仓库内的脚本源代码文件,它可以自动删除 .docx 文档中的空段落,并在非空段落中合并连续换行(将多个连续换行替换为一个)。脚本同时会处理表格单元格内的段落。
本工具最初用于在申请软件著作权时,批量清理源代码文档中的空行,让提交给软著的源代码文档更加紧凑、排版整齐,方便审核和归档。
如果你不方便在本地安装 Python,也可以使用浏览器版工具:删除 DOCX 空行(网页版),直接在网页中选择 .docx 文件并下载清理后的文档。
主要功能
- 删除文档正文中空的段落(完全没有可见字符的段落)。
- 在非空段落中把连续的
\n合并为单个\n,避免多余的空行或换行符导致格式混乱。 - 遍历文档内的表格,按单元格同样规则清理空段落并合并换行。
- 提供简单的 Tkinter GUI,交互选择输入/输出文件路径,适合非命令行用户。
依赖
- 使用
python-docx(包名python-docx)来读写 Word 文档。仓库中的脚本示例使用from docx import Document。
安装
pip install python-docx
(如果要使用 live GUI,请确保当前 Python 环境包含 Tkinter。Windows 上自带标准 Python 通常包含 Tkinter。)
如何使用
图形界面(推荐,脚本默认行为):
运行脚本:
python 原始内容文档/dele_null_line.py
脚本会弹出文件选择对话框,请选择要处理的
.docx文件,并指定输出文件名。
作为模块调用(在其他脚本中复用函数):
from 原始内容文档.dele_null_line import remove_empty_lines_from_docx remove_empty_lines_from_docx(‘input.docx’, ‘output.docx’)
实现要点(供维护者参考)
- 段落处理:脚本先遍历
doc.paragraphs,把纯空的段落标记删除,非空段落使用正则re.sub(r"\n+","\n", text)合并连续换行。 - 表格处理:进入每个
doc.tables,对每个单元格的cell.paragraphs做同样的清理与合并。 - 删除操作:对要删除的段落或单元格段落,使用底层 XML 节点
._element.getparent().remove(...)执行删除,避免改变段落集合时引发索引问题(通过反向索引删除)。
示例场景
- 批量格式化从其他来源复制粘贴到 Word 的内容,常见于论文、报告或网页复制导致的多余空行。
- 清理表格中因分行导致的冗余空段落,使单元格显示更整洁。
注意与限制
- 脚本基于
python-docx的 API 操作,可能不会保留某些复杂样式或嵌入对象(图形/SmartArt 等)的精确格式。 - 删除空段落是以“纯文本为空”为判断标准;如果某些段落仅包含空白字符或不可见字符(特殊控制符),会被视为空并删除。
- 如果需要保留段落样式或分页断点,请在使用前备份原始文件。
改进建议
- 增加批处理(对目录下所有
.docx文件递归处理)。 - 增加可选参数:是否保留段落样式、是否只处理正文不处理表格、备份原文件等。
- 在保存前增加简易的差异报告(列出删除的段落数、修改的单元格数),便于审计。
示例输出提示
脚本运行结束会打印:
空行清理完成!输出文件:<output_path>
(UI 模式下会用弹窗告知完成情况。)
完整代码如下:
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import re
def remove_empty_lines_from_docx(input_path, output_path):
doc = Document(input_path)
# 段落:删除空段落,非空段落合并连续换行
paragraphs = list(doc.paragraphs)
to_delete = []
for idx, p in enumerate(paragraphs):
text = p.text or ""
if text.strip() == "":
to_delete.append(idx)
else:
p.text = re.sub(r"\n+", "\n", text)
for idx in reversed(to_delete):
paragraphs[idx]._element.getparent().remove(paragraphs[idx]._element)
# 表格:删除单元格内空段落,非空段落合并连续换行
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
cell_paras = list(cell.paragraphs)
del_idxs = []
for i, cp in enumerate(cell_paras):
txt = cp.text or ""
if txt.strip() == "":
del_idxs.append(i)
else:
cp.text = re.sub(r"\n+", "\n", txt)
for i in reversed(del_idxs):
cell_paras[i]._element.getparent().remove(cell_paras[i]._element)
doc.save(output_path)
print(f"空行清理完成!输出文件:{output_path}")
# ------------------- 调用示例 -------------------
import tkinter as tk
from tkinter import filedialog, messagebox
# 中文注释:通过图形界面选择输入与输出的 .docx 文件并执行清理
def main():
try:
root = tk.Tk()
root.withdraw()
input_path = filedialog.askopenfilename(
title="选择输入 .docx 文件",
filetypes=[("Word 文档", "*.docx")]
)
if not input_path:
messagebox.showwarning("提示", "未选择输入文件,已取消。")
return
output_path = filedialog.asksaveasfilename(
title="选择输出 .docx 文件",
defaultextension=".docx",
filetypes=[("Word 文档", "*.docx")]
)
if not output_path:
messagebox.showwarning("提示", "未选择输出文件,已取消。")
return
remove_empty_lines_from_docx(input_path, output_path)
messagebox.showinfo("完成", f"空行清理完成!\n输出文件:{output_path}")
except Exception as e:
try:
messagebox.showerror("错误", f"处理失败:{e}")
except Exception:
print(f"处理失败:{e}")
if __name__ == "__main__":
main()