Python中对文件的基本操作

news2025/1/24 5:35:20

文章目录

      • 文件和目录路径
      • 文件的读取、写入、复制、删除、变更位置及修改名称
      • 解压缩zip格式的文件
      • 剪切板的应用
      • 使用python-docx处理Word文档
      • 使用openpyxl处理Excel文档
      • 示例:获取Excel文档中的数据生成Word文档

文件和目录路径

os库是Python内置的标准库,包含了上百个函数,常用路径操作、进程管理、环境参数等几类,os.path子库是以path为入口,用于操作和处理文件路径

import os           # 导入os模块

print(os.getcwd())  # 打印当前工作目录
print(os.path.abspath("."))         # 打印当前工作目录的绝对路径
print(os.path.abspath(".."))        # 打印上一级目录的绝对路径
print(os.path.abspath("test.py"))   # 打印当前文件的绝对路径

print(os.path.relpath("D:\\"))              # 打印当前工作目录至D:\的相对路径
print(os.path.relpath("D:\\Code\\Java"))    # 打印当前工作目录至特定path的相对路径
print(os.path.relpath("D:\\","test.py"))    # 打印当前文件至D:\的相对路径

print("判断当前工作目录下是否存在输入的文件或目录:",os.path.exists("test.py"))
print("判断当前工作目录下是否存在输入的文件或目录:",os.path.exists("Java"))
print("判断当前工作目录下是否存在输入的文件或目录:",os.path.exists("D:\\Code"))

print("判断当前输入的是否为绝对路径:",os.path.isabs("test.py"))
print("判断当前输入的是否为绝对路径:",os.path.isabs("D:\\Code\\Java"))

print("判断当前输入的是否为文件名:",os.path.isfile("D:\\Code\\Python\\test.py"))
print("判断当前输入的是否为文件名:",os.path.isfile("D:\\Code\\Java"))

print("判断当前输入的是否为目录名:",os.path.isdir("D:\\Code\\Python\\test.py"))
print("判断当前输入的是否为目录名:",os.path.isdir("D:\\Code\\Java"))

my_dir = "test.txt"
if os.path.exists(my_dir):
    print(f"已存在名为{my_dir}目录")
else:
    os.mkdir(my_dir)
    print(f"在当前工作目录下成功创建名为{my_dir}目录")

if os.path.exists(my_dir):
    os.rmdir(my_dir)                # 只能删除空目录
    print(f"成功删除名为{my_dir}目录")
else:
    print(f"名为{my_dir}目录不存在")

my_file = "test.txt"
if os.path.exists(my_file):
    os.remove(my_file)
    print(f"成功删除名为{my_file}文件")
else:
    print(f"不存在名为{my_file}文件")

new_dir = "D:\\Code\\Python\\testdir"
cureentdir = os.getcwd()
print("打印当前工作目录路径:",cureentdir)
if os.path.exists(new_dir):
    print(f"已存在名为{new_dir}目录")
else:
    os.mkdir(new_dir)
    print(f"成功创建名为{new_dir}目录")
os.chdir(new_dir)       # 将当前工作目录改至new_dir
print("打印最新的工作目录路径:",os.getcwd())
os.chdir(cureentdir)    # 改回至原来的工作目录
print("打印改回后的工作目录路径:",os.getcwd())

print(os.path.join("D:\\","Code","test.py"))    #传回文件路径,将字符串结合为一个文件路径,至少包含两个参数
files = ["test1.py","dyd.py","yd.py"]
for i in files:
    print(os.path.join("D:\\Code\\Python\\testdir",i))

print("获取指定文件的大小:",os.path.getsize("D:\\Code\\Cypress_test\\cypress.json"))
print("获取当前工作目录下指定文件的大小",os.path.getsize("test.py"))

print("使用绝对路径获取指定目录下的内容",os.listdir("D:\\Code\\Python"))
print("使用相对路径获取指定目录下的内容",os.listdir("../../Download"))

totalsizes = 0
for i in os.listdir("."):
    totalsizes += os.path.getsize(os.path.join(".",i))
print("当前工作目录D:\\Code\\Python下全部文件大小总和为:",totalsizes)

import glob           # 导入glob模块,与listdir的不同是glob可以使用通配符,比如只获取txt格式文件,就可以用”*.txt“

for i in glob.glob("D:\\Code\\Python\*.*"):
    print("打印D:\\Code\\Python目录下所有的文件:",i)

for i in glob.glob("test*.py"):
    print("打印当前目录下以test开头以.py为后缀的文件:",i)

for dirName,subdirNames,fileNames in os.walk("D:\\Code\\Python"):
    print("当前根工作目录名:",dirName)
    print("当前子目录名列表:",subdirNames)
    print("当前文件名列表:",fileNames)

文件的读取、写入、复制、删除、变更位置及修改名称

# 读取文件
file = "../../Download/test.txt"                # 设置欲开启的文件,绝对相对路径都可以
file_Obj = open(file,"r",encoding="UTF-8")      # 使用只读模式并以UTF8格式开启文件,传给file_Obj
data = file_Obj.read()                          # 读取文件内容并赋值给变量data
print(data)                     # 输出变量data,即输出文件内容
file_Obj.close()                # 建议使用close()将文件关闭,否则未来此文件内容可能会出现不可预期的损害

with open(file,"r",encoding="UTF-8") as file_Obj:   # 使用只读模式并以UTF8格式开启文件,传给file_Obj
    data = file_Obj.read()      # 读取文件内容并赋值给变量data
    print(data)                 # 输出变量data,即输出文件内容

