作品展示
调用原来的主题知识素材,制作下学期的19周的主题知识word
背景需求:
开学了,继续做周计划系列,在原有基础上,进行进一步代码优化
【办公类-22-02】周计划系列(2)-生成“主题知识”(提取旧docx指定段落的内容,写入EXCLE模板,再次生成新docx)_从docx-tpl怎么:导入docx模板-CSDN博客文章浏览阅读580次。【办公类-22-02】周计划系列(2)-生成“主题知识”(提取旧docx指定段落的内容,写入EXCLE模板,再次生成新docx)_从docx-tpl怎么:导入docx模板https://blog.csdn.net/reasonsummer/article/details/129902271
素材准备:
都是“02 主题知识”下的内容
第01步:原有文件的名称 1-9周改成01-09周
原来的主题知识资料(内容包含主题知识和信息窗)
把文件名中的周次改成2位数
文件名格式不统一,有的周后面有空格,有的窗后面有主题名称……需要统一改成——第X周 主题说明
A:先统一格式
B:在对1-9周的数字进行2位数补全
代码展示:
微调部分——统计文件名的长度:
如:第9周 主题知识.doc 一共12字符,对所有12字符的文件名进行加0处理,如果 第10周 主题知识.doc 等于13 字符,就不要加0
import os
import time
path =r"D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识\01doc"
fileList=os.listdir(path)
print(fileList)
for file in fileList:
# 如果格式不统一 提取所有的周次
split_str = file.split('周')
newname1 = split_str[0] # _的第0部分=序号
print(newname1)
# newname2= split_str[1] # _的第0部分=序号
# print(newname2)
newname=newname1+'周 主题知识.doc'
oldname_path = os.path.join(path,file)
# 文件新路径
newname_path = os.path.join(path,newname)
# 新旧对调
os.rename(oldname_path, newname_path)
# 延时
time.sleep(2)
fileList=os.listdir(path)
# 这一份主题说明信息窗和主题说明在一起的,第X周后面加 “主题说明”几个字
for file in fileList:
# a=len(file)
# print(a)
if len(file)==12: # 第9周 主题说明.doc 12是一位数的周次
print(file)
split_str = file.split('第')
newname1 = split_str[0] # _的第0部分=序号
print(newname1)
newname2= split_str[1] # _的第0部分=序号
print(newname2)
newname=newname1+'第0'+newname2
oldname_path = os.path.join(path,file)
# 文件新路径
newname_path = os.path.join(path,newname)
# 新旧对调
os.rename(oldname_path, newname_path)
if len(file)==13: # 第10周 主题说明.doc 13是两位数的周次
pass
终端显示
第2步:原有文件格式从doc变成docx
代码展示——doc文件下的19个doc转到docx文件下的19个docx
原来代码用的是绝对路径双反斜杠并且需要手动把doc文件复制一份到docx,现在用相对路径,且直接另存到docx内
import os
from win32com import client as wc
import time
# 注意:目录的格式必须写成双反斜杠
path=r"D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识"
oldpath=path+r'\01doc' # 使用绝对地址(可更改)原文件doc地址
newpath=path+r'\02docx'# 使用绝对地址(可更改)docx地址
# 提取所有doc内的19周doc周计划的路径
files=[]
for file in os.listdir(oldpath):
# 找出文件中以.doc结尾并且不以~$开头的文件(~$是为了排除临时文件)
if file.endswith('.doc') and not file.startswith('~$'):
files.append(oldpath+'\\'+file)
print(files)
# 打开doc文件下的doc文件,另存到docx文件下的docx文件
for file in files:
word = wc.Dispatch("Word.Application")
print("已处理文件:"+file)
# # # 打开文件
doc = word.Documents.Open(file)
# # # 将文件另存为到docx文件夹,另存为.docx
# # 这里根据文件名称长度,进行数字确定
new=newpath+'\\'+file[-13:]+'x'
print(new)
doc.SaveAs("{}".format(new), 12) # 12表示docx格式
doc.Close()
第3步:删除docx里面的回车符
每份docx里面会有一些空行回车
删除空行回车符
代码展示
from docx import Document
from openpyxl import load_workbook
import glob
import os
path=r"D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识"
for file in glob.glob(path + r'\02docx\*.docx'): # 读取所有以前的信息窗参考资料
doc = Document(file)
for paragraph in doc.paragraphs: # 读取文档段落
if len(paragraph.text) == 0:
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
doc.save(path+r'\03去掉回车'+"\\"+file[-14:])
# # ————————————————
# # 版权声明:本文为CSDN博主「lsjweiyi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# # 原文链接:https://blog.csdn.net/lsjweiyi/article/details/121728630
第4步:整理“主题知识”的EXCEL信息,写入 中4班下学期“主题知识”.xlsx
代码展示:
# https://blog.csdn.net/lau_jw/article/details/114383781
from docx import Document
from openpyxl import load_workbook
import glob
import re
# 将模板 Excel 读取进程序:
path = r"D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识"
workbook = load_workbook(path + r'\10 改周次过渡模板_主题知识.xlsx')
sheet = workbook.active
number = 0
# 提取四个加粗标题所在的行数 # 参考https://www.shouxicto.com/article/96876.html
for file in glob.glob(path + r'\03去掉回车\*.docx'):
print(file)
doc= Document(file)
#获取每个文档的行数
# print("段落数:"+str(len(doc.paragraphs)))#段落数为13,每个回车隔离一段
d=len(doc.paragraphs)
for i in range(len(doc.paragraphs)):
if '主题说明:' in doc.paragraphs[i].text:
h1=i # 主题说明在第几行
print('主题说明',h1)
# z2.append(i)
# print(z2)
for i in range(len(doc.paragraphs)):
if '主题目标:'in doc.paragraphs[i].text:
h2=i # 主题说明在第几行
# print('主题目标',h2)
# z3.append(i)
# print(z3)
for i in range(len(doc.paragraphs)):
if '家园共育:' in doc.paragraphs[i].text:
h3=i # 家园共育在第几行
# # #家园共育结束值等于总行数
h4=d
z1=[] # 主题名称:
# 查找“主题名称”所在的行
for i in range(len(doc.paragraphs)):
# print("第"+str(i)+"段的内容是:"+doc.paragraphs[i].text)
if '主题名称:' in doc.paragraphs[i].text:
a1=doc.paragraphs[i].text
z1.append(a1[5:])
# 在同一行上,从5开始提取后面的汉字
# print(z1)
content1 = '\n'.join(z1) # 组合并加回车
z2=[] # 主题说明:
# 提取“主题说明”
for paragraph2 in doc.paragraphs[h1+1:h2]: # 主题说明h0固定是1行,所以从2开始提取,主题目标 是提取的行数h1-1, 索引取值,还是h1
t2 = paragraph2.text
z2.append(t2)
print(z2)
content2 = '\n'.join(z2) # 组合并加回车
z3=[] # 主题目标:
# 提取“主题目标”
for paragraph3 in doc.paragraphs[h2+1:h3]: # 主题说明h0固定是1行,所以从2开始提取,主题目标 是提取的行数h1-1, 索引取值,还是h1
t3 = paragraph3.text
z3.append(t3)
print(z3)
content3 = '\n'.join(z3) # 组合并加回车
z4=[] # 家园共育:
# 提取“家园共育”
for paragraph4 in doc.paragraphs[h3+1:]: # 主题说明h0固定是1行,所以从2开始提取,主题目标 是提取的行数h1-1, 索引取值,还是h1
t4 = paragraph4.text
z4.append(t4)
print(z4)
content4 = '\n'.join(z4) # 组合并加回车
number += 1
# sheet.append([number, content1,content2,content3,content4]) # number是序号,一共遍历提取了几分Word的内容,content是主题知识中间部分的内容
sheet.cell(row=number+1, column=1).value = number
sheet.cell(row=number+1, column=2).value = content1
sheet.cell(row=number+1, column=3).value = content2
sheet.cell(row=number+1, column=4).value = content3
sheet.cell(row=number+1, column=5).value = content4
workbook.save(path + r'\11 中4班下学期_主题知识.xlsx')
workbook.close()
print('--打开XLSX-,把里面的空格删除,把1、替换成1.--')#
# 打开Excel文件
workbook = load_workbook(path + r'\11 中4班下学期_主题知识.xlsx')
# 获取第一个工作表
worksheet = workbook.active
# # 遍历每个单元格
for row in worksheet.iter_rows():
for cell in row:
if cell.value and isinstance(cell.value, str):
# 清除单元格内文字的格式
cell.value = cell.value.strip()
# 判断单元格中的文字是否有空格
if ' ' in str(cell.value):
# 替换空格为无空格
cell.value = str(cell.value).replace(' ', '')
if ' ' in str(cell.value):
# 替换空格为无空格
cell.value = str(cell.value).replace(' ', '')
# 替换文本
for s in range(1,10):
if cell.value and isinstance(cell.value, str):
cell.value = cell.value.replace("{}、".format(s), "{}.".format(s))
# 保存修改后的Excel文件
workbook.save(path + r'\11 中4班下学期_主题知识.xlsx')
# 关闭Excel文件
workbook.close()
思路解析——提取“主题知识”中灰色部分的内容
重点说明:
1、读取关键词所在的行数
2、提取段落内容
3、在Excel里面去除格式和空格(不用手工批量删除了!)
结果展示
第5步:读取word模板,把EXCEL-主题知识 的内容 合成19份主题知识 Docx
代码展示
# 一、导入相关模块,设定excel所在文件夹和生成word保存的文件夹
from docxtpl import DocxTemplate
import pandas as pd
import os
import xlwt
import xlrd
import os
import random
from win32com.client import constants,gencache
from win32com.client.gencache import EnsureDispatch
from win32com.client import constants # 导入枚举常数模块
import os,time
import docx
from docx import Document
from docx.shared import Pt
from docx.shared import RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# path=r'D:\\test\\02办公类\\90周计划4份\\01 信息窗'+'\\'
path = r"D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识"
print(path)
file_path=path+r'\04合成新主题知识'
print(file_path)
# 二、遍历excel,逐个生成word(小标签.docx是前面的模板)
try:
os.mkdir(file_path)
except:
pass
# list = pd.read_excel(path+'\\11 中4班下学期_主题知识.xlsx')
list = pd.read_excel(path+'\\11 中4班下学期_主题知识.xlsx')
title = list["title"].str.rstrip()
name=list["name"]
sm=list["sm"].str.rstrip()# 没有str.rstrip()是数字格式
mb=list["mb"].str.rstrip()# 没有str.rstrip()是数字格式
gy=list["gy"].str.rstrip()# 没有str.rstrip()是数字格式
classroom =list["classroom"].str.rstrip() # str.rstrip()都是文字格式
# T1 =list["T1"].str.rstrip() # 没有str.rstrip()是数字格式
# T2 =list["T2"].str.rstrip()# 没有str.rstrip()是数字格式
time=list["time"].str.rstrip()
# 遍历excel行,逐个生成
numnum = list.shape[0]
for i in range(numnum):
context = {
"name": name[i],
"title": title[i],
"sm": sm[i],
"mb" :mb[i],
"gy" :gy[i],
"classroom": classroom[i],
"time": time[i],
}
tpl = DocxTemplate(path+'\\12 主题知识_竖版双.docx')
# tpl = DocxTemplate(path+'\\12 主题知识_竖版.docx')
# tpl = DocxTemplate(path+'\\12 主题知识_横版.docx')
tpl.render(context)
tpl.save(file_path+r"\\第{}周 {}班 主题知识({}).docx".format('%02d'%name[i],classroom[i],time[i]))
# tpl.save(file_path+r"\\{}主题知识 {} {}班 ({}).docx".format('%02d'%name[i],title[i],classroom[i],time[i])) # 这是19周的6次
运行结果
第6步:把主题知识转为png格式,便于上传“班级主页”
代码展示:
'''
作者:毛毛
性质:转载
原网址 https://zhuanlan.zhihu.com/p/367985422
安装python,确保以下模块已经安装:win32com,fitz,re
在桌面新建文件夹,命名为:word2pdf2png
将需要转换的word(只能docx格式,可以多个)放入文件夹word2pdf2png
复制以下代码并运行。
本代码只生成png 文件夹内只有一级,子文件不生成
说明:
1、
2、把“03 新周计划生成(原版)”的内容复制到“04 新周计划(没有反思的打印)”
3、把“04 新周计划(没有反思的打印)”内容复制到“05 新周计划(没有反思的jpg上传)”
4、然后“05 新周计划(没有反思的jpg上传)”文件夹删除并生成第一张无反思的图片20份
5、空余时间。把““03 新周计划生成(原版)”文件夹的内容复制到“08 新周计划生成(手动修改-准)”文件夹,手动修改
(1)周计划第一页反思(限定在一页内)
(2)教案等
'''
#coding=utf-8
from win32com.client import Dispatch
import os
import re
import fitz
wdFormatPDF = 17 #转换的类型
zoom_x=2 #尺寸大小,越大图片越清晰 5超大,这里改成2
zoom_y=2 #尺寸大小,越大图片越清晰,长宽保持一致
rotation_angle=0#旋转的角度,0为不旋转
# print(----'把"04合成新主题知识"文件夹里的资料复制到"05jpg上传"'-----)
import os
import shutil
def copy_docx_files(source_dir, dest_dir):
for filename in os.listdir(source_dir):
source_path = os.path.join(source_dir, filename)
dest_path = os.path.join(dest_dir, filename)
if os.path.isfile(source_path) and filename.endswith(".docx"):
shutil.copy(source_path, dest_path)
if os.path.isdir(source_path):
copy_docx_files(source_path, dest_dir)
# 指定源文件夹和目标文件夹
old_pat =r'D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识\04合成新主题知识' # 要复制的文件所在目录
new_path = r'D:\test\02办公类\91周计划4份_2024年中4班\02 主题知识\05jpg上传' #新路径
# 调用复制函数
copy_docx_files(old_pat, new_path)
#print(----生成PDF和第一页图片-----)
def doc2pdf2png(input_file):
for root, dirs, files in os.walk(input_file):
for file in files:
if re.search('\.(docx|doc)$', file):
filename = os.path.abspath(root + "\\" + file)
print('filename', filename)
word = Dispatch('Word.Application')
doc = word.Documents.Open(filename)
doc.SaveAs(filename.replace(".docx", ".pdf"), FileFormat=wdFormatPDF)
doc.Close()
word.Quit()
for root, dirs, files in os.walk(input_file):
for file in files:
if re.search('\.pdf$', file):
filename = os.path.abspath(root + "\\" + file)
print('filename', filename)
# 打开PDF文件
pdf = fitz.open(filename)
# 逐页读取PDF
for pg in range(0, pdf.pageCount):
page = pdf[pg]
# 设置缩放和旋转系数
trans = fitz.Matrix(zoom_x, zoom_y).preRotate(rotation_angle)
pm = page.getPixmap(matrix=trans, alpha=False)
# 开始写图像
pm.writePNG(filename.replace('.pdf', '') + str(pg+1) + ".png")
pdf.close()
doc2pdf2png(new_path)
# 删除生成文件PDF 和 生成文件docx
for parent, dirnames, filenames in os.walk(new_path):
for fn in filenames:
if fn.lower().endswith('.pdf'):
os.remove(os.path.join(parent, fn))
if fn.lower().endswith('.docx'):# 删除原始文件docx 正则[pdf|docx]套不上,只能分成两条了
os.remove(os.path.join(parent, fn))
# 删除png中,尾号是2-8的png(Word只要第一页,后面生成的第二页图片不要
for parent, dirnames, filenames in os.walk(new_path):
for fn in filenames:
for k in range(2,9): # png文件名的尾数是2,3,4,5,6,7,8 不确定共有几页,可以把9这个数字写大一点)
if fn.lower().endswith(f'{k}.png'): # 删除尾号为2,3,4,5,6,7,8的png图片 f{k}='{}'.formart(k)
os.remove(os.path.join(parent, fn))