with open(file,"r",encoding="UTF-8") as file_Obj:   # 使用只读模式并以UTF8格式开启文件,传给file_Obj
    for i in file_Obj:          # 逐行读取文件内容并赋值给变量data
        print(i.rstrip())       # 输出变量i,即输出文件内容,rstrip()的作用是删除末端换行符号,也可以使用end=""

with open(file,"r",encoding="UTF-8") as file_Obj:   # 使用只读模式并以UTF8格式开启文件,传给file_Obj
    data = file_Obj.readlines() # 逐行读取文件内容,并将结果存储到列表中,注意:每行的换行符也会一并存储到列表中
    print(data)                 # 输出变量data,以列表的形式输出结果

str1 = ""                       # 设置一个空字符串
for i in data:                  # 将各行字符串存入到str1,组合数据
    str1 += i.rstrip()          # 数据存入时去掉换行符
print(str1)                     # 打印组合后的字符串

with open(file,"r",encoding="UTF-8") as file_Obj:   # 使用只读模式并以UTF8格式开启文件,传给file_Obj
    data = file_Obj.read()                          # 读取文件内容并赋值给变量data
    new_data = data.replace("test","ceshi")         # 将test替换为【ceshi】
    print(new_data)                                 # 打印文件新内容

 findstr = input("请输入要查询的字符串:")
 if findstr in str1:
     print(f"查找的{findstr}字符串,{file}文件中存在!")
 else:
     print(f"查找的{findstr}字符串,{file}文件中不存在!")

 findstr = input("请输入要查询的字符串:")
 index = str1.find(findstr)
 if index >=0:
     print(f"查找的{findstr}字符串,{file}文件中存在,出现在索引{index}位置!")
 else:
     print(f"查找的{findstr}字符串,{file}文件中不存在!")

# 写入文件
f = "text1.txt"
str2 = "这句是写入文件的!"
num = 123
with open(f,"w",encoding="UTF-8") as file_Obj1:     # w表示写入模式
    file_Obj1.write(str2)

with open(f,"a",encoding="UTF-8") as file_Obj2:     # a表示追加模式
    file_Obj2.write(str(num))                       # 输入数值时必须先转为字符串,否则报TypeError

with open(f,"r+",encoding="UTF-8") as file_Obj3:    # r+ 表示读取并写入,也可以写作rw
    file_Obj3.write(str2+"\n")                      # 使用换行符输入多行数据
    file_Obj3.write(str(num))

import shutil   # 导入shutil模块

shutil.copy("text1.txt","cy_text.txt")                          # 在当前目录复制文件并命名为cy_text.txt
shutil.copy("text1.txt","../../Download")                       # 从当前目录复制文件到Download目录下,绝对/相对路径都可以
shutil.copy("D:\\Download\\test.docx","testdir/cy_test.docx")   # 不同目录的文件复制,复制Download下的test.docx文件到testdir目录下

shutil.copytree("testdir","cy_testdir")             # 在当前目录复制目录,当文件已存在时,无法创建该文件,报FileExistsError
shutil.copytree("D:\\Download\\Edge","./cy_Edge")   # 不同目录下的复制目录,复制Download下的Edge目录到当前目录并命名为cy_Edge

shutil.move("cy_text.txt","testdir")                  # 移动cy_text.txt文件到testdir目录下
shutil.move("testdir/cy_text.txt","./test123.txt")    # 若移动目标目录路径中包含文件名,则表示移动此文件并重命名
shutil.move("cy_Edge","D:\\Download\\Edge123")        # 也可以移动目录,将cy_Edge目录移动到Download目录下并重命名为Edge123

shutil.rmtree("cy_testdir")         # 上文有介绍os.rmdir()只能删除空目录,可以使用此方式删除有数据的目录

# 使用shutil.rmtree()直接删除有数据的文件太危险,所以可以使用第三方模块send2trash,先使用pip命令安装后再导入使用
import send2trash

send2trash.send2trash("test123.txt")              # 将test123.txt放到回收站
send2trash.send2trash("D:\\Download\\Edge123")    # 将Download目录下Edge123目录放到回收站

解压缩zip格式的文件

Python中有内置zipFile模块,用于将文件或目录解压缩,直接导入使用即可

import zipfile  # 导入zipfile模块
# 压缩文件
fileZip = zipfile.ZipFile("dydtest.zip","w")        # 压缩文件,命名为dydtest.zip,将结果赋值fileZip对象
for name in glob.glob("D:\\Code\\Python\*.*"):      # 通过循环获取D:\\Code\\Python\目录下的所有文件
    fileZip.write(name,os.path.basename(name),zipfile.ZIP_DEFLATED) # 使用ZIP_DEFLATED压缩方式,压缩D:\\Code\\Python\整个目录

fileZip.close() # 关闭压缩包

# 解压文件
listZipinfo = zipfile.ZipFile("dydtest.zip","r")    # 读取压缩文件dydtest.zip中的内容
print(listZipinfo.namelist())                       # 以列表方式查看压缩包中的文件

for name in listZipinfo.infolist():                 # 通过for循环获取每一个文件
    print(name.filename,name.file_size,name.compress_size)  # 打印每个文件的文件名、原文件大小,压缩后的文件大小

fileUnzip = zipfile.ZipFile("dydtest.zip")          # 解压缩包,获取dydtest.zip中的文件
fileUnzip.extractall("undydtest")                   # 解压到当前目录下的名为undydtest目录中
fileUnzip.close()       # 关闭压缩包

剪切板的应用

剪切板功能是属于第三方pyperclip模块内,使用前需先安装pip install pyperclip,该模块仅可用于复制粘贴文本

import pyperclip    			# 导入模块
str3 = "测试123!@#"
pyperclip.copy(str3.split("123")[0])        # 将字符串str3中的【测试】二字复制到剪切板
str4 = pyperclip.paste()    	# 粘贴剪切板内容并赋值给str4
print(str4)     				# 打印str4的值,结果为“测试”
pyperclip.copy(str3[2:])        # 将字符串str3中的【123!@#】复制到剪切板
str5 = pyperclip.paste()    	# 粘贴剪切板内容并赋值给str5
print(str5)     				# 打印str4的值,结果为“123!@#”
pyperclip.copy(str3)        	# 将字符串str3所有字符复制到剪切板
str6 = pyperclip.paste()    	# 粘贴剪切板内容并赋值给str6
print(str6)     				# 打印str4的值,结果为“测试123!@#”

使用python-docx处理Word文档

python-docx是用于创建或修改Word的一个第三方python库,使用前需先安装pip install python-docxpython-docx中将Word文件结构分为三层:

  1. Document:代表整个Word文件
  2. Paragraph:一个Word文件由多个段落组成,每单击一次Enter键就会产生一个段落,所有段落以Paragraph对象列表方式存在
  3. Run:Word文件中可设置字体、字号、色彩等,这些称之为样式,一个Run对象所指的是Paragraph对象汇总相同样式的连续文字,若文字样式发生变化,则将以新的Run对象表示

以下代码同时运行可能出现报错或部分页面样式被覆盖等问题,故请按需获取,写在一起记录,仅是为方便以后查找使用,更多功能实现方法请查看官方文档

from docx import Document
from docx.enum.section import WD_SECTION_START, WD_ORIENTATION
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Cm, Pt, RGBColor, Mm
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_COLOR_INDEX

wd = Document()					# 定义一个新的文档对象
p = wd.add_paragraph("风度翩翩") # 添加段落
print(p)						# 打印段落
p.text = "玉树临风"				 # 修改段落内容

# p.text = ""     # 删除段落内容,此方式其实段落仍存在只是无内容
# print(len(wd.paragraphs))

# 彻底删除段落
for i in wd.paragraphs:         # 通过遍历获取所有段落
    p = i._element              # 每个段落都是由一个个标签组成,获取段落中的标签
    # print(p)
    p.getparent().remove(p)     # 获取标签的父标签,然后通过父标签删除当前标签,标签不能自己删除自己
    p._parent = None            # 然后父标签也设置为空
print(f"共有{len(wd.paragraphs)}段落")       # 获取总段落,结果为0

# 添加段落并设置段落对齐方式
p1 = wd.add_paragraph("左对齐,也是默认对齐样式")
p2 = wd.add_paragraph("右对齐")
p3 = wd.add_paragraph("居中对齐")
p4 = wd.add_paragraph("两端对齐,即最后一行未占满时,以左对齐的方式显示")
p5 = wd.add_paragraph("分散对齐,即最后一行未占满时,分散文字占满此行")

p1.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
p2.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
p3.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p4.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY
p5.alignment = WD_PARAGRAPH_ALIGNMENT.DISTRIBUTE

p6 = wd.add_paragraph("这是段落①")
p7 = wd.add_paragraph("这是段落②")
p8 = wd.add_paragraph("这是段落③")
p9 = wd.add_paragraph("这是段落④",style="List Bullet")
p9.style.delete()       # 删除段落样式,会恢复默认样式,即style="Normal"

p6.paragraph_format.line_spacing = Cm(2)     # 行间距为2cm
p7.paragraph_format.first_line_indent = Cm(1)   # 首行缩进1cm
p8.paragraph_format.space_before = Cm(2)        # 段落前空出2cm
p9.paragraph_format.space_after = Cm(3)         # 段落后空出3cm

p10 = wd.add_paragraph("这是段落⑤")
r1 = p10.add_run("追加文字0")             # 此时段落5和追加的文字属于同一个run
r1.font.bold = True                      # 加粗,此时”追加文字0“字体加粗,与段落5不再属于同一个run
r2 = p10.add_run("追加文字1")              # 此时段落5和追加文字1属于同一个run,但与追加文字不属于同一个run
r2.font.italic = True                     # 斜体,此时三者不属于同一个run
r3 = p10.add_run("追加文字2")              # 此时段落5和追加文字2属于同一个run,但与其它的不属于同一个run
r3.font.underline = True                  # 下划线,此时四者不属于同一个run
# r3.font.underline = WD_UNDERLINE.DOUBLE # r3设为双下划线
# r3.font.underline = WD_UNDERLINE.THICK  # r3设为下划线加粗
# r3.font.underline = WD_UNDERLINE.WAVY   # r3下划线设为波浪线
# ↓ 查看所有下划线类型
# for line_type in WD_UNDERLINE.__members__:
#     print(line_type.name)

r4 = p10.add_run("追加文字3")             # 此时段落5和追加文字3属于同一个run,但与其它的不属于同一个run
r4.font.strike = True                    # 中划线,此时五者不属于同一个run
# r4.font.double_strike = True           # r4设为双中划线
r5 = p10.add_run("追加文字4")             # 此时段落5和追加文字4属于同一个run,但与其它的不属于同一个run
r5.font.shadow = True                    # 阴影,此时五者不属于同一个run

r6 =p10.add_run("追加文字5,five")      	 # 此时段落5和追加文字5属于同一个run,但与其它的不属于同一个run
r6.font.name = "Arial"                  # 设置英文字体为Arial
r6.element.rPr.rFonts.set(qn("w:eastAsia"),"楷体")   # 设置中文字体为楷体,注意:即使run中没有英文,在设置中文字体前也必须先设置英文字体
r6.font.size = Pt(18)                   # 设置字号为18磅
# ↑ 此时六者不属于同一个run,因为“这是追加文字5”和“five”设置的样式是相同的,且二者是连续的,中间没有其它样式的run,所以它俩属于同一个run
r7 =p10.add_run("测试123")
r7.text = "\n这是换行追加的文字6"    				  # 修改了r7的文本内容
# r7.font.color.rgb = RGBColor(251,139,5)           # 设置字体颜色,使用rgb值
r7.font.color.rgb = RGBColor.from_string("9933FA")  # 使用十六进制rgb值设置字体颜色
r8 =p10.add_run("追加文字7")
r8.font.highlight_color = WD_COLOR_INDEX.PINK       # 设置字体背景色
# ↓ 查看所有支持的背景色
# for color in WD_COLOR_INDEX.__members__:
#     print(color.name)

print(f"共有{len(wd.paragraphs)}段落")                # 统计段落数
for pa in wd.paragraphs:                			# 通过遍历打印各段落内容
    print(pa.text)									# 打印段落内容
print(f"共有{len(wd.paragraphs[9].runs)}run")        # 统计段落10中的run数
for run in wd.paragraphs[9].runs:       			# 通过遍历打印各段落10中各run的内容
    print(run.text)									# 打印run内容

pic = wd.add_picture(r"E:\b2b5ab6.jpeg",width=Cm(3),height=Cm(2))    # 添加图片,可自定义长宽
wd.paragraphs[10].runs[0].add_picture(r"E:\5fa8f7d8aa67e.jpg",Cm(5)) # 添加图片和pic在同一行,不指定长宽时默认设置为宽度,高度同比例缩放
pic1 = wd.add_picture(r"E:\5165027.png")           		 # 添加图片,默认情况一张图为一个段落,后加的图片不会与之前添加的图片在同一行
print(f"宽:{pic1.width.cm}Cm,高:{pic1.height.cm}Cm")     # 打印pic1图片的原有宽度和高度,单位可选择cm和mm,或者不带单位
pic1.width = int(pic1.width * 0.2)      			# 设置pic1宽度为原有的20%
pic1.height = int(pic1.height * 0.2)    			# 设置pic1高度为原有的20%
print(f"当前文档中共{len(wd.inline_shapes)}张图")  	   # 统计文档中共有几张图片

# 因为默认情况一张图就是一个段落,所以图片的对齐方式和段落对齐方式一样,默认左对齐
wd.paragraphs[10].alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  	# 将pic图片靠右对齐
wd.paragraphs[11].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  	#将pic1图靠居中对齐
wd.paragraphs[10].alignment = WD_PARAGRAPH_ALIGNMENT.DISTRIBUTE # 将pic两张图分散对齐

# 新建表格
tab = wd.add_table(rows=2,cols=3)
tab.add_row()           					 # 添加一行,无需参数
tab.add_column(Cm(5))   					 # 添加一列,必须指定一个宽度
print(f"共{len(tab.rows)}行")    				# 统计表格行数
print(f"共{len(tab.columns)}列") 				# 统计表格列数
count = 0
for r in tab.rows:                            # 通过行获取各个单元格
    for j,rcell in enumerate(r.cells):        # enumerate可用于获取索引列表
        print(f"单元格:{r._index, j}", rcell) # 打印单元格坐标
        count +=1
print(count)                                 # 统计单元格个数,因tab表为3行4列,故共12个

for c in tab.columns:                       # 通过列获取各个单元格
    for j,ccell in enumerate(c.cells):
        print(f"单元格:{c._index, j}")      # 打印单元格坐标

for c in tab.rows[1:3]:                     # 通过切片方式,获取指定区域的单元格坐标
    for j,ccell in enumerate(c.cells):
        print(f"单元格:{c._index, j}")      # 打印单元格坐标

row = tab.rows[0]                    # 获取表格第1行并赋值给row
row.cells[0].text = "通过标准"        # 在单元格(0,0)输入
row.cells[1].text = "实际执行结果"     # 在单元格(0,1)输入
row.cells[2].text = "测试结果"        # 在单元格(0,2)输入

print("打印指定单元格中的内容:",tab.cell(0, 0).text)
for cell in tab.row_cells(0):
    print("打印第1行单元格中的内容:",cell.text)

for cell in tab.column_cells(0):
    print("打印第1列单元格中的内容:",cell.text)

for row in tab.rows:                # 通过嵌套循环打印所有单元格中的内容
    for cell in row.cells:
        print(cell.text)

cell1 = tab.cell(1,2)                # 获取单元格(0,2)并赋值给cell1
cell1.add_paragraph("通过")           # 在单元格(0,2)填写内容
cell1.add_paragraph().add_run().add_picture(r"E:\0fa202.jpeg",Mm(15))   # 单元格(0,2)换行添加图片

tab.add_row()                       # tab表添加一行
tab.cell(3,2).merge(cell1)          # 合并单元格

tab.rows[2]._element.getparent().remove(tab.rows[2]._element)   # 删除第3行

col = tab.columns[3]                # 删除第4列
for cell in col.cells:              # 通过for循环获取第4列的每个单元格后删除
    cell._element.getparent().remove(cell._element)

# ↓通过列表推导式获取表格样式
tab_styles = [s for s in wd.styles if s.type == WD_STYLE_TYPE.TABLE]
for style in tab_styles:    # 通过循环打印样式名称
    print(style.name)

tab1 = wd.add_table(2, 2,style="Table Grid")    # 新建表格,并设置表格网线
tab1.alignment = WD_TABLE_ALIGNMENT.CENTER      # 表格居中,默认居左,亦可设为居右
tab1.cell(0,0).text = "右对齐"
tab1.cell(0,0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
tab1.cell(0,1).text = "居中对齐"
tab1.cell(0,1).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
tab1.cell(1,0).text = "两端对齐"
tab1.cell(1,0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY
tab1.cell(1,1).text = "分散对齐"
tab1.cell(1,1).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.DISTRIBUTE

for r in tab1.rows:             #通过for循环每个单元格都设为居中对齐
    for j,rcell in enumerate(r.cells):
        tab1.cell(r._index, j).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

# 设置行宽行高
# tab.autofit = False           # 设置为不自动调整时,行宽行高设置才能同时生效
tab.rows[1].height = Mm(15)   # 设置第一行单元格高度
# tab.columns[0].width = Mm(15) # 设置第一列单元格宽度

# 分节符
wd.add_section(WD_SECTION_START.NEW_PAGE)   # 新的分页符
wd.add_section(WD_SECTION_START.CONTINUOUS) # 连续的分页符
wd.add_section(WD_SECTION_START.NEW_COLUMN) # 新的列分页符
wd.add_section(WD_SECTION_START.EVEN_PAGE)  # 偶数页分页符
wd.add_section(WD_SECTION_START.ODD_PAGE)   # 奇数页分页符
print(f"共有{len(wd.sections)}页")

# 设置第5页纸
section = wd.sections[4]
print(section.page_width.cm)
print(section.page_height.cm)
# 改为A4纸大小
section.page_width = Cm(21)
section.page_height = Cm(29.7)
print(section.orientation)
# 设置为横向纸,然后对调纸张的长宽
section.orientation = WD_ORIENTATION.LANDSCAPE
section.page_width,section.page_height = section.page_height,section.page_width
print(section.orientation)

# 设置第6页纸
section1 = wd.sections[5]
# 获取当前页边距
print(section1.top_margin.cm)
print(section1.bottom_margin.cm)
print(section1.left_margin.cm)
print(section1.right_margin.cm)
# 修改页边距
section1.top_margin = Cm(2)
section1.bottom_margin = Cm(2)
section1.left_margin = Cm(3)
section1.right_margin = Cm(3)
# 设置装订线
section1.gutter = Cm(2.5)

# 强制换页,即新建空白页
wd.add_page_break()

# 设置页眉页脚
wd.sections[0].header.paragraphs[0].add_run("每页纸上都显示该页眉")
wd.sections[0].footer.paragraphs[0].add_run("每页纸上都显示该页脚")
# 修改页眉页脚
wd.sections[0].header.paragraphs[0].text = "这是页眉"
wd.sections[0].footer.paragraphs[0].text = "这是页脚"
# 修改第5页及之后的纸张的页眉页脚
wd.sections[4].header.is_linked_to_previous = False     # 此代码的目的是不让它继承上一个页眉
wd.sections[4].header.paragraphs[0].text = "这是页眉2"
wd.sections[4].footer.is_linked_to_previous = False
wd.sections[4].footer.paragraphs[0].text = "这是页脚2"
# 页眉页脚中也可以添加图片、表格,设置字体样式等
wd.sections[0].header.paragraphs[0].add_run().add_picture(r"E:\190339.png",Cm(1))

wd.settings.odd_and_even_pages_header_footer = True     # 此代码的目的开启区分奇数页和偶数页的页眉页脚
wd.sections[0].header.paragraphs[0].text = "这是奇数页眉"
wd.sections[0].footer.paragraphs[0].text = "这是奇数页脚"
wd.sections[0].even_page_footer.paragraphs[0].text = "这是偶数页页眉"
wd.sections[0].even_page_footer.paragraphs[0].text = "这是偶数页页脚"
wd.add_page_break()     # 强行换页,也可以理解为添加一个空白页

wd.sections[0].different_first_page_header_footer = True    # 此代码的目的是让其可设置首页与其它页的页眉页脚不同
wd.sections[0].first_page_header.paragraphs[0].text = "这是首页页眉"
wd.sections[0].first_page_footer.paragraphs[0].text = "这是首页页脚"
wd.sections[0].header.paragraphs[0].text = "这是其它页的页眉"
wd.sections[0].footer.paragraphs[0].text = "这是其它页的页脚"

wd.save("dydtest.docx")

使用openpyxl处理Excel文档

openpyxl是支持读写Excel的python库,支持xlsx格式的Excel文件,能够同时读取和修改Excel文档,使用前需先安装pip install openpyxl

以下代码同时运行可能报错或部分页面样式被覆盖,故请按需获取,写在一起记录,仅是为方便以后查找使用,更多功能请查看官方文档

import openpyxl
from openpyxl.styles import PatternFill, GradientFill
from openpyxl.styles.borders import Border, Side
from openpyxl.styles.alignment import Alignment
from openpyxl.styles.fonts import Font
from openpyxl.utils import get_column_letter, column_index_from_string

wb = openpyxl.Workbook("E:/test_data.xlsx")   # 创建Excel文件
wb.save("E:/test_data.xlsx")

# 打开已存在的Excel文件,有些表格数据是通过函数计算的,data_only=True表示只查看最终数据
wb = openpyxl.load_workbook("E:/dydtest.xlsx",data_only=True)
# sheet = wb["成绩表"]			    # 指定打开名为“成绩”的工作表
sheet = wb[wb.sheetnames[0]]	    # 也可以使用下标的方式打开工作表

row = sheet.max_row				# 获取总行数
row1 = len(tuple(sheet.rows))	# 或者使用此方式获取总行数
col = sheet.max_column			# 获取总列数
col1 = len(tuple(sheet.columns))# 或者使用此方式获取总列数

wb.create_sheet("日历表")              # 新建工作表

copy_wb_st = wb.copy_worksheet(wb["成绩表"])  # 复制成绩表
copy_wb_st.title = "复制的成绩表"              # 指定表名,未指定时会在使用原表名并加上Copy

for i in wb.worksheets:         # 获取所有工作表
    print(i.title)              # 打印所有工作表名称
    if i.title != "成绩表":
        wb.remove(wb[i.title])  # 删除工作表,只保留“成绩表”

print(sheet["A1"].value)        # 打印单元格的值
print(sheet.cell(1,1).value)	# 或者使用坐标方式,先行后列,或使用参数名row=,column=
# sheet["A2"].value = int(126)    # 修改数据,默认是字符串格式
sheet.cell(6,8,value="测试")

for row in sheet["B2:E9"]:      # 获取指定区域的行
    for cell in row:            # 然后获取指定行中的单元格
        print(cell.value)       # 最后获取单元格中的内容

# ↓也可以使用此方式,iter_rows表示按行获取单元格,iter_cols表示按列获取单元格
ran = sheet.iter_rows(min_row=1,max_row=10,min_col=1,max_col=8)
for row in ran:               # 获取指定区域的行
    for cell in row:            # 然后获取指定行中的单元格
        if cell.value != None:  # 若单元格不为空则打印结果
            print(cell.value)

# 动态获取文档中所有的数据,即使增删了行列,也无需修改代码
for row in sheet.iter_rows(1,sheet.max_row,1,sheet.max_column):
    print([cell.value for cell in row if cell.value != None])# 使用列表推导式直接打印列表中的数据

# [1:]是使用切片的方式去掉顶部和左侧的表头
for row in list(sheet.iter_rows(1,sheet.max_row,1,sheet.max_column))[1:]:
    print([cell.value for cell in row[1:] if cell.value != None])

sheet.insert_rows(idx=2,amount=3)# 从第2行插入3行,idx=表示位置,amount=表示行/列数
sheet.delete_rows(2,3)        	 # 从第2行删除3行
sheet.insert_cols(2,3)        	 # 从第2列插入3列
sheet.delete_cols(2,3)        	 # 从第2列删除3列

list1 = ["张珊",136,128,98,286]
# 插入一行数据
for r in range(len(list1)):     # 获取列表元素总个数,做为列数
    # ↓ 在最后一行插入数据,list1列表中每拿到1个数据,列数就加1,然后赋值给对应单元格
    sheet.cell(row=sheet.max_row,column=r+1).value=list1[r]

sheet.insert_rows(idx=2,amount=1)# 在第2行插入1空行
for r in range(len(list1)):      # 在插入的空行填写数据
    sheet.cell(row=2,column=r+1).value=list1[r]

list2 = ["文综",268,188,288]
# 插入一列数据
for c in range(len(list2)):     # 获取列表元素总个数,做为行数
    sheet.cell(row=c+1,column=sheet.max_column).value=list2[c]

sheet.merge_cells("A2:B6")      # 合并单元格
sheet.unmerge_cells("A2:B6")    # 取消合并单元格

sheet.move_range("A1:C8",rows=10,cols=8)    # 移动单元格

sheet.freeze_panes = "B2"       # 冻结窗口

for row in sheet["A1:H1"]:      # 设置第一行(表头)样式
    for cell in row:
        cell.font = Font(name=u"宋体",bold=True,italic=True,size=18)  # 设置字体样式
        cell.fill = PatternFill(fill_type="solid",fgColor="FCFC0C")  # 设置背景色,实心填充

#渐变填充,type分为两种:linear表示线性渐变,path表示中心扩散;degree指旋转角度,stop中是颜色RGB值
sheet["D6"].fill=GradientFill(type="linear",degree=25,stop=("4158D0","C850C0","FFCC70"))

# 边框设置,可设置边框线的样式和颜色
l_side = Side(style='thin', color="EE0000")
r_side = Side(style='double', color="3608FC")
t_side = Side(style='dashed', color="0AFA38")
b_side = Side(style='hair', color="000000")
sheet["G6"].border = Border(left=l_side,right=r_side,top=t_side,bottom=b_side)

# 设置行高列宽,若低于Excel默认大小会失效
sheet.row_dimensions[2].height = 25
sheet.column_dimensions["C"].width = 15

# 通过for循环遍历所有单元格,然后设置统一的样式
for row in sheet.iter_rows(1,sheet.max_row,1,sheet.max_column):
    for cell in row:
        cell.font = Font(name=u"楷体",bold=True,size=15)      # 设置字体样式和大小
        cell.alignment = Alignment(horizontal="center",vertical="center",wrap_text=False)   # 字体水平垂直都居中,不自动换行
        cell.border = Border(left=Side(style='thin'), right=Side(style='thin'),top=Side(style='thin'),bottom=Side(style='thick'))

# 数字与字母转换,获取第几列时会用到
print(f"数字转换成字母:{get_column_letter(26)}")
print(f"字母转换成数字:{column_index_from_string('A')}")

wb.save("E:/dydtest.xlsx")	# 保存文件

示例:获取Excel文档中的数据生成Word文档

Excel文件的数据如图所示:

在这里插入图片描述

import datetime
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor
from openpyxl import load_workbook


wb = load_workbook("E:/dyd/A新员工信息.xlsx")	# 打开Excel文件
sheet = wb[wb.sheetnames[0]]	# 打开第一个工作表

employees= []  		# 新建一个空列表,将读取出来的每行数据存放到列表中
for x in range(2, int(sheet.max_row)+1):        # 获取可用数据行数,跳过表头
    employee_info = []  		                # 组装每行数据,形成一个列表
    for y in range(1,int(sheet.max_column)+1):  # 获取可用数据共几列
        employee_info.append(sheet.cell(row=x, column=y).value) # 将每个单元格数据添加到employee_info列表中
    employees.append(employee_info)             # 将每行数据添加到employees列表中

for r in range(0, int(sheet.max_row)-1):        # 获取可用数据行数,作为下标值,决定了内循环次数
    for i in employees[r]:                      # 通过下标获取嵌套列表中的每个列表
        employee_name = employees[r][0]         # 获取员工姓名
        department = employees[r][1]            # 获取部门
        job = employees[r][2]                   # 获取职位
        total_salary = sum(employees[r][3:7])   # 获取各项薪资并计算总金额
        salary_ratio = employees[r][7]          # 获取薪资发放比例
        entry_time = datetime.datetime.strptime(str(employees[r][8]),"%Y-%m-%d %H:%M:%S").date()    # 获取日期,去掉时分秒

        doc = Document()                        # 新建Word文档
        title = doc.add_paragraph()             # 添加一个段落作为标题
        title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 标题居中
        title_run = title.add_run("录用通知函")       # 添加标题内容
        title_run.font.size = Pt(20)                # 设置标题字号为20磅
        title_run.font.name = "Arial"               # ←↓设置字体样式
        title_run.element.rPr.rFonts.set(qn("w:eastAsia"),"宋体")

        # 正文段落
        text = doc.add_paragraph()                  # 添加一个段落
        run_list = list()  # 保存需要设置颜色的数据,即对从Excel文件获取的数据进行样式修改
        text.add_run(f"{employee_name},您好!")      # 使用Excel文件中的【姓名】
        text.add_run("很荣幸地通知您,根据我公司的需要及对您各项基本情况的审查和考核,您被成功录用为我公司员工。您所在的部门为")
        run_list.append(text.add_run(f"{department}"))  # 使用Excel文件中的【部门】,并将其添加到run_list列表中
        text.add_run("部,您的职位为")
        run_list.append(text.add_run(f"{job}"))
        text.add_run("。您的税前薪资为")
        run_list.append(text.add_run(f"{total_salary}"))
        text.add_run("元,试用期薪资")
        run_list.append(text.add_run(f"{salary_ratio}"))
        text.add_run(",绩效奖金和项目奖金的发放规则按照公司相关制度执行。请您于")
        run_list.append(text.add_run(f"{entry_time}"))
        text.add_run(""" 九点整到公司人力资源部报到,逾期此录用通知函自动失效。

        报到时,请携带以下材料:
        1. 原公司解除劳动合同证明
        2. 身份证原件、学历证书(包括学位证)原件
        3. 一寸照片三张

        此录用通知函不视为双方已建立劳动关系,劳动关系的建立以双方签订书面劳动合同为准。

        地址:汴京市-测试区东坡路188号268-8
        联系方式:周霸  188 6666 8888
        """)
        for run in run_list:        # 获取run_list列表中的数据,并设置样式
            run.font.color.rgb = RGBColor.from_string("EF0F0F") # 设置字体为红色

        text.style.font.size = Pt(12)                           # 设置正文字体为12磅
        text.paragraph_format.first_line_indent = Pt(24)        # 设置正文首行缩进2个字
        text.paragraph_format.line_spacing = 1.5                # 设置正文行距为1.5
        text.style.font.name = "Arial"                          # ←↓设置正文字体样式
        text.style.element.rPr.rFonts.set(qn("w:eastAsia"),"宋体")

        doc.save(f"E:/dyd/{employee_name}-offer.docx")          # 没遍历完一行数据就另存为一个Word文档

生成的word结果如下图所示,Excel中有几行数据就会生成几个Word文档
在这里插入图片描述

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

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

相关文章

张天禹移动端学习

文章目录 相关概念(一)屏幕相关1. 屏幕大小2. 屏幕分辨率3. 屏幕密度 (二)像素相关1.物理像素2. css 像素3. 设备独立像素4.像素比5.像素之间的关系 (三)图片高清显示位图像素图片的高清显示(媒…

chatgpt赋能python:Python下如何给网页添加背景图片

Python下如何给网页添加背景图片 随着现代互联网的快速发展,人们对于网页设计的要求越来越高,其中非常重要的一项就是背景图。在Python编程中,我们也可以很容易的为网页添加背景图片。 HTML中的background属性 要给网页加上背景图&#xf…

chatgpt赋能python:Python加法表达式,快速简便的计算方式

Python加法表达式,快速简便的计算方式 介绍 Python是一种可读性强、简洁、易于学习的编程语言,同时也是一种高级编程语言,由于其简洁性和可读性,越来越多的程序员们选择Python作为他们的工作语言。在Python中,加法表…

C++技能 - 详解使用Lambda表达式【再也不怕看不懂别人的代码了,干货还是蛮多的】

系列文章目录 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 C技能系列 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the future of dream w…

C语言之函数初阶(2)

目录 1. 函数是什么 2. 库函数 3. 自定义函数 4. 函数参数 5. 函数调用 6. 函数的嵌套调用和链式访问 7. 函数的声明和定义 8. 函数递归 上一篇博客我们讲解了函数的前六个比较容易理解的部分,这一篇博客我们来讲解最后两个部分 在讲这篇博客之前&am…

Shell免交互操作

目录 一、Here Document 免交互 1.免交互定义 2.格式和使用方法 二、Expect 免交互 1.简介 2.格式和使用 (1)声明解释器 (2)spawn(跟踪) (3)expect(期望&#x…

SpringBoot整合minio服务(超详细)

一、使用docker部署minio 1、拉取镜像 docker pull minio/minio 2、创建目录 mkdir -p /home/minio/config mkdir -p /home/minio/data 3、创建Minio容器并运行 docker run -p 9000:9000 -p 9090:9090 \--nethost \--name minio \-d --restartalways \-e "MINIO_ACC…

基于OpenCV的自动报靶识别实验

基于OpenCV的自动报靶识别实验 问题方案实验结论 问题 户外胸环靶自动报靶问题,目前是通过声电等方式来识别,成本较高,本文尝试使用图像处理的方法来识别。 方案 前提:固定相机 确定靶子的四个顶点:目前使用人工手…

使用imp和exp命令对orcale进行导入和导出

docker 进行orcale 查看这篇文章 https://editor.csdn.net/md/?articleId131026846 1、进入orcale 1、进入orcale容器 docker exec -it oracle11g bash2、orcale连接sysdba用户 进入root su root密码:helowin切换到oracle用户 su oracle使用sqlplus登录test用户…

chatgpt赋能python:Python中如何删除字符串中某个字符

Python中如何删除字符串中某个字符 Python是一种功能强大的编程语言,许多开发人员喜欢使用它来编写应用程序。字符串是Python中的常见数据类型之一,可用于存储文本。有时,我们可能需要删除字符串中的某个字符。本文将介绍如何在Python中使用…

GDB的学习

目录: 什么是gdb?gdb的安装gdb的使用 gdb的一些骚操作watch命令的使用调试core文件 什么是gdb? gdb的全称是GNU debugger,看名字就知道 gdb 是用来对程序进行 debug 的,不管是学习还是工作中,用好gdb&…

redis五种数据类型具体时候的底层编码

redis随着值的类型不同,其在底层编码类型会不相同。目前现有的编码格式有 #define OBJ_ENCODING_RAW 0 /* Raw representation */ #define OBJ_ENCODING_INT 1 /* Encoded as integer */ #define OBJ_ENCODING_HT 2 /* Encoded as hash table */ #def…

RabbitMQ集群部署之普通模式

1.集群分类 在RabbitMQ的官方文档中,讲述了两种集群的配置方式: 普通模式:普通模式集群不进行数据同步,每个MQ都有自己的队列、数据信息(其它元数据信息如交换机等会同步)。例如我们有2个MQ:m…

chatgpt赋能python:Python怎么再加一个的SEO

Python怎么再加一个的SEO 作为一名有10年Python编程经验的工程师,我深知如何将Python项目优化为搜索引擎友好的代码。当谈到SEO时,构建优化的代码比任何其他技术都更加重要。在本文中,我将介绍一些Python中的关键SEO技巧,并强调如…

Spring 事务管理方案和事务管理器及事务控制的API

目录 一、事务管理方案 1. 修改业务层代码 2. 测试 二、事务管理器 1. 简介 2. 在配置文件中引入约束 3. 进行事务配置 三、事务控制的API 1. PlatformTransactionManager接口 2. TransactionDefinition接口 3. TransactionStatus接口 往期专栏&文章相关导读 …

【前端 - CSS】第 11 课 - 选择器

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、基础选择器 2.1、标签选择器 2.2、类选择器 2.3、id 选择器 2.4、通配符选择器 3、画盒子 4、总结 1、缘…

chatgpt赋能python:如何使用Python删除变量中的数据?

如何使用Python删除变量中的数据? Python是一种非常流行的编程语言,许多开发人员使用它来开发高效和可靠的应用程序。在处理数据时,Python提供了一些内置功能来执行一些基本任务。本文将探讨如何使用Python删除变量中的数据的方法。 什么是…

差动保护原理

差动保护是输入的两端CT矢量差,当达到设定的动作值时启动动作元件。保护范围在输入的两端CT之间的设备(可以是线路,发电机,电动机,变压器等电气设备) 什么是差动保护 电流差动保护是中的一种保护。正相序是…

UDP协议和TCP协议

目录 UDP TCP 通过序列号与确认应答提高可靠性 为什么TCP是三次握手 为什么是四次挥手 超时重传机制 流控制 利用窗口控制提高速度 窗口控制与重发控制 拥塞控制 延迟确认应答 捎带应答 UDP UDP是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。…

总结一下js的浅拷贝和深拷贝

js中对象的赋值是通过将一个对象的引用赋值给另一个变量,两个变量指向同一个内存地址。这意味着如果更改其中一个对象的值,另一个对象的值也会更改。 浅拷贝是将一个对象的值复制给另一个对象,但如果对象中包含对其他对象的引用,